你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

为 Azure Kubernetes 服务上基于 Istio 的服务网格加载项插入 CA 证书

在 Azure Kubernetes 服务的基于 Istio 的服务网格加载项中,默认情况下,Istio 证书颁发机构 (CA) 会生成自签名根证书和密钥,并使用它们对工作负荷证书进行签名。 若要保护根 CA 密钥,应使用在安全计算机上脱机运行的根 CA。 可以使用根 CA 向在每个群集中运行的 Istio CA 颁发中间证书。 Istio CA 可以使用管理员指定的证书和密钥对工作负载证书进行签名,并将管理员指定的根证书作为信任根分发到工作负载。 本文介绍如何在基于 Istio 的服务网格附加产品中为 Azure Kubernetes 服务提供自带 Istio CA 的证书和密钥。

显示带 Istio 的根和中间 CA 的示意图。

本文介绍如何使用 Azure Key Vault 将根证书、签名证书和密钥作为输入提供的 Istio 证书颁发机构配置 Istio 证书颁发机构,并将其提供给基于 Istio 的服务网格附加产品。

开始之前

验证 Azure CLI 版本

加载项需要安装 Azure CLI 2.57.0 或更高版本。 可以运行 az --version 来验证版本。 若要进行安装或升级,请参阅[安装 Azure CLI][azure-cli-install]。

设置 Azure Key Vault

  1. 需要 Azure Key Vault 资源才能向 Istio 附加产品提供证书和密钥输入。

  2. 需要脱机生成根证书、中间证书、中间密钥和证书链。 此处的步骤 1-3 提供了有关如何生成这些文件的示例。

  3. 使用证书和密钥在 Azure Key Vault 中创建机密:

    az keyvault secret set --vault-name $AKV_NAME --name root-cert --file <path-to-folder/root-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-cert --file <path-to-folder/ca-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-key --file <path-to-folder/ca-key.pem>
    az keyvault secret set --vault-name $AKV_NAME --name cert-chain --file <path-to-folder/cert-chain.pem>
    
  4. 启用适用于群集的用于机密存储 CSI 驱动程序的 Azure Key Vault 提供程序

    az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
    

    注意

    轮换证书时,若要控制机密同步到群集的速度,可以使用 Azure Key Vault 机密提供程序附加产品的 --rotation-poll-interval 参数。 例如:az aks addon update --resource-group $RESOURCE_GROUP --name $CLUSTER --addon azure-keyvault-secrets-provider --enable-secret-rotation --rotation-poll-interval 20s

  5. 授权附加产品的用户分配的托管标识有权访问 Azure Key Vault 资源:

    OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv)
    
    az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
    

    注意

    如果你使用“Azure RBAC 授权”而不是“保管库访问策略”为权限模型创建了 Key Vault,请按照此处的说明为托管标识创建权限。 为加载项的用户分配的托管标识添加 Key Vault Reader 的 Azure 角色分配。

使用插件 CA 证书设置基于 Istio 的服务网格附加产品

  1. 引用前面创建的 Azure Key Vault 机密时,为现有 AKS 群集启用 Istio 服务网格附加产品:

    az aks mesh enable --resource-group $RESOURCE_GROUP --name $CLUSTER \
    --root-cert-object-name root-cert \
    --ca-cert-object-name ca-cert \
    --ca-key-object-name ca-key \
    --cert-chain-object-name cert-chain \
    --key-vault-id /subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$AKV_NAME
    

    注意

    对于使用 Istio CA 生成的自签名根证书的 Istio 附加产品的现有群集,不支持切换到插件 CA。 首先需要禁用这些群集上的网格,然后使用上述命令再次启用该网格,以传递插件 CA 输入。

  2. 验证是否已在群集上创建 cacerts

    kubectl get secret -n aks-istio-system
    

    预期输出:

    NAME                                                         TYPE                 DATA   AGE
    cacerts                                                      opaque               4      13h
    sh.helm.release.v1.azure-service-mesh-istio-discovery.v380   helm.sh/release.v1   1      2m15s
    sh.helm.release.v1.azure-service-mesh-istio-discovery.v381   helm.sh/release.v1   1      8s    
    
  3. 验证 Istio 控制平面是否已选取自定义证书颁发机构:

    kubectl logs deploy/istiod-asm-1-17 -c discovery -n aks-istio-system | grep -v validationController | grep x509
    

    预期输出应类似于:

    2023-11-06T15:49:15.493732Z     info    x509 cert - Issuer: "CN=Intermediate CA - A1,O=Istio,L=cluster-A1", Subject: "", SN: e191d220af347c7e164ec418d75ed19e, NotBefore: "2023-11-06T15:47:15Z", NotAfter: "2033-11-03T15:49:15Z"
    2023-11-06T15:49:15.493764Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Intermediate CA - A1,O=Istio,L=cluster-A1", SN: 885034cba2894f61036f2956fd9d0ed337dc636, NotBefore: "2023-11-04T01:40:02Z", NotAfter: "2033-11-01T01:40:02Z"
    2023-11-06T15:49:15.493795Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Root A,O=Istio", SN: 18e2ee4089c5a7363ec306627d21d9bb212bed3e, NotBefore: "2023-11-04T01:38:27Z", NotAfter: "2033-11-01T01:38:27Z"
    

