插入 CA 憑證

此任務說明管理員如何使用根憑證、簽署憑證和金鑰來設定 Istio 憑證授權機構 (CA)。

預設情況下,Istio CA 會產生自我簽署的根憑證和金鑰,並使用它們來簽署工作負載憑證。為了保護根 CA 金鑰,您應使用在安全的離線機器上執行的根 CA,並使用根 CA 向在每個叢集中執行的 Istio CA 發出中繼憑證。Istio CA 可以使用管理員指定的憑證和金鑰簽署工作負載憑證,並將管理員指定的根憑證作為信任根分發給工作負載。

下圖示範包含兩個叢集的網格中建議的 CA 階層。

CA Hierarchy
CA 階層

此任務示範如何產生並插入 Istio CA 的憑證和金鑰。可以重複這些步驟,為在每個叢集中執行的 Istio CA 佈建憑證和金鑰。

將憑證和金鑰插入叢集

  1. 在 Istio 安裝套件的頂層目錄中,建立一個目錄來存放憑證和金鑰

    $ mkdir -p certs
    $ pushd certs
    
  2. 產生根憑證和金鑰

    $ make -f ../tools/certs/Makefile.selfsigned.mk root-ca
    

    這會產生以下檔案

    • root-cert.pem:產生的根憑證
    • root-key.pem:產生的根金鑰
    • root-ca.conf:用於 openssl 產生根憑證的設定檔
    • root-cert.csr:為根憑證產生的 CSR
  3. 針對每個叢集,為 Istio CA 產生一個中繼憑證和金鑰。以下是 cluster1 的範例

    $ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts
    

    這會在名為 cluster1 的目錄中產生以下檔案

    • ca-cert.pem:產生的中繼憑證
    • ca-key.pem:產生的中繼金鑰
    • cert-chain.pem:產生的憑證鏈,供 istiod 使用
    • root-cert.pem:根憑證

    您可以將 cluster1 替換為您選擇的字串。例如,使用引數 cluster2-cacerts,您可以在名為 cluster2 的目錄中建立憑證和金鑰。

    如果您是在離線機器上執行此操作,請將產生的目錄複製到可以存取叢集的機器上。

  4. 在每個叢集中,建立一個包含所有輸入檔案 ca-cert.pemca-key.pemroot-cert.pemcert-chain.pem 的 secret cacerts。例如,針對 cluster1

    $ kubectl create namespace istio-system
    $ kubectl create secret generic cacerts -n istio-system \
          --from-file=cluster1/ca-cert.pem \
          --from-file=cluster1/ca-key.pem \
          --from-file=cluster1/root-cert.pem \
          --from-file=cluster1/cert-chain.pem
    
  5. 返回 Istio 安裝的頂層目錄

    $ popd
    

部署 Istio

  1. 使用 demo 設定檔部署 Istio。

    Istio 的 CA 將從 secret 掛載的檔案中讀取憑證和金鑰。

    $ istioctl install --set profile=demo
    

部署範例服務

  1. 部署 httpbincurl 範例服務。

    $ kubectl create ns foo
    $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
    $ kubectl apply -f <(istioctl kube-inject -f samples/curl/curl.yaml) -n foo
    
  2. 部署一個策略,使 foo 命名空間中的工作負載僅接受相互 TLS 通訊。

    $ kubectl apply -n foo -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: PeerAuthentication
    metadata:
      name: "default"
    spec:
      mtls:
        mode: STRICT
    EOF
    

驗證憑證

在本節中,我們驗證工作負載憑證是否由我們插入 CA 的憑證簽署。這需要您在機器上安裝 openssl

  1. 在檢索 httpbin 的憑證鏈之前,先等待 20 秒讓 mTLS 策略生效。由於此範例中使用的 CA 憑證是自簽署的,因此 openssl 命令返回的 verify error:num=19:self signed certificate in certificate chain 錯誤是預期的。

    $ sleep 20; kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- openssl s_client -showcerts -connect httpbin.foo:8000 > httpbin-proxy-cert.txt
    
  2. 解析憑證鏈上的憑證。

    $ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' httpbin-proxy-cert.txt > certs.pem
    $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
    
  3. 驗證根憑證與管理員指定的憑證相同

    $ openssl x509 -in certs/cluster1/root-cert.pem -text -noout > /tmp/root-cert.crt.txt
    $ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt
    $ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
    Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical
    
  4. 驗證 CA 憑證與管理員指定的憑證相同

    $ openssl x509 -in certs/cluster1/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt
    $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
    $ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
    Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical
    
  5. 驗證從根憑證到工作負載憑證的憑證鏈

    $ openssl verify -CAfile <(cat certs/cluster1/ca-cert.pem certs/cluster1/root-cert.pem) ./proxy-cert-1.pem
    ./proxy-cert-1.pem: OK
    

清理

  • 從您的本機磁碟移除憑證、金鑰和中繼檔案

    $ rm -rf certs
    
  • 移除 secret cacerts

    $ kubectl delete secret cacerts -n istio-system
    
  • foo 命名空間中移除身分驗證策略

    $ kubectl delete peerauthentication -n foo default
    
  • 移除範例應用程式 curlhttpbin

    $ kubectl delete -f samples/curl/curl.yaml -n foo
    $ kubectl delete -f samples/httpbin/httpbin.yaml -n foo
    
  • 從叢集中解除安裝 Istio

    $ istioctl uninstall --purge -y
    
  • 從叢集中移除命名空間 fooistio-system

    $ kubectl delete ns foo istio-system
    
此資訊是否有用?
您有任何改進建議嗎?

感謝您的意見回饋!