插件 CA 证书
此任务展示管理员如何使用根证书、签名证书和密钥配置 Istio 证书颁发机构 (CA)。
默认情况下,Istio CA 会生成自签名的根证书和密钥,并使用它们来签署工作负载证书。为了保护根 CA 密钥,您应该使用运行在安全脱机机器上的根 CA,并使用根 CA 向在每个集群中运行的 Istio CA 发行中间证书。Istio CA 可以使用管理员指定的证书和密钥签署工作负载证书,并将管理员指定的根证书分发到工作负载中作为信任根。
下图展示了包含两个集群的网格中推荐的 CA 层次结构。
本任务演示了如何生成和插入 Istio CA 的证书和密钥。这些步骤可以重复以配置每个集群中运行的 Istio CA 的证书和密钥。
将证书和密钥插入集群
在 Istio 安装包的顶级目录中,创建一个目录来存放证书和密钥
$ mkdir -p certs $ pushd certs
生成根证书和密钥
$ make -f ../tools/certs/Makefile.selfsigned.mk root-ca
这将生成以下文件
root-cert.pem
:生成的根证书root-key.pem
:生成的根密钥root-ca.conf
:openssl
用于生成根证书的配置root-cert.csr
:生成的根证书 CSR
对于每个集群,为 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
的目录中创建证书和密钥。如果您在脱机机器上执行此操作,请将生成的目录复制到可以访问集群的机器上。
在每个集群中,创建一个包含所有输入文件
ca-cert.pem
、ca-key.pem
、root-cert.pem
和cert-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
返回 Istio 安装的顶级目录
$ popd
部署 Istio
使用
demo
配置文件部署 Istio。Istio 的 CA 将从秘密挂载文件中读取证书和密钥。
$ istioctl install --set profile=demo
部署示例服务
部署
httpbin
和curl
示例服务。$ 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
为
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
。
休眠 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
解析证书链上的证书。
$ 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
验证根证书是否与管理员指定的相同
$ 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
验证 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
验证从根证书到工作负载证书的证书链
$ 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
删除示例应用程序
curl
和httpbin
$ kubectl delete -f samples/curl/curl.yaml -n foo $ kubectl delete -f samples/httpbin/httpbin.yaml -n foo
从集群中卸载 Istio
$ istioctl uninstall --purge -y
从集群中删除命名空间
foo
和istio-system
$ kubectl delete ns foo istio-system