Azure Kubernetes 服务 (AKS) 中的证书轮换

Azure Kubernetes 服务 (AKS) 使用证书对其许多组件进行身份验证。 出于安全或策略原因,需要定期轮换这些证书。 本文介绍如何在 AKS 群集中使用证书轮换。

先决条件

  • 本文需要 Azure CLI 2.0.77 或更高版本。 使用 az --version 命令查看版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

  • 使用以下命令配置 kubectl 以连接到 AKS 群集 az aks get-credentials

    az aks get-credentials --resource-group <resource-group> --name <cluster-name>
    

AKS 证书、证书颁发机构和服务帐户

AKS 可生成和使用以下证书、证书颁发机构 (CA) 和服务帐户 (SA):

  • AKS API 服务器创建一个名为 群集 CA 的 CA,该 CA 对证书进行单向通信(从 API 服务器到 kubelet)进行签名。
  • 每个 kubelet 会创建一个证书签名请求 (CSR),该 CSR 由群集 CA 签名,用于从 kubelet 到 API 服务器的通信。
  • API 聚合器使用群集 CA 颁发证书,以便与其他 API 进行通信。 API 聚合器也可以拥有自己的 CA 来颁发这些证书,但它目前使用群集 CA。
  • 每个代理节点都使用群集 CA 签名的 SA 令牌。
  • kubectl 客户端具有用于与 AKS 群集通信的证书。

Azure 将维护本部分所述的所有证书,但群集证书除外。

证书到期日期

重要

证书的到期日期取决于 AKS 群集的创建时间:

  • 对于 2019 年 5 月之前创建的 AKS 群集,其证书将在两年后到期。
  • 对于 2019 年 5 月之后创建的 AKS 群集,其群集 CA 证书将在 30 年后到期。

可以使用命令 kubectl get nodes 验证群集的创建时间,该命令会显示代理节点 Age

检查群集证书到期日期

  • 使用 kubectl config view 命令检查群集证书的到期日期。

    kubectl config view --raw -o jsonpath="{.clusters[?(@.name == '')].cluster.certificate-authority-data}" | base64 -d | openssl x509 -text | grep -A2 Validity
    

检查 API 服务器证书过期日期

  • 使用 curl 以下命令检查 API 服务器证书的到期日期:

    curl https://{apiserver-fqdn} -k -v 2>&1 | grep expire
    

检查虚拟机(VM)代理节点证书过期日期

  • 使用 az vm run-command invoke 命令检查 VM 代理节点证书的到期日期。

    此命令中的关键参数: - --resource-group <node-resource-group>包含 VM 代理节点的资源组。 - --name <vm-name>:VM 代理节点的名称。 - --scripts "openssl x509 -in /etc/kubernetes/certs/apiserver.crt -noout -enddate":检索位于 /etc/kubernetes/certs/apiserver.crt的 API 服务器证书的到期日期的脚本。

    az vm run-command invoke --resource-group <node-resource-group> --name <vm-name> --command-id RunShellScript --query 'value[0].message' -otsv --scripts "openssl x509 -in /etc/kubernetes/certs/apiserver.crt -noout -enddate"
    

检查 Azure 虚拟机规模集代理节点的证书过期时间

  • 使用 az vmss run-command invoke 命令检查 Azure 虚拟机规模集代理节点证书的到期日期。

    此命令中的关键参数: - --resource-group <node-resource-group>包含 Azure 虚拟机规模集代理节点的资源组。 - --name <vmss-name>:Azure 虚拟机规模集的名称。 - --instance-id 1:Azure 虚拟机规模集代理节点的实例 ID。 - --scripts "openssl x509 -in  /var/lib/kubelet/pki/kubelet-client-current.pem -noout -enddate":用于检索位于的 /var/lib/kubelet/pki/kubelet-client-current.pemkubelet 客户端证书的到期日期的脚本。

    az vmss run-command invoke --resource-group <node-resource-group> --name <vmss-name> --command-id RunShellScript --instance-id 1 --scripts "openssl x509 -in  /var/lib/kubelet/pki/kubelet-client-current.pem -noout -enddate" --query "value[0].message"
    

手动轮换群集证书

  1. 使用 az aks rotate-certs 命令轮换群集上的所有证书、CA 和 SA。

    az aks rotate-certs --resource-group <resource-group> --name <cluster-name>
    

    重要

    az aks rotate-certs 命令会重新创建所有代理节点、Azure 虚拟机规模集和磁盘。 此命令还可能导致 AKS 群集 停机长达 30 分钟 。 如果在完成之前命令失败,请使用 [az aks show][az-aks-show] 命令验证群集的状态。Certificate Rotating 如果群集处于失败状态,请重新运行 az aks rotate-certs 命令以再次轮换证书。

  2. 使用任何 kubectl 命令验证旧证书是否不再有效。 以下示例使用 kubectl get nodes 命令:

    kubectl get nodes
    

    如果未更新所使用的 kubectl证书,则会看到类似于以下示例输出的错误:

    Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "ca")
    
  3. 使用带有 kubectl 标志的 az aks get-credentials 命令更新 --overwrite-existing 使用的证书。

    az aks get-credentials --resource-group <resource-group> --name <cluster-name> --overwrite-existing
    
  4. 使用 kubectl get 命令验证证书是否已更新。

    kubectl get nodes
    

