使用 Kubernetes CSR 自定义 CA 集成
这个特性需要 Kubernetes 版本 >= 1.18。
此任务显示如何提供工作负载证书的自定义证书颁发机构Kubernetes CSR API。这个特性利用了,一个轻量级组件与Istiod链接,使用 Kubernetes CSR API 签署证书。
这项任务分为两部分。第一部分演示了如何使用 Kubernetes CA 本身来签署工作负载证书。第二部分演示了如何使用与 Kubernetes CSR API 集成的自定义 CA 来为证书签名。
注意,这个示例只用于基本计算。不建议在生产环境中使用 kubernetes.io/legacy-unknown
。
在 bookinfo 命名空间中部署
bookinfo
示例应用程序。确保在 Istio 根目录下执行以下命令。$ kubectl create ns bookinfo $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml) -n bookinfo
验证安装的证书是否正确
在部署工作负载时,它们会向 Istiod 发送 CSR 请求,Istiod 将它们转发到 Kubernetes CA 进行签名。如果一切顺利,签名的证书将被发送回安装它们的工作负载。要验证它们是否已由 Kubernetes CA 签名,您需要先提取已签名的证书。
获取在命名空间中运行的所有 pod。
$ kubectl get pods -n bookinfo
为下一步选择任何一个正在运行的 Pod。
获取 Istio 代理用于 mTLS 的证书链和 CA 根证书。
$ istioctl pc secret <pod-name> -o json > proxy_secret
proxy_secret json 文件在
trustedCA
字段中包含 mTLS 的 CA 根证书。请注意,此证书是 base64 编码的。Kubernetes CA 使用的证书(特别是
kubernetes.io/legacy-unknown
)被加载到与 bookinfo 命名空间中的每个服务帐号关联的密钥上。$ kubectl get secrets -n bookinfo
$ kubectl get secrets -n bookinfo <secret-name> -o json
输出中的 字段包含 base64 编码的 Kubernetes CA 证书。
将上一步获得的
ca.cert
与上一步中TrustedCA
字段的内容进行比较。这两个应该是一样的。(可选)按照中的其余步骤确保服务之间的通信按预期进行。
删除
istio-system
和bookinfo
命名空间:$ kubectl delete ns istio-system $ kubectl delete ns bookinfo
假设自定义 CA 实现了一个控制器,该控制器具有读取和签署 Kubernetes CSR 请求的必要权限。 更多细节请参考Kubernetes CSR 文档。请注意,以下步骤取决于外部源并且可能会发生变化。
在 Kubernetes 集群中部署自定义 CA 控制器
对于此示例,我们使用开源证书颁发机构实现。此代码构建了一个控制器,该控制器读取 Kubernetes 集群上的 CSR 资源并使用本地密钥创建证书。按照页面上的说明进行操作:
- 构建 Certificate-Controller docker 镜像
- 将镜像上传到 Docker Registry
- 生成 Kubernetes manifest 以进行部署
确认所有的服务都在运行。
```
$ kubectl get services -n signer-ca-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
signer-ca-controller-manager-metrics-service ClusterIP 10.8.9.25 none 8443/TCP 72s
```
获取 CA 的公钥。这是在 signer-ca-system 命名空间中的 “signer-ca-*” secrets 中编码的。
$ kubectl get secrets signer-ca-5hff5h74hm -o json
tls.crt
字段包含 base64 编码的公钥文件。记录下来以备将来使用。
将 secret 加载到 istiod 命名空间中。
$ cat <<EOF > ./external-ca-secret.yaml apiVersion: v1 kind: Secret metadata: name: external-ca-cert namespace: istio-system data: root-cert.pem: <tls.cert from the step above> EOF $ kubectl apply -f external-ca-secret.yaml
部署 Istio
使用
istioctl
在集群上部署 Istio,配置如下。在 bookinfo 命名空间中部署
bookinfo
示例应用程序。$ kubectl create ns bookinfo $ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml) -n bookinfo
在部署工作负载时,它们会向 Istiod 发送 CSR 请求,Istiod 将它们转发到 Kubernetes CA 进行签名。如果一切顺利,签名的证书将被发送回安装它们的工作负载。要验证它们确实已由 Kubernetes CA 签名,您需要首先提取已签名的证书。
获取在命名空间中运行的所有 pod。
$ kubectl get pods -n bookinfo
为下一步选择任何正在运行的 Pod。
获取 Istio 代理用于 mTLS 的证书链和 CA 根证书。
$ istioctl pc secret <pod-name> -o json > proxy_secret
proxy_secret
json 文件在 trustedCA
字段中包含 mTLS 的 CA 根证书。请注意,此证书是 base64 编码的。
将上述步骤中获得的 CA 根证书与 external-ca-cert 中的 ”root-cert.pem“ 值进行比较。这两个应该是一样的。
(可选)按照bookinfo 示例中的其余步骤确保服务之间的通信按预期进行。
清理第 2 部分
删除
istio-system
和bookinfo
命名空间:$ kubectl delete ns istio-system $ kubectl delete ns bookinfo
增加了安全性 -
plugin-ca-cert
或默认的self-signed
选项不同,启用此功能意味着 CA 私钥不需要存在于 Kubernetes 集群中。自定义 CA 集成 - 通过在 Kubernetes CSR 请求中指定签名者名称,此功能允许 Istio 使用 Kubernetes CSR API 接口与自定义证书颁发机构集成。这确实需要自定义 CA 来实现一个 Kubernetes 控制器来观察 和
Certificate
资源并对其采取行动。