轮替集群凭据


本页面介绍如何在 Google Kubernetes Engine (GKE) 集群中执行凭据轮替。

GKE 中的凭据轮替简介

集群根证书授权机构 (CA) 的生命周期有限。CA 过期后,所有由 CA 签名的凭据将不再有效,包括集群客户端证书(来自 MasterAuth API 字段)、API 服务器的密钥和证书以及 kubelet 客户端证书。如需了解详情,请参阅集群根 CA 生命周期

您可以执行凭据轮替以便为集群撤消凭据并颁发新凭据。此操作会轮替集群 CA 私钥,并需要重新创建节点以使用新凭据。您必须在当前凭据到期之前为集群启动和完成凭据轮替。除轮替凭据外,凭据轮替还执行 IP 地址轮替

何时执行凭据轮替

您应在当前凭据到期日期之前定期执行凭据轮替。凭据轮替需要重新创建节点才能使用新凭据,这可能会中断正在运行的工作负载。规划维护时段并在维护窗口执行轮替,以避免工作负载意外停机或集群外部的 API 客户端无响应。

查找凭据即将过期或已过期的集群

如果集群的凭据将在未来 180 天内过期,或者集群的凭据已过期,则 GKE 会提供包含数据分析和建议的指导,说明您必须为此集群执行凭据轮替。此指导包含凭据的过期日期。您可以在 Google Cloud 控制台中查看此指导。或者,您可以使用 gcloud CLI 或 Recommender API 查看此指导,并指定 CLUSTER_CA_EXPIRATION 子类型。

如果您收到集群的数据分析和建议,则必须执行凭据轮替,否则 GKE 会在当前 CA 过期日期前的 30 天内自动启动凭据轮替,如下一部分所述。

用于防止集群服务中断的 GKE 自动化政策

为了防止集群在当前凭据过期时进入不可恢复的状态,GKE 会在当前 CA 过期日期前的 30 天内自动启动凭据轮替。例如,如果集群 CA 于 2024 年 1 月 6 日过期,而您未在 2023 年 12 月 5 日之前轮替凭据,则 GKE 会在 2023 年 12 月 7 日或之后启动自动轮替,并且会在操作开始七天后完成此轮替。这种自动轮替是用于防止集群服务中断的最后手段,因此请考虑以下事项:

  • 自动轮替会忽略任何已配置的维护窗口或维护排除项
  • 凭据轮替完成后,到期的凭据将被撤消。除非您将客户端配置为使用新凭据,否则集群外部的 Kubernetes API 客户端(如本地环境中的 kubectl)将无法运行
  • 在轮替期间重新创建节点池可能会导致正在运行的工作负载中断

GKE 启动的自动轮替是最后的服务中断预防措施。请不要仅依赖这些自动轮替,它们只是一项用于避免完全服务中断的预防性紧急措施。

须知事项

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

检查凭据生命周期

我们建议您在执行凭据轮替前后检查凭据生命周期,以便了解集群根 CA 的有效性。

如需检查单个集群的凭据生命周期,请运行以下命令:

gcloud container clusters describe CLUSTER_NAME \
    --region REGION_NAME \
    --format "value(masterAuth.clusterCaCertificate)" \
    | base64 --decode \
    | openssl x509 -noout -dates

输出类似于以下内容:

notBefore=Mar 17 16:45:34 2023 GMT
notAfter=Mar  9 17:45:34 2053 GMT

如需检查项目中所有集群的凭据生命周期,请运行以下命令:

gcloud container clusters list --project PROJECT_ID \
    | awk 'NR>1 {print "echo; echo Validity for cluster " $1 " in location " $2 ":;\
         gcloud container clusters describe --project PROJECT_ID " $1 " --location " $2 " \
         --format \"value(masterAuth.clusterCaCertificate)\" \
         | base64 --decode | openssl x509 -noout -dates"}' \
    | bash

执行凭据轮替

