# 部署 Nginx 服務,並透過 istio ingressgateway 使用 https 訪問 ## 環境準備 * 已安裝好 istio ``` $ kubectl -n istio-system get pod NAME READY STATUS RESTARTS AGE istio-cni-node-5kmfh 1/1 Running 0 18h istio-cni-node-975fn 1/1 Running 0 18h istio-cni-node-9jqsq 1/1 Running 0 18h istio-cni-node-9n8s6 1/1 Running 0 18h istio-cni-node-d5d4z 1/1 Running 0 18h istio-ingressgateway-5b6548c6d6-n6x64 1/1 Running 0 18h istiod-d498fb64c-d9w5x 1/1 Running 0 18h jaeger-76444674f-s2nqj 1/1 Running 0 18h kiali-6d774d8bb8-6n6zj 1/1 Running 0 18h ztunnel-dc56s 1/1 Running 0 18h ztunnel-f4t5s 1/1 Running 0 18h ztunnel-mfxxn 1/1 Running 0 18h ztunnel-vrbs2 1/1 Running 0 18h ztunnel-w4xkp 1/1 Running 0 18h ``` ## 部署 Nginx * 在 demo namespace 設定 `istio.io/dataplane-mode=ambient` label ``` $ kubectl create ns demo $ kubectl label namespace demo istio.io/dataplane-mode=ambient ``` * 建立 Nginx deployment ``` $ kubectl -n demo create deploy web --image=nginx --port=80 $ kubectl -n demo expose deploy web --name=svc-web --target-port=80 --port=80 ``` * 建立自簽憑證 ``` $ git clone https://github.com/cooloo9871/SelfSigned-RootCA.git;cd SelfSigned-RootCA/ # ip 為 istio ingressgateway svc ip $ ./mk create nginx.k8s.com 192.168.1.35 # 需要有 dns server 做名稱解析 $ host nginx.k8s.com nginx.k8s.com has address 192.168.1.35 ``` * 建立 secret,需要在 `istio-system` namespace 上產生,提供給 ingressgateway 使用 ``` $ kubectl -n istio-system create secret tls tls-nginx --cert=cert.pem --key=cert-key.pem ``` ## 設定 istio ``` $ nano istio.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: nginx-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: tls-nginx hosts: - nginx.k8s.com --- apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: nginx-vs namespace: demo spec: hosts: - "nginx.k8s.com" gateways: - istio-system/nginx-gateway http: - route: - destination: host: svc-web.demo.svc.cluster.local port: number: 80 --- apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: nginx namespace: demo spec: host: svc-web.demo.svc.cluster.local trafficPolicy: tls: mode: DISABLE ``` ``` $ kubectl apply -f istio.yaml ``` ``` $ kubectl -n istio-system get gateway.networking NAME AGE nginx-gateway 11s $ kubectl -n demo get virtualservice NAME GATEWAYS HOSTS AGE nginx-vs ["nginx-gateway"] ["nginx.k8s.com"] 30s $ kubectl -n demo get destinationrule NAME HOST AGE nginx svc-web.demo.svc.cluster.local 43s ``` ## 驗證 * 將 `ca.pem` 匯入到 client 後就可以使用 https 訪問 * 以下為 ubuntu 24.04 匯入自簽憑證設定 ``` $ sudo cp ca.pem /usr/share/pki/trust/anchors/ $ sudo cp ca.pem /etc/pki/trust/anchors/ $ sudo update-ca-certificates --fresh ``` ``` $ curl https://nginx.k8s.com <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> ...... ``` * 環境清除 ``` $ kubectl delete -f istio.yaml $ kubectl -n istio-system delete secret tls-nginx ``` ## 使用 cert-manager 自簽憑證 ### 0. 環境準備 1. 已安裝好 istio 以及 cert-manager ### 1.先建立 SelfSigned Issuer → 再用它簽一個 CA → 用 CA 建一個 ClusterIssuer ``` $ nano cert.yaml apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer namespace: cert-manager spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: istio-ca namespace: cert-manager spec: isCA: true duration: 2160h # 90d renewBefore: 720h # 30d commonName: istio-ca secretName: istio-ca-secret issuerRef: name: selfsigned-issuer kind: Issuer --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: istio-ca-clusterissuer spec: ca: secretName: istio-ca-secret ``` * 部署以及檢查資源 ``` $ kubectl apply -f cert.yaml $ kubectl -n cert-manager get Issuer NAME READY AGE selfsigned-issuer True 32s $ kubectl -n cert-manager get Certificate NAME READY SECRET AGE istio-ca True istio-ca-secret 47s $ kubectl get ClusterIssuer NAME READY AGE istio-ca-clusterissuer True 87m $ kubectl -n cert-manager get secret istio-ca-secret NAME TYPE DATA AGE istio-ca-secret kubernetes.io/tls 3 98m ``` ### 2. 建立 HTTPS 憑證 * 使用 `istio-ca-clusterissuer` 這個 ClusterIssuer 來簽發憑證,憑證簽發後會把 公鑰和私鑰放在 `nginx-cert-tls` secret。 * `dnsNames:` 就是 憑證的 主體名稱(SANs),也是服務對外的 domain,也需要將名稱解析到 istio ingressgateway 的 svc ip。 ``` $ nano nginx-cert.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: nginx-cert namespace: istio-system spec: duration: 2160h # 90d renewBefore: 720h # 30d secretName: nginx-cert-tls dnsNames: - nginx.k8s.com issuerRef: name: istio-ca-clusterissuer kind: ClusterIssuer $ kubectl apply -f nginx-cert.yaml $ kubectl -n istio-system get Certificate nginx-cert NAME READY SECRET AGE nginx-cert True nginx-cert-tls 3h25m $ kubectl -n istio-system get secret nginx-cert-tls NAME TYPE DATA AGE nginx-cert-tls kubernetes.io/tls 3 101m ``` ### 3. 建立 Istio Gateway 與 VirtualService * 設定 Istio 的流量路由,目標是讓外部流量透過 HTTPS 進入 Istio Ingress Gateway,然後轉發到內部 Nginx Service。 ``` $ nano istio2.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: nginx-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: nginx-cert-tls # 對應憑證 Secret hosts: - nginx.k8s.com --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: nginx-vs namespace: demo spec: hosts: - nginx.k8s.com gateways: - istio-system/nginx-gateway http: - route: - destination: host: svc-web.demo.svc.cluster.local port: number: 80 --- apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: nginx namespace: demo spec: host: svc-web.demo.svc.cluster.local trafficPolicy: tls: mode: DISABLE $ kubectl apply -f istio2.yaml ``` ### 3. 將 ca.pem 匯入到每一個 client 上 ``` $ kubectl -n cert-manager get secret istio-ca-secret -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.pem ``` * 以下為 ubuntu 24.04 匯入自簽憑證設定 ``` $ sudo cp ca.pem /usr/local/share/ca-certificates/ca.crt $ sudo update-ca-certificates ``` ### 4. 測試 * 可以直接透過 https 訪問 ``` $ curl https://nginx.k8s.com <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> ``` 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up