本文介绍管理员如何使用根证书、签发证书及秘钥为 Istio 配置 CA(证书颁发机构)。Istio CA 使用由中间 CA 签发的私钥及证书,而中间 CA 由根 CA 签发。这样,Istio CA 即可为工作负载签发根证书及私钥。CA 层次结构图如下。
图片引自(Plug in CA Certificates)
接下来即介绍如何为 Istio 生成及植入 CA。
首先,进入 Istio 安装目录/usr/local/istio-1.8.1
,创建证书目录certs
后进入该目录。
$ cd /usr/local/istio-1.8.1
$ mkdir certs
$ cd certs
然后,使用如下命令生成根证书及私钥。
$ make -f ../tools/certs/Makefile.selfsigned.mk root-ca
其会生成 4 个文件。
FILE | DESCRIPTION |
---|---|
root-cert.pem | 根证书 |
root-key.pem | 根秘钥 |
root-ca.conf | 生成根证书的openssl 配置 |
root-cert.csr | 根证书的CSR |
接下来,使用如下命令生成中间证书及私钥。
$ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts
其会在cluster1
文件夹下生成 4 个文件。
FILE | DESCRIPTION |
---|---|
ca-cert.pem | 中间证书 |
ca-key.pem | 中间秘钥 |
cert-chain.pem | istiod 所使用的证书链 |
root-cert.pem | 根证书 |
最后,创建 namespace istio-system
,接着基于cluster1
文件夹下生成的文件创建 Secret cacerts
。
$ kubectl create ns 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
指定模式为demo
,安装 Istio,Istio CA 将从cacerts
读取证书及私钥。
$ istioctl install --set profile=demo
接着,进入 Istio 安装根目录,创建 namespace istio-demo
,然后在该 namespace 下部署样例服务httpbin
及用于测试的服务sleep
。
$ cd /usr/local/istio-1.8.1
$ kubectl create ns istio-demo
$ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n istio-demo
$ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n istio-demo
然后,使用如下命令指定istio-demo
下的工作负载只接受双向 TLS 的流量。
$ kubectl apply -n istio-demo -f - <<EOF
heredoc> apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
name: "default"
spec:
mtls:
mode: STRICT
heredoc> EOF
下面,我们将验证工作负载是否使用了我们所植入的 CA 所签发的证书。
首先,等待20s
,让所配置的 mTLS 规则生效。然后使用如下命令进入sleep
的istio-proxy
Sidecar 来尝试获取httpbin
的证书链。
$ kubectl exec "$(kubectl get pod -l app=sleep -n istio-demo -o jsonpath={.items..metadata.name})" -c istio-proxy -n istio-demo -- openssl s_client -showcerts -connect httpbin.istio-demo:8000 > httpbin-proxy-cert.txt
然后,得到错误“verify error:num=19:self signed certificate in certificate chain
”,符合预期。
查看文件httpbin-proxy-cert.txt
,发现里边有 4 套证书,将其拷贝出来,分别以proxy-cert-i.pem (i=1,2,3,4)
命名。
然后,使用如下命令校验根证书是否与管理员所签发的一致。
$ 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
使用如下命令移除证书。
$ cd /usr/local/istio-1.8.1
$ rm proxy-cert-*.pem
$ rm httpbin-proxy-cert.txt
$ rm -rf certs
使用如下命令移除 Secret cacerts
,删除 namespace istio-demo
,istio-system
。
$ kubectl delete secret cacerts -n istio-system
$ kubectl delete ns istio-demo istio-system
总结本文,介绍了 Istio 的 CA 如何签发,然后使用 httpbin 样例作了测试。
参考资料