证书颁发机构轮换

出于安全或策略原因,可能需要定期轮换证书颁发机构。 本部分介绍如何处理中间 CA 和根 CA 轮换方案。

中间证书颁发机构轮换

  1. 可以在保持根 CA 的同时轮换中间 CA。 使用新的证书和密钥文件更新 Azure Key Vault 资源中的机密:

    az keyvault secret set --vault-name $AKV_NAME --name root-cert --file <path-to-folder/root-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-cert --file <path-to-folder/ca-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-key --file <path-to-folder/ca-key.pem>
    az keyvault secret set --vault-name $AKV_NAME --name cert-chain --file <path/cert-chain.pem>
    
  2. 等待 --rotation-poll-interval 的持续时间。 检查是否根据 Azure Key Vault 资源上更新的新中间 CA 在群集上刷新了 cacerts 机密:

    kubectl logs deploy/istiod-asm-1-17 -c discovery -n aks-istio-system | grep -v validationController
    

    预期输出应类似于:

    2023-11-07T06:16:21.091844Z     info    Update Istiod cacerts
    2023-11-07T06:16:21.091901Z     info    Using istiod file format for signing ca files
    2023-11-07T06:16:21.354423Z     info    Istiod has detected the newly added intermediate CA and updated its key and certs accordingly
    2023-11-07T06:16:21.354910Z     info    x509 cert - Issuer: "CN=Intermediate CA - A2,O=Istio,L=cluster-A2", Subject: "", SN: b2753c6a23b54d8364e780bf664672ce, NotBefore: "2023-11-07T06:14:21Z", NotAfter: "2033-11-04T06:16:21Z"
    2023-11-07T06:16:21.354967Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Intermediate CA - A2,O=Istio,L=cluster-A2", SN: 17f36ace6496ac2df88e15878610a0725bcf8ae9, NotBefore: "2023-11-04T01:40:22Z", NotAfter: "2033-11-01T01:40:22Z"
    2023-11-07T06:16:21.355007Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Root A,O=Istio", SN: 18e2ee4089c5a7363ec306627d21d9bb212bed3e, NotBefore: "2023-11-04T01:38:27Z", NotAfter: "2033-11-01T01:38:27Z"
    2023-11-07T06:16:21.355012Z     info    Istiod certificates are reloaded
    
  3. 工作负载会从 Istio 控制平面接收证书,默认情况下有效期为 24 小时。 如果不重启 Pod,所有工作负载会在 24 小时内基于新的中间 CA 获取新的叶证书。 如果要强制所有这些工作负载立即从新的中间 CA 获取新的叶证书,则需要重启工作负载。

    kubectl rollout restart deployment <deployment name> -n <deployment namespace>
    

