插入外部 CA 证书

本任务演示系统管理员如何使用现有的根证书、签名证书和密钥配置 Istio 的 CA。

缺省情况下 Istio 的 CA 会生成自签署的根证书和密钥,用于给工作负载签署证书。Istio 的 CA 还可以使用运维人员指定的根证书、证书和密钥进行工作负载的证书颁发。该任务演示了向 Istio CA 插入外部证书和密钥的方法。

插入现有密钥和证书

假设我们想让 Istio 的 CA 使用现有的 ca-cert.pem 证书和 ca-key.pem,其中 ca-cert.pem 是由 root-cert.pem 根证书签发的,我们也准备使用 root-cert.pem 作为 Istio 工作负载的根证书。

下面的例子中,Istio CA 的签署(CA)证书(root-cert.pem)不同于根证书(root-cert.pem),因此工作负载无法使用根证书进行证书校验。工作负载需要一个 cert-chain.pem 文件作为信任链,其中需要包含所有从根证书到工作负载证书之间的中间 CA。在我们的例子中,它包含了 Istio CA 的签署证书,所以 cert-chain.pemca-cert.pem 是一致的。注意,如果你的 ca-cert.pemroot-cert.pem 是一致的,那么 cert-chain.pem 就是个空文件了。

这些文件都会在 samples/certs/ 目录中准备就绪提供使用。

下面的步骤将外部证书和密钥存入 Kubernetes secret 对象,这些 secret 会被 Istio 的 CA 读取:

  1. 创建一个名为 cacert 的 secret,其中包含所有输入文件 ca-cert.pemca-key.pemroot-cert.pem 以及 cert-chain.pem

    $ kubectl create namespace istio-system
    $ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem \
        --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem \
        --from-file=samples/certs/cert-chain.pem
    
  2. 使用 demo 的部署配置,将 global.mtls.enabled 设置为 true,部署 Istio。

Istio 的 CA 会从挂载的 secret 文件中读取证书和秘钥信息。

$ istioctl manifest apply --set profile=demo --set values.global.mtls.enabled=true

检查新证书

在本节中,我们将验证工作负载证书是否由插入 CA 的证书签名。这需要在本机安装 openssl

  1. 部署 httpbinsleep 简单服务。

    $ 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/sleep/sleep.yaml) -n foo
    
  2. 获取 httpbin 的证书链。

    $ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c istio-proxy -n foo -- openssl s_client -showcerts -connect httpbin.foo:8000 > httpbin-proxy-cert.txt
    

    打开上面命令生成的 httpbin-proxy-cert.txt 文件,将其中的三个证书分别保存到 proxy-cert-0.pemproxy-cert-1.pemproxy-cert-2.pem。每个证书以 -----BEGIN CERTIFICATE----- 开始,以 -----END CERTIFICATE----- 结束。

  3. 检查根证书和运维人员指定的证书是否一致:

    Zip
    $ openssl x509 -in @samples/certs/root-cert.pem@ -text -noout > /tmp/root-cert.crt.txt
    $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-root-cert.crt.txt
    $ diff /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
    

    输出为空代表符合预期。

  4. 检查 CA 证书和运维人员指定的是否一致

    Zip
    $ openssl x509 -in @samples/certs/ca-cert.pem@ -text -noout > /tmp/ca-cert.crt.txt
    $ openssl x509 -in ./proxy-cert-1.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
    $ diff /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
    

    输出为空代表符合预期。

  5. 检查从根证书到工作负载证书的证书链:

    ZipZip
    $ openssl verify -CAfile <(cat @samples/certs/ca-cert.pem@ @samples/certs/root-cert.pem@) ./proxy-cert-0.pem
    ./proxy-cert-0.pem: OK
    

清理

  • 移除 secret cacerts 并使用 Istio CA 自签署证书重新部署 Istio:

    $ kubectl delete secret cacerts -n istio-system
    $ istioctl manifest apply
    
  • 移除 Istio 组件:按照卸载说明进行删除。

这些信息有用吗?
Do you have any suggestions for improvement?

Thanks for your feedback!