Istio 服务网格加载项插件 CA 证书故障排除
本文讨论 Istio 加载项插件证书颁发机构 (CA) 证书功能的常见故障排除问题,并提供解决这些问题的解决方案。 本文还回顾了为服务网格加载项设置插件 CA 证书的一般过程。
注意
本文假定 Istio 修订版 asm-1-21
部署在群集上。
先决条件
用于连接到群集的 Kubernetes kubectl 工具或类似工具。 若要使用 Azure CLI 安装 kubectl,请运行 az aks install-cli 命令。
以下 Linux 样式的标准 shell 工具:
grep
sort
tail
awk
xargs
用于查询 JSON 数据的 jq 工具。
常规设置过程
在启用 Istio 加载项以使用插件 CA 证书功能之前,必须在群集上为机密存储加载项启用 Azure 密钥库 提供程序。 确保 Azure 密钥库和群集位于同一 Azure 租户上。
启用 Azure 密钥库机密提供程序加载项后,必须为加载项创建的用户分配的托管标识设置对 Azure 密钥库的访问权限。
授予用户分配的托管标识访问 Azure 密钥库的权限后,可以将插件 CA 证书功能与 Istio 加载项一起使用。 有关详细信息,请参阅 “启用 Istio 加载项以使用插件 CA 证书 ”部分。
若要使群集自动检测 Azure 密钥库 机密中的更改,必须为 Azure 密钥库 机密提供程序加载项启用自动轮换。
尽管自动应用对中间证书的更改,但在部署由加载项部署的 cronjob 重启部署后
istiod
,才会选取对根证书所做的更改,如“已部署的资源”部分所述。 此 cronjob 以 10 分钟的间隔运行。
启用 Istio 加载项以使用插件 CA 证书
Istio 加载项 插件 CA 证书 功能允许为网格配置插件根证书和中间证书。 若要在启用加载项时提供插件证书信息,请在 Azure CLI 中为 az aks mesh enable 命令指定以下参数。
参数 | 说明 |
---|---|
--key-vault-id <resource-id> |
Azure 密钥库资源 ID。 此资源应与托管群集位于同一租户中。 此资源 ID 必须采用 Azure 资源管理器 模板(ARM 模板)资源 ID 格式。 |
--root-cert-object-name <root-cert-obj-name> |
Azure 密钥库中的根证书对象名称。 |
--ca-cert-object-name <inter-cert-obj-name> |
Azure 密钥库中的中间证书对象名称。 |
--ca-key-object-name <inter-key-obj-name> |
Azure 密钥库中的中间证书私钥对象名称。 |
--cert-chain-object-name <cert-chain-obj-name> |
Azure 密钥库中的证书链对象名称。 |
如果要使用插件 CA 证书功能,则必须指定所有五个参数。 所有 Azure 密钥库 对象应属于机密类型。
有关详细信息,请参阅基于 Istio 的服务网格加载项的插件 CA 证书Azure Kubernetes 服务。
已部署资源
作为插件证书功能的加载项部署的一部分,以下资源将部署到群集:
cacerts
在加载项部署时,aks-istio-system
会在命名空间中创建 Kubernetes 机密。 此机密包含同步的 Azure 密钥库 机密:kubectl describe secret cacerts --namespace aks-istio-system
Name: cacerts Namespace: aks-istio-system Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: opaque Data ==== ca-cert.pem: 1968 bytes ca-key.pem: 3272 bytes cert-chain.pem: 3786 bytes root-cert.pem: 3636 bytes
istio-spc-asm-1-21
在加载项部署时,aks-istio-system
在命名空间中创建 SecretProviderClass 对象。 此资源包含机密存储容器存储接口 (CSI) 驱动程序的特定于 Azure 的参数:kubectl get secretproviderclass --namespace aks-istio-system
NAME AGE istio-spc-asm-1-21 14h
istio-ca-root-cert
configmap 是在命名空间和所有用户管理的命名空间中创建aks-istio-system
的。 此配置映射包含证书颁发机构使用的根证书,命名空间中的工作负荷使用它来验证工作负荷到工作负荷的通信,如下所示:kubectl describe configmap istio-ca-root-cert --namespace aks-istio-system
Name: istio-ca-root-cert Namespace: aks-istio-system Labels: istio.io/config=true Annotations: <none> Data ==== root-cert.pem: ---- -----BEGIN CERTIFICATE----- <certificate data> -----END CERTIFICATE-----
cronjob
istio-cert-validator-cronjob-asm-1-21
对象 是在命名空间中创建的aks-istio-system
。 此 cronjob 计划每隔 10 分钟运行一次,以检查根证书上的更新。 如果 Kubernetes 机密中的cacerts
根证书与命名空间中的aks-istio-system
configmap 不匹配istio-ca-root-cert
,则会重启istiod-asm-1-21
部署:kubectl get cronjob --namespace aks-istio-system
NAME SCHEDULE SUSPEND ACTIVE istio-cert-validator-cronjob-asm-1-21 */10 * * * * False 0
可以运行以下命令来检查上次运行的 cronjob 日志:
kubectl logs --namespace aks-istio-system $(kubectl get pods --namespace aks-istio-system | grep 'istio-cert-validator-cronjob-' | sort -k8 | tail -n 1 | awk '{print $1}')
此命令生成以下输出消息之一,具体取决于是否检测到根证书更新:
Root certificate update not detected.
Root certificate update detected. Restarting deployment... deployment.apps/istiod-asm-1-21 restarted Deployment istiod-asm-1-21 restarted.
确定部署日志中的证书类型
可以查看 istiod
部署日志,以确定是拥有自签名 CA 证书还是插件 CA 证书。 若要查看日志,请运行以下命令:
kubectl logs deploy/istiod-asm-1-21 --container discovery --namespace aks-istio-system | grep -v validationController
在每个证书日志条目之前,紧接着是描述该类型的证书的另一个日志条目。 对于自签名的 CA 证书,条目指出“没有插入证书在 etc/cacerts/ca-key.pem;使用自签名证书。”对于插件证书,条目指出“在 etc/cacerts/ca-key.pem 中使用插入证书”。下表显示了与证书相关的示例日志条目。
自签名 CA 证书的日志条目
Timestamp 日志级别 消息 2023-11-20T23:27:36.649019Z info 使用 istiod 文件格式对 ca 文件进行签名 2023-11-20T23:27:36.649032Z info 在 etc/cacerts/ca-key.pem 上没有插入证书;使用自签名证书 2023-11-20T23:27:36.649536Z info x509 证书 - <证书详细信息> 2023-11-20T23:27:36.649552Z info 重新加载 Istiod 证书 2023-11-20T23:27:36.649613Z info spiffe 在对等证书验证程序中添加了 1 个证书,用于信任域群集.local 插件 CA 证书的日志条目
Timestamp 日志级别 消息 2023-11-21T00:20:25.808396Z info 使用 istiod 文件格式对 ca 文件进行签名 2023-11-21T00:20:25.808412Z info 在 etc/cacerts/ca-key.pem 上使用插入证书 2023-11-21T00:20:25.808731Z info x509 证书 - <证书详细信息> 2023-11-21T00:20:25.808764Z info x509 证书 - <证书详细信息> 2023-11-21T00:20:25.808799Z info x509 证书 - <证书详细信息> 2023-11-21T00:20:25.808803Z info 重新加载 Istiod 证书 2023-11-21T00:20:25.808873Z info spiffe 在对等证书验证程序中添加了 1 个证书,用于信任域群集.local
日志条目中的证书详细信息显示为颁发者、使用者、序列号(SN(长十六进制字符串)的逗号分隔值,以及定义证书有效时间的开始和结束时间戳值。
对于自签名 CA 证书,有一个详细信息条目。 下表显示了此证书的示例值。
颁发者 | Subject | SN | NotBefore | NotAfter |
---|---|---|---|---|
“O=cluster.local” | "" | <32 位十六进制值> | “2023-11-20T23:25:36Z” | “2033-11-17T23:27:36Z” |
对于插件 CA 证书,有三个详细信息条目。 其他两个条目用于根证书更新和对中间证书的更改。 下表显示了这些条目的示例值。
颁发者 | Subject | SN | NotBefore | NotAfter |
---|---|---|---|---|
CN=中间 CA - A1,O=Istio,L=cluster-A1” | "" | <32 位十六进制值> | “2023-11-21T00:18:25Z” | “2033-11-18T00:20:25Z” |
CN=Root A,O=Istio” | “CN=中间 CA - A1,O=Istio,L=cluster-A1” | <40 位十六进制值> | “2023-11-04T01:40:22Z” | “2033-11-01T01:40:22Z” |
CN=Root A,O=Istio” | “CN=Root A,O=Istio” | <40 位十六进制值> | “2023-11-04T01:38:27Z” | “2033-11-01T01:38:27Z” |
排查常见问题
问题 1:对 Azure 密钥库的访问设置不正确
启用 Azure 密钥库机密提供程序加载项后,必须向 Azure 密钥库授予加载项的用户分配托管标识的访问权限。 设置对 Azure 密钥库的访问不正确会导致加载项安装停止。
kubectl get pods --namespace aks-istio-system
在 Pod 列表中,可以看到 istiod-asm-1-21
Pod 停滞在 Init:0/2
某个状态。
名称 | 就绪 | 状态 | RESTARTS | 年龄 |
---|---|---|---|---|
istiod-asm-1-21-6fcfd88478-2x95b | 0/1 | 正在终止 | 0 | 5m55s |
istiod-asm-1-21-6fcfd88478-6x5hh | 0/1 | 正在终止 | 0 | 5m40s |
istiod-asm-1-21-6fcfd88478-c48f9 | 0/1 | Init:0/2 | 0 | 54s |
istiod-asm-1-21-6fcfd88478-wl8mw | 0/1 | Init:0/2 | 0 | 39 秒 |
若要验证 Azure 密钥库访问问题,请kubectl get pods
运行以下命令以查找命名空间中具有secrets-store-provider-azure
标签的 kube-system
Pod:
kubectl get pods --selector app=secrets-store-provider-azure --namespace kube-system --output name | xargs -I {} kubectl logs --namespace kube-system {}
以下示例输出显示发生“403 禁止访问”错误,因为你对密钥库的机密没有“get”权限:
“无法处理装载请求”err=“未能获取 objectType:secret, objectName:<secret-object-name>, objectVersion:: keyvault。BaseClient#GetSecret:响应请求失败:StatusCode=403 -- 原始错误:autorest/azure:服务返回错误。 Status=403 Code=\“Forbidden\” Message=\“User, group or application 'appid=<appid>;oid=<oid>;iss=<iss>“ 没有机密获取密钥保管库”MyAzureKeyVault“的权限;location=eastus'. 有关解决此问题的帮助,请参阅 https://go.microsoft.com/fwlink/?linkid=2125287\“ InnerError={\”code\“:\”AccessDenied\“}”
若要解决此问题,请通过获取对 Azure 密钥库 机密的 Get 和 List 权限并重新安装 Istio 加载项来设置对 Azure 密钥库 机密提供程序加载项的用户分配托管标识的访问权限。 首先,通过运行 az aks show 命令,获取 Azure 密钥库 机密提供程序加载项的用户分配托管标识的对象 ID:
OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId')
若要设置访问策略,请通过指定获取的对象 ID 来运行以下 az keyvault set-policy 命令:
az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
注意
是否使用 Azure RBAC 授权为权限模型而不是保管库访问策略创建密钥库? 在这种情况下,请参阅使用 Azure 基于角色的访问控制提供对密钥库密钥、证书和机密的访问权限,以创建托管标识的权限。 为密钥库读取者添加 Azure 角色分配,以便为加载项的用户分配托管标识。
问题 2:未设置自动检测密钥库机密更改
若要使群集自动检测 Azure 密钥库 机密中的更改,必须为 Azure 密钥库 提供程序加载项启用自动轮换。 自动轮换可以自动检测中间证书和根证书中的更改。 对于启用 Azure 密钥库 提供程序加载项的群集,请az aks show
运行以下命令来检查是否启用了自动轮换:
az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER | jq -r '.addonProfiles.azureKeyvaultSecretsProvider.config.enableSecretRotation'
如果群集启用了 Azure 密钥库 提供程序加载项,请az aks show
运行以下命令来确定轮询间隔:
az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER | jq -r '.addonProfiles.azureKeyvaultSecretsProvider.config.rotationPollInterval'
Azure 密钥库在上一次同步后轮询间隔时间过后与群集同步。 默认间隔值为两分钟。
问题 3:证书值缺失或配置不正确
如果 Azure 密钥库中缺少机密对象,或者这些对象配置不正确,istiod-asm-1-21
Pod 可能会停滞在Init:0/2
状态中,从而延迟加载项的安装。 若要查找此问题的根本原因,请针对istiod
部署运行以下命令kubectl describe
并查看输出:
kubectl describe deploy/istiod-asm-1-21 --namespace aks-istio-system
该命令显示可能与以下输出表类似的事件。 在此示例中,缺少机密是问题的原因。
类型 | 原因 | 年龄 | From | 消息 |
---|---|---|---|---|
正常 | 计划 | 3m9s | default-scheduler | 已成功将 aks-istio-system/istiod-asm-1-21-6fcfd88478-hqdjjj 分配到 aks-userpool-24672518-vmss000000 |
警告 | FailedMount | 66s | kubelet | 无法附加或装载卷:卸载的卷=[cacerts]、未附加的卷=[]、无法处理卷=[]:等待条件超时 |
警告 | FailedMount | 61s (x9 超过 3m9s) | kubelet | 卷“cacerts”的 MountVolume.SetUp 失败:rpc 错误:代码 = 未知 desc = 无法为 pod aks-istio-system/istiod-asm-1-21-6fcfd88478-hqdjj 装载机密存储对象, err: rpc error: code = Unknown desc = failed to mount objects, error: failed to get objectType:secret, objectName:test-cert-chain, objectVersion:: keyvault.BaseClient#GetSecret:响应请求失败:StatusCode=404 -- 原始错误:autorest/azure:服务返回错误。 Status=404 Code=“SecretNotFound” Message=“A secret with (name/id) test-cert-chain 的机密未在此密钥保管库中找到。 如果最近删除了此机密,则可以使用正确的恢复命令恢复它。 有关解决此问题的帮助,请参阅 https://go.microsoft.com/fwlink/?linkid=2125182” |
资源
第三方信息免责声明
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 对这些产品的性能和可靠性不作任何明示或默示担保。
第三方联系人免责声明
Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。
联系我们寻求帮助
如果你有任何疑问或需要帮助,请创建支持请求或联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区。