本节展示了管理员如何使用现有的根证书来授权istio证书,签发证书和密钥。
默认情况下,istio的CA会生成一个自签的根证书和密钥,并使用它们签发负载证书。istio的CA也会使用管理员指定的证书和密钥,以及管理员指定的根证书来签发负载证书。本节展示如何将这些证书和密钥插入Istio的CA。
假设istio的CA需要使用现有的签名证书ca-cert.pem
和密钥ca-key.pem
,其中 root-cert.pem
签发了证书ca-cert.pem
,使用 root-cert.pem
作为istio负载的根证书。
在下面的例子中,istio的CA证书(ca-cert.pem
)与根证书(root-cert.pem
)不同,因此负载无法通过根证书验证工作负载证书,需要使用一个cert-chain.pem
来指定信任的证书链,该证书链包含负载和根CA之间的所有中间CA,在此例子中,它包含了istio的CA签名证书,因此cert-chain.pem
和ca-cert.pem
是相同的。注意,如果ca-cert.pem
与root-cert.pem
相同,那么ca-chain.pem
文件应该是空的。
这些文件位于samples/certs/
目录。
默认的istio CA安装根据如下命令(如名为
cacerts
的secret,名为root-cert.pem文
件中的根证书,ca-key.pem
文件中的istio CA等)预先定义的密钥和文件名,必须使用这些指定的secret和文件名,或在部署istio的时候重新配置istio的CA。
下面步骤将证书和密钥插入kubernetes的secret中,后续会被istio的CA读取:
$ 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
$ istioctl install --set profile=demo
$ 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
$ kubectl apply -n foo -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
name: "default"
spec:
mtls:
mode: STRICT
EOF
本节中会校验插入到CA中的证书是否签发了负载证书。
$ sleep 20; 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
$ 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
卸载证书cacert
和foo
以及istio-system
命名空间
$ kubectl delete secret cacerts -n istio-system
$ kubectl delete ns foo istio-system
本节展示如何使用 Chiron提供和管理DNS证书,Chiron是一个与istiod相连的轻量型组件,它使用kubernetes的CA API签发证书,无需管理私钥。有如下优势:
首先使用istioctl安装istio,并配置DNS证书,当istiod启动后会读取该配置
$ cat <<EOF > ./istio.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
certificates:
- secretName: dns.example1-service-account
dnsNames: [example1.istio-system.svc, example1.istio-system]
- secretName: dns.example2-service-account
dnsNames: [example2.istio-system.svc, example2.istio-system]
EOF
$ istioctl install -f ./istio.yaml
注:使用openshift4.3并没有生成预期的kubernetes secret,参见该issue
istio根据用户的配置为DNS证书提供了DNS名字和secret名称。DNS证书由kubernetes CA签发,并根据配置保存到secret中。istio也管理着DNS证书的生命周期,包括证书滚动和重新生成。
可以在 istioctl install
命令中使用IstioControlPlane
用户资源对istio进行配置。dnsNames
字段用于设定证书中的DNS名称,secretName
字段指定保存证书和密钥的kubernetes secret的名称。
在配置istio生成DNS证书并保存到secret后,需要校验提供的证书是否能够正确运行。
为了校验istio前面例子中生成的dns.example1-service-account
的DNS证书,以及校验该证书是否包含配置的DNS名称,需要获取kubernetes的secret,解析并对其解码,查看其具体内容:
$ kubectl get secret dns.example1-service-account -n istio-system -o jsonpath="{.data['cert-chain\.pem']}" | base64 --decode | openssl x509 -in /dev/stdin -text -noout
输出的文本包括:
X509v3 Subject Alternative Name:
DNS:example1.istio-system.svc, DNS:example1.istio-system
istio可以在DNS证书被错删的情况下重新生成证书。
输出包括
X509v3 Subject Alternative Name:
DNS:example1.istio-system.svc, DNS:example1.istio-system
$ kubectl delete ns istio-system