凭据轮替包括以下步骤:

  1. 开始轮替:除了原始 IP 地址以外,控制层面还会通过新 IP 地址开始处理流量。新凭据会颁发给工作负载和控制平面。
  2. 重新创建节点:GKE 会重新创建集群节点,以便节点使用新的 IP 地址和凭据,并遵循可用的维护窗口和排除项。
  3. 更新 API 客户端:启动轮替后,更新任何集群 API 客户端(例如使用 kubectl 的开发机器),以使用新的 IP 地址与控制平面进行通信。
  4. 完成轮替:控制层面会停止通过原始 IP 地址处理流量。旧凭据会被撤销,包括 Kubernetes ServiceAccount 的任何现有静态凭据。

启动轮替

如需启动凭据轮替,请运行以下命令:

gcloud container clusters update CLUSTER_NAME \
    --region REGION_NAME \
    --start-credential-rotation

此命令会创建新凭据,向控制平面颁发这些凭据,并将控制平面配置为通过两个 IP 地址(原始 IP 地址和新 IP 地址)处理流量。

重新创建节点

重新配置 API 服务器以在新 IP 地址上提供服务后,如果有可用的维护窗口,GKE 会自动更新节点以使用新的 IP 地址和凭据。GKE 会将所有节点升级到节点已经运行的 GKE 版本,从而重新创建节点。如需了解详情,请参阅节点池升级

默认情况下,GKE 会在您启动操作七天后自动完成凭据轮替。如果集群中的活跃维护窗口或排除项阻止 GKE 在这七天内重新创建某些节点,则凭据轮替无法完成。

  • 如果您使用可能导致轮替失败的维护排除项或维护窗口,请手动升级集群以强制重新创建节点:

    gcloud container clusters upgrade CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=VERSION
    

    VERSION 替换为集群已在使用的同一 GKE 版本

    如需了解详情,请参阅维护窗口的注意事项

检查节点池重新创建的进度

  1. 要启动轮替操作,请运行以下命令:

    gcloud container operations list \
        --filter="operationType=UPGRADE_NODES AND status=RUNNING" \
        --format="value(name)"
    

    此命令返回节点升级操作的 ID

  2. 要轮询操作,请将操作 ID 传递给以下命令:

    gcloud container operations wait OPERATION_ID
    

节点池会逐一重新创建,并且每个节点池都有自己的操作。如果您有多个节点池,请按照以下说明轮询每个操作。

更新 API 客户端

启动凭据轮替后,您必须更新集群外的所有 API 客户端(例如开发者机器上的 kubectl)才能使用新凭据并指向控制平面的新 IP 地址。

要更新 API 客户端,请为每个客户端运行以下命令:

gcloud container clusters get-credentials CLUSTER_NAME \
    --region REGION_NAME

更新 Kubernetes ServiceAccount 凭据

如果您在集群的 ServiceAccount 中使用静态凭据,请切换到短期凭据。完成轮替会使现有的 ServiceAccount 凭据失效。如果您不想使用短期凭据,请确保在完成轮替后为集群中的所有 ServiceAccounts 重新创建静态凭据。

更新硬编码的 IP 地址和防火墙规则

如果您在环境中对控制平面的 IP 地址进行了硬编码,或者有防火墙规则以控制平面的 IP 地址为目标,请将地址更新为新的 IP 地址。如果您完成轮替但未在应用和防火墙规则中更新 IP 地址,则当 GKE 停止在之前的控制平面 IP 地址上提供服务时,这些资源可能会中断。

完成轮替

更新集群外部的 API 客户端后,请完成轮替以将控制平面配置为仅通过新凭据和新 IP 地址处理流量:

gcloud container clusters update CLUSTER_NAME \
    --region=REGION_NAME \
    --complete-credential-rotation

如果凭据轮替无法完成,并返回类似于以下内容的错误消息,请参阅问题排查

ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.

后续步骤