根证书颁发机构轮换

  1. 需要使用具有旧根证书和新根证书的串联根证书文件来更新 Azure Key Vault 机密:

    az keyvault secret set --vault-name $AKV_NAME --name root-cert --file <path-to-folder/root-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-cert --file <path-to-folder/ca-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-key --file <path-to-folder/ca-key.pem>
    az keyvault secret set --vault-name $AKV_NAME --name cert-chain --file <path/cert-chain.pem>
    

    root-cert.pem 的内容遵循以下格式:

    -----BEGIN CERTIFICATE-----
    <contents of old root certificate>
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    <contents of new root certificate>
    -----END CERTIFICATE-----
    

    附加产品包括群集上每 10 分钟运行一次的 CronJob,用于检查根证书的更新。 如果检测到更新,它将重启 Istio 控制平面(istiod 部署),以选取更新。 可以检查其日志,确认检测到根证书更新,以及 Istio 控制平面是否已重启:

    kubectl logs -n aks-istio-system $(kubectl get pods -n aks-istio-system | grep 'istio-cert-validator-cronjob-' | sort -k8 | tail -n 1 | awk '{print $1}')
    

    预期输出:

    Root certificate update detected. Restarting deployment...
    deployment.apps/istiod-asm-1-17 restarted
    Deployment istiod-asm-1-17 restarted.
    

    重启 istiod 后,它应指示已将两个证书添加到信任域:

    kubectl logs deploy/istiod-asm-1-17 -c discovery -n aks-istio-system 
    

    预期输出:

    2023-11-07T06:42:00.287916Z     info    Using istiod file format for signing ca files
    2023-11-07T06:42:00.287928Z     info    Use plugged-in cert at etc/cacerts/ca-key.pem
    2023-11-07T06:42:00.288254Z     info    x509 cert - Issuer: "CN=Intermediate CA - A2,O=Istio,L=cluster-A2", Subject: "", SN: 286451ca8ff7bf9e6696f56bef829d42, NotBefore: "2023-11-07T06:40:00Z", NotAfter: "2033-11-04T06:42:00Z"
    2023-11-07T06:42:00.288279Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Intermediate CA - A2,O=Istio,L=cluster-A2", SN: 17f36ace6496ac2df88e15878610a0725bcf8ae9, NotBefore: "2023-11-04T01:40:22Z", NotAfter: "2033-11-01T01:40:22Z"
    2023-11-07T06:42:00.288298Z     info    x509 cert - Issuer: "CN=Root A,O=Istio", Subject: "CN=Root A,O=Istio", SN: 18e2ee4089c5a7363ec306627d21d9bb212bed3e, NotBefore: "2023-11-04T01:38:27Z", NotAfter: "2033-11-01T01:38:27Z"
    2023-11-07T06:42:00.288303Z     info    Istiod certificates are reloaded
    2023-11-07T06:42:00.288365Z     info    spiffe  Added 2 certs to trust domain cluster.local in peer cert verifier
    
  2. 需要等待 24 小时(叶证书有效期的默认时间),或强制重启所有工作负载。 这样,所有工作负载在进行 mTLS 验证时都能同时识别新旧证书颁发机构。

    kubectl rollout restart deployment <deployment name> -n <deployment namespace>
    
  3. 现在可以仅使用新 CA 更新 Azure Key Vault 机密(无需旧 CA):

    az keyvault secret set --vault-name $AKV_NAME --name root-cert --file <path-to-folder/root-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-cert --file <path-to-folder/ca-cert.pem>
    az keyvault secret set --vault-name $AKV_NAME --name ca-key --file <path-to-folder/ca-key.pem>
    az keyvault secret set --vault-name $AKV_NAME --name cert-chain --file <path/cert-chain.pem>
    

    检查 CronJob 的日志以确认检测到根证书更新并重启 istiod

    kubectl logs -n aks-istio-system $(kubectl get pods -n aks-istio-system | grep 'istio-cert-validator-cronjob-' | sort -k8 | tail -n 1 | awk '{print $1}')
    

    预期输出:

    Root certificate update detected. Restarting deployment...
    deployment.apps/istiod-asm-1-17 restarted
    Deployment istiod-asm-1-17 restarted.
    

    更新 istiod 后,它应仅确认新根 CA 的使用情况:

    kubectl logs deploy/istiod-asm-1-17 -c discovery -n aks-istio-system | grep -v validationController
    

    预期输出:

    2023-11-07T08:01:17.780299Z     info    x509 cert - Issuer: "CN=Intermediate CA - B1,O=Istio,L=cluster-B1", Subject: "", SN: 1159747c72cc7ac7a54880cd49b8df0a, NotBefore: "2023-11-07T07:59:17Z", NotAfter: "2033-11-04T08:01:17Z"
    2023-11-07T08:01:17.780330Z     info    x509 cert - Issuer: "CN=Root B,O=Istio", Subject: "CN=Intermediate CA - B1,O=Istio,L=cluster-B1", SN: 2aba0c438652a1f9beae4249457023013948c7e2, NotBefore: "2023-11-04T01:42:12Z", NotAfter: "2033-11-01T01:42:12Z"
    2023-11-07T08:01:17.780345Z     info    x509 cert - Issuer: "CN=Root B,O=Istio", Subject: "CN=Root B,O=Istio", SN: 3f9da6ddc4cb03749c3f43243a4b701ce5eb4e96, NotBefore: "2023-11-04T01:41:54Z", NotAfter: "2033-11-01T01:41:54Z"
    

    从本文所示的示例输出中,可以看到我们从根 A(启用附加产品时使用)移动到了根 B。

  4. 同样可以等待 24 小时或强制重启所有工作负载。 强制重启会使工作负载立即从新的根 CA 获取新的叶证书。

    kubectl rollout restart deployment <deployment name> -n <deployment namespace>