Istio 插件 CA 示例证书(samples/certs)深度解析:预生成证书、中间 CA 信任链与工作负载证书签发
【免费下载链接】istioConnect, secure, control, and observe services.项目地址: https://gitcode.com/GitHub_Trending/is/istio
Istio 支持让网格 CA(历史上为 Citadel,当前由 istiod 承担)作为现有外部根 CA 之下的中间 CA运行,这被称为"插件 CA 证书(plugin CA cert)"模式。samples/certs/目录就是为该模式准备的一套开箱即用的示例证书与密钥,包含根 CA、中间 CA、证书信任链,以及可直接验证流程的工作负载(workload)证书。读完本文,你将理解这些示例文件的角色划分与生成关系、如何用仓库自带的generate-workload.sh签发带 SPIFFE URI SAN 的工作负载证书、如何用openssl校验整条信任链,以及如何把它们映射为网格 CA 实际读取的cacertsSecret 以完成落地配置。
一、目录定位:插件 CA 示例证书解决了什么问题
在默认部署中,Istio 的网格 CA 会自签一个根证书并作为根 CA 签发工作负载证书。但对于已经拥有企业 PKI/外部 CA 的组织,通常希望网格内的证书能由自己信任的根 CA 签发,让整个网格纳入既有信任体系。此时可通过插件 CA 证书机制,向网格 CA 提供:
- 一个根 CA 证书(用于构建信任链、校验对端);
- 网格 CA 自己的中间 CA 证书与私钥(网格 CA 用它签发所有工作负载证书)。
samples/certs/README.md开篇即说明了这批预生成样例的用途:演示操作者如何用已存在的根证书 + 签名证书 + 密钥来配置 Citadel;在这种部署形态下,Citadel 充当给定根 CA 之下的中间 CA。
随着演进,证书签发逻辑已经整合进pilot/pkg/bootstrap/istio_ca.go与security/pkg/pki/ca/ca.go等实现中,而这套样例文件与使用方式仍然有效——它们对应的是网格 CA 通过文件系统(/etc/cacerts)或 Secret(cacerts)读取外部 CA 材料的接入点。在 manifests/charts/istio-control/istio-discovery/templates/deployment.yaml 中可以清楚看到 istiod 会挂载名为cacerts的 Secret 到/etc/cacerts(readOnly: true),并且该 Secret 是可选的(optional: true,见同文件 deployment.yaml),即未提供时回退为自签 CA。
二、示例文件清单与角色划分
/samples/certs/共包含 23 个文件,全部为 PEM 格式的证书或私钥。按角色可分为四组:
2.1 根 CA 层:信任锚与多根合并
| 文件 | 作用 |
|---|---|
root-cert.pem | 根 CA 证书(主信任锚) |
root-cert-alt.pem | 备选根 CA 证书,用于模拟"另一个信任域/第二套根" |
root-cert-combined.pem | 把root-cert.pem与root-cert-alt.pem拼接为单个文件的产物 |
root-cert-combined-2.pem | 把root-cert.pem与两份root-cert-alt.pem拼接的产物,用于验证去重/多份相同证书拼接的场景 |
实际签发时这套根证书的 Subject 为O = Istio, OU = Test, CN = Root CA,有效期从 2018-01 至 2117-12(百年期样例证书),仅用于测试/演示,不具备生产合法性。
2.2 中间 CA 层:网格 CA 的身份与密钥
| 文件 | 作用 |
|---|---|
ca-cert.pem/ca-key.pem | 网格 CA 的中间证书与对应私钥,由root-cert.pem签发 |
ca-cert-alt.pem/ca-key-alt.pem | 备选中间证书与私钥(模拟 cluster1 的中间 CA) |
ca-cert-alt-2.pem/ca-key-alt-2.pem | 由root-cert-alt.pem签发的另一套备选中间证书与私钥(模拟 cluster2 的中间 CA) |
三套中间 CA 的 Subject 均为O = Istio, CN = Intermediate CA,通过L字段区分(cluster1/cluster2/ 主样例),Issuer 均指向CN = Root CA,体现了"根 CA 之下多个中间 CA"的典型多集群布局。中间证书中还包含DNS: ca.istio.io的 Subject Alternative Name(SAN),这是网格 CA 的传统标识名。
2.3 信任链文件:cert-chain 的组织形式
| 文件 | 内容 |
|---|---|
cert-chain.pem | 主证书信任链(中间 CA 证书本身) |
cert-chain-alt.pem | 与ca-cert-alt.pem配套的信任链 |
cert-chain-alt-2.pem | 与ca-cert-alt-2.pem配套、由root-cert-alt.pem体系签发的信任链 |
从生成脚本看,信任链文件内容即中间 CA 证书本身(cp leaf-workload 的签发证书时把 cert-chain 追加为链),验证时通常把cert-chain + root-cert一起作为-CAfile。
2.4 工作负载层:成品证书与签发中间产物
| 文件 | 作用 |
|---|---|
workload-foo-cert.pem/workload-foo-key.pem | 工作负载 foo 的完整证书(含信任链)与私钥 |
workload-bar-cert.pem/workload-bar-key.pem | 工作负载 bar 的完整证书(含信任链)与私钥 |
workload-foo-root-certs.pem | foo 证书所需的 root + 中间 CA 证书拼接,供对端校验 |
workload-bar-root-certs.pem | bar 证书所需的 root + 中间 CA 证书拼接 |
leaf-workload-foo-cert.pem | foo 的裸叶证书(不含信任链) |
leaf-workload-bar-cert.pem | bar 的裸叶证书(不含信任链) |
两组工作负载分别使用不同信任域(trust domain)的 SPIFFE 标识:
- foo:URI SAN 为
spiffe://trust-domain-foo/ns/foo/sa/foo,由ca-cert.pem/ca-key.pem签发; - bar:URI SAN 为
spiffe://trust-domain-bar/ns/bar/sa/bar,同样由ca-cert.pem/ca-key.pem签发。
即默认样例演示了同一个中间 CA 同时为两个不同信任域签发证书的场景(这正是多集群/多 trust domain 混部时的真实形态)。
三、用 generate-workload.sh 复现签发流程
工作负载证书不是手工固定的,而是由仓库根目录下脚本 samples/certs/generate-workload.sh 自动生成。README 中给出了两种用法:
# 用法一:按默认参数生成 ./generate-workload.sh foo ./generate-workload.sh bar # 用法二:显式指定全部参数,并用备选根证书签发 ./generate-workload.sh name namespace serviceAccount tmpDir use-alternative-root ./generate-workload.sh name namespace serviceAccount tmpDir use-alternative-root对照脚本源码(generate-workload.sh),其参数位置语义为:
| 参数位置 | 变量名 | 默认值 | 含义 |
|---|---|---|---|
$1 | name | foo | 名称,同时决定信任域前缀 |
$2 | ns | 取name | Kubernetes 命名空间 |
$3 | sa | 取name | ServiceAccount 名,同时用于输出文件名(workload-$sa-*.pem) |
$4 | tmp | 空 | 若给定目录,则将 CA 材料复制到该目录再签发 |
$5 | rootselect | 空 | 传use-alternative-root时切换到备选根签发 |
由此构造出的 SPIFFE SAN 恒为spiffe://trust-domain-$name/ns/$ns/sa/$sa(见 generate-workload.sh),与实际运行时 Pod 的 SPIFFE 身份(trust-domain/ns/.../sa/...)一一对应。
3.1 脚本内部执行步骤
整体流程在 generate-workload.sh 中清晰可见:
- 生成工作负载私钥:
openssl genrsa -out workload-$sa-key.pem 2048,2048 位 RSA。 - 写入 CSR 配置
workload.cfg:关键扩展包括keyUsage = digitalSignature, keyEncipherment、extendedKeyUsage = serverAuth, clientAuth、basicConstraints = critical, CA:FALSE(声明叶证书不是 CA)、以及subjectAltName指向URI = $san(见 generate-workload.sh)。 - 选择签发材料:默认使用
cert-chain.pem / ca-cert.pem / ca-key.pem / root-cert.pem;当$rootselect等于use-alternative-root时切换为cert-chain-alt.pem / ca-cert-alt.pem / ca-key-alt.pem / root-cert-alt.pem(见 generate-workload.sh)。 - 生成 CSR 并用中间 CA 签发:
openssl req -new(subj 为/,身份全部走 SAN),随后openssl x509 -req -CA $cacert -CAkey $cakey -CAcreateserial签发叶证书,有效期 3650 天,扩展取自workload.cfg的v3_req。 - 组装最终产物:
leaf-workload-$sa-cert.pem:仅叶证书;workload-$sa-cert.pem:叶证书 + 追加的cert-chain(用于发给对端);workload-$sa-root-certs.pem:cert-chain+ 追加的root-cert(用于本地校验对端)。
- 自校验:用
openssl verify -CAfile <(cat cert-chain root-cert) workload-$sa-cert.pem验证整条链(见 generate-workload.sh)。
此外脚本在$tmp非空时会把主/备两套共 8 个 CA 文件复制到目标目录(见 generate-workload.sh),并以 EXIT trap 清理.srl、workload.cfg、workload.csr等中间文件(见 generate-workload.sh),保证目录整洁。README 第二段命令中两行参数内容相同,本质是为了分别生成两组工作负载(可理解为分别对应foo与bar两次调用)。
四、用 openssl 亲手验证示例证书
以下命令可直接在仓库目录执行,用于核对文件间的真实关系:
# 查看根 CA 与中间 CA openssl x509 -in samples/certs/root-cert.pem -noout -subject -issuer -dates openssl x509 -in samples/certs/ca-cert.pem -noout -subject -issuer -dates # 查看备选根签发的第二套中间 CA openssl x509 -in samples/certs/ca-cert-alt-2.pem -noout -subject -issuer # 查看叶证书的 SPIFFE URI SAN(foo) openssl x509 -in samples/certs/leaf-workload-foo-cert.pem -noout -ext subjectAltName # 输出:URI:spiffe://trust-domain-foo/ns/foo/sa/foo # 校验中间 CA 由根 CA 签发 openssl verify -CAfile samples/certs/root-cert.pem samples/certs/ca-cert.pem # 校验 foo 工作负载完整证书(叶 + cert-chain)的信任链 openssl verify -CAfile <(cat samples/certs/cert-chain.pem samples/certs/root-cert.pem) \ samples/certs/workload-foo-cert.pem实测结果与 README 描述完全一致:root-cert.pem自签(Subject = Issuer =CN = Root CA),ca-cert.pem与cert-chain.pem的 Issuer 均指向Root CA,leaf-workload-foo-cert.pem的 Issuer 为CN = Istio CA(即主中间 CA),SAN 中 URI 即上文 SPIFFE 标识;而ca-cert-alt-2.pem与cert-chain-alt-2.pem的 Issuer 为CN = Root CA(无 OU=Test,区别于主根),正好与"由root-cert-alt.pem签发"的说明互证。
五、从样例到落地:映射 cacerts Secret
这套样例的最终消费场景是把它装载成网格 CA 读取的cacertsSecret。社区约定(同时也是 istiod 实现所遵循的)Secret 中需要包含以下四个键:
ca-cert.pem:中间 CA 证书;ca-key.pem:中间 CA 私钥;root-cert.pem:根 CA 证书;cert-chain.pem:信任链文件。
在代码侧,security/pkg/pki/ca/ca.go会基于这些文件构造 CA 实例;security/pkg/nodeagent/util/util.go的OutputKeyCertToDir则展示了工作负载证书落地时按key.pem/cert-chain.pem/root-cert.pem文件名原子写盘的习惯(见 util.go),可见root-cert.pem、cert-chain.pem这类命名在网格内是被广泛依赖的约定。部署侧,manifests/charts/istio-control/istio-discovery/templates/deployment.yaml 将名为cacerts的 Secret(optional: true)挂载至 istiod 容器/etc/cacerts;因此用户通常可以这样把样例投入测试:
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之后安装/重启 istiod,其 CA 私钥便会取自该中间 CA,签发给各工作负载的证书即可被上层的root-cert.pem所信任,实现"外部根 CA 之下的 Istio 中间 CA"这一插件 CA 架构。
六、正确理解样例边界
- 仅供测试与演示:所有证书均为仓库内固定的测试证书(部分有效期至 2117 年),私钥公开在仓库中,绝不应用于生产环境;生产必须使用自有 CA 体系重新生成。
- README 中的 Citadel 为历史名称:对应能力的现代实现位于
pilot/pkg/bootstrap/istio_ca.go、security/pkg/pki/ca/ca.go等模块,功能语义不变。 - 多套样例模拟多集群:
-alt、-alt-2系列分别对应不同根证书/不同中间 CA 组合,便于在多集群、多信任域验证插件 CA 与信任关系,例如cert-chain-alt-2.pem这类由备选根签发的链路可与主链路并存比较。
综上,samples/certs/是一个自包含、可复现的插件 CA 实验工具箱:读懂其文件矩阵即可把握"根 CA → 中间 CA → 叶证书"的完整链式结构,运行generate-workload.sh即可按任意 trust domain 重签工作负载证书,配合openssl verify与cacertsSecret 即可完成从样例到 Istio 网格 CA 的完整验证闭环。
【免费下载链接】istioConnect, secure, control, and observe services.项目地址: https://gitcode.com/GitHub_Trending/is/istio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考