如果有任何服务在 AKS 上运行,则可能需要更新其证书。

更新 kubelet 服务证书

轮换 kubelet 服务证书时,AKS 允许 kubelet 服务器传输层安全性 (TLS) 引导,以便引导和轮换群集 CA 签名的服务证书。

kubelet 服务证书轮换的限制

  • 在 Kubernetes 版本 1.27 及更高版本上受支持。
  • 当节点池使用基于任何早于 202501.12.0 的节点映像的节点池快照时,不受支持。
  • 无法手动启用此功能。 Kubelet 服务证书轮换在现有的节点池上默认情况下启用,当它们执行第一次升级到任何 Kubernetes 版本 1.27 或更高版本时。 默认情况下,Kubernetes 1.27 或更高版本的新节点池启用了 Kubelet 服务证书轮换。 要查看区域内是否已启用 kubelet 服务证书轮换,请检查 AKS 版本

验证是否已启用 kubelet 服务证书轮换

启用该功能的每个节点都将自动获得标签 kubernetes.azure.com/kubelet-serving-ca=cluster

  • 使用 kubectl get nodes -L kubernetes.azure.com/kubelet-serving-ca 命令验证标签是否已设置。

    kubectl get nodes -L kubernetes.azure.com/kubelet-serving-ca
    

    输出应显示每个代理节点的标签kubernetes.azure.com/kubelet-serving-ca及其对应值cluster

验证 kubelet TLS 引导功能是否正常工作

  • 使用 kubectl get 命令验证引导过程是否已发生。

    kubectl get csr --field-selector=spec.signerName=kubernetes.io/kubelet-serving
    

    在输出中,所有待处理的 CSR 都应处于 Approved,Issued 状态,这表示这些 CSR 已被批准并颁发了签名证书。 服务 CSR 的签名者名称为 kubernetes.io/kubelet-serving。 例如:

    NAME        AGE    SIGNERNAME                                    REQUESTOR                    REQUESTEDDURATION   CONDITION
    csr-1ab2c   113s   kubernetes.io/kube-apiserver-client-kubelet   system:bootstrap:uoxr9r      none              Approved,Issued
    csr-defgh   111s   kubernetes.io/kubelet-serving                 system:node:akswinp7000000   none              Approved,Issued
    csr-ij3kl   46m    kubernetes.io/kubelet-serving                 system:node:akswinp6000000   none              Approved,Issued
    csr-mn4op   46m    kubernetes.io/kube-apiserver-client-kubelet   system:bootstrap:ho7zyu      none              Approved,Issued
    

验证 kubelet 是否使用从服务器 TLS 引导获取的证书

  • 使用 kubectl debug 命令确认 kubelet 正在使用由群集 CA 签名的服务证书。

    kubectl debug node/<node> -ti --image=mcr.azk8s.cn/azurelinux/base/core:3.0 -- ls -l /host/var/lib/kubelet/kubelet-server-current.pem
    

    如果存在kubelet-server-current.pem符号链接,则 kubelet 初始化或更新其自身的服务证书,由集群 CA 签署。

禁用 kubelet 服务证书轮换

  • 使用 az aks nodepool update 命令并结合 aks-disable-kubelet-serving-certificate-rotation=true 标签更新节点池,以禁用 kubelet 提供的证书轮换。

    az aks nodepool update --cluster-name <cluster-name> --resource-group <resource-group> --name <node-pool-name> --tags aks-disable-kubelet-serving-certificate-rotation=true
    
  1. 使用 节点映像升级 或通过将池缩放到个实例后再扩展到所需数量来重置节点。

证书自动轮换

使用证书自动轮换时,请记住以下注意事项:

  • 如果有现有群集,则必须升级该群集才能启用证书自动轮用。
  • 不要禁用 TLS Bootstrap,以保持证书自动轮换功能处于启用状态。
  • 如果在证书自动轮换期间群集处于停止状态,则只会轮换控制平面证书。 在这种情况下,应在证书轮换后重新创建节点池,以启动节点池证书轮换。
  • 对于在 2022 年 3 月之后创建或升级的任何 AKS 群集,AKS 会在客户端证书有效时间的 80% 内自动轮换控制平面和代理节点上的非 CA 证书,且群集不会停机。

验证当前的代理节点池是否启用了 TLS 启动

  1. 通过浏览到以下路径,验证群集是否启用了 TLS 引导:

    • 在 Linux 节点上/var/lib/kubelet/bootstrap-kubeconfig/host/var/lib/kubelet/bootstrap-kubeconfig
    • 在 Windows 节点上C:\k\bootstrap-config

    有关详细信息,请参阅连接到 Azure Kubernetes 服务 (AKS) 群集节点以进行维护或故障排除

    注意

    随着 Kubernetes 版本的发展,文件路径可能会更改。

  2. 配置区域后,创建新的群集或升级现有群集以设置群集证书的证书自动轮换。 需要升级控制平面和节点池才能启用此功能。