插件 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.confopenssl 用于生成根证书的配置
    • 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 的秘密 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 将从秘密挂载文件中读取证书和密钥。

    $ 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. 休眠 20 秒以使 mTLS 策略生效,然后再检索 httpbin 的证书链。由于本示例中使用的 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
    
  • 删除秘密 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
    
这些信息对您有用吗?
您有什么改进建议吗?

感谢您的反馈!