# 自簽 Root-CA 提供給 Cert-manager 再去簽發服務 server certificate ## 環境準備 ### 1. 本次範例服務對外使用 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 ``` ### 2. 部署 nignix 範例 * 在 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 ``` ## 建立 Root-CA 自簽憑證 ``` $ git clone https://github.com/cooloo9871/SelfSigned-RootCA.git;cd SelfSigned-RootCA/ # ip 為 istio ingressgateway svc ip $ ./mk create nginx.k8sexample.com 10.10.7.87 # 需要有 dns server 做名稱解析 $ host nginx.k8sexample.com nginx.k8sexample.com has address 10.10.7.87 ``` * 建立 `root-ca-secret` secret,在 `cert-manager` namespace 上產生,提供給 cert-manager 使用 ``` $ kubectl create secret tls my-root-ca-secret \ --cert=ca.pem \ --key=ca-key-decrypted.pem \ -n cert-manager ``` ## 設定 cert-manager 建立 ClusterIssuer * 將自簽的 `root-ca-secret` 提供給 cert-manager 做出 `ClusterIssuer` ``` $ nano cert.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: root-ca-clusterissuer spec: ca: secretName: my-root-ca-secret ``` * 部署以及檢查資源 ``` $ kubectl apply -f cert.yaml $ kubectl get ClusterIssuer NAME READY AGE root-ca-clusterissuer True 25s ``` ## 建立 HTTPS 憑證 * 使用 `root-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: 8760h # 1 year renewBefore: 720h # 30d secretName: nginx-cert-tls dnsNames: - nginx.k8sexample.com issuerRef: name: root-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 4s $ kubectl -n istio-system get secret nginx-cert-tls NAME TYPE DATA AGE nginx-cert-tls kubernetes.io/tls 3 16s ``` ## 建立 Istio Gateway 與 VirtualService * 設定 Istio 的流量路由,目標是讓外部流量透過 HTTPS 進入 Istio Ingress Gateway,然後轉發到內部 Nginx Service。 ``` $ 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: nginx-cert-tls # 對應憑證 Secret hosts: - nginx.k8sexample.com --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: nginx-vs namespace: demo spec: hosts: - nginx.k8sexample.com gateways: - istio-system/nginx-gateway http: - route: - destination: host: svc-web.demo.svc.cluster.local port: number: 80 ``` * 部署以及檢查資源 ``` $ kubectl apply -f istio.yaml $ kubectl -n istio-system get gateway.networking NAME AGE nginx-gateway 21s $ kubectl -n demo get virtualservice NAME GATEWAYS HOSTS AGE nginx-vs ["istio-system/nginx-gateway"] ["nginx.k8sexample.com"] 45s ``` ## 將 ca.pem 匯入到每一個 client 上 * 以下為 ubuntu 24.04 匯入自簽憑證設定 ``` $ sudo cp ca.pem /usr/local/share/ca-certificates/ca.crt $ sudo update-ca-certificates ``` * 就可以直接訪問 https ``` $ curl https://nginx.k8sexample.com <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> ``` ## 檢查憑證 issuer 與到期時間 ``` $ sudo openssl x509 -in /usr/local/share/ca-certificates/ca.crt -noout -subject -issuer -dates subject=C = TW, ST = Taipei, L = Taipei, O = test, OU = lab, CN = example issuer=C = TW, ST = Taipei, L = Taipei, O = test, OU = lab, CN = example notBefore=Aug 27 01:56:39 2025 GMT notAfter=Aug 27 01:56:39 2026 GMT ```
×
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