GKE:升级策略、停止条件与回退
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
先查目标 location/channel 可用版本,控制面和 node pool 分别推进。
推荐做法#
- 升级前验证废弃 API、插件、备份恢复、PDB、Pod IP 与 surge 配额。
- Standard 先试点 pool;Autopilot 节点交给平台,持续检查业务直到收敛。
- 按当前升级阶段确认 rollback 资格;预设错误率、延迟与数据一致性停止条件。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
LOCATION='REPLACE_REGION_OR_ZONE'
CLUSTER='REPLACE_CLUSTER'
gcloud container get-server-config --project="$PROJECT_ID" --location="$LOCATION"
gcloud container clusters describe "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
gcloud container operations list --project="$PROJECT_ID" --location="$LOCATION"容易踩的坑#
- 手动升级不受 maintenance window 阻止;PDB 不能无限延迟平台驱逐。
已完成的控制面 minor 升级不能随意降回上一 minor;取消操作也不还原已升级节点。 回退资格按当前阶段判断,见下方恢复表,变更前准备兼容修复或新集群恢复方案。
配置说明与完整示例(按需展开)
适用于 Standard / Autopilot。控制面由 GKE 管理;不要运行 kubeadm,也不能自行恢复托管 etcd。前置:GKE 实验、IAM。以下 Bash 命令逐段执行,Standard node pool 步骤不用于 Autopilot 集群。
阅读本篇前先理解的概念#
控制面管理 API,节点承载 Pod,node pool统一管理节点配置;它们是不同升级对象。GKE 托管存储对象状态的 etcd,自建集群工具 kubeadm 不适用。
| 术语 | 在升级中表示什么 |
|---|---|
| minor / patch | 1.N.P 中的 N 是次版本,P 是补丁版本;例如 1.35 → 1.36 是 minor 升级 |
| release channel | GKE 的版本发布选择与升级节奏配置,决定可用版本与自动升级节奏 |
| 版本偏差(version skew) | 控制面、节点和客户端之间允许的版本差距,不能任意混用 |
| 维护窗口 / 排除期 | 允许自动维护的时间安排 / 在限定期限内限制指定自动升级范围 |
| PDB | PodDisruptionBudget,约束自愿驱逐时的副本可用性 |
| readiness | 应用就绪检查,决定 Pod 是否可以接收服务流量 |
| surge 升级 | 临时增加新节点,逐步替换旧节点 |
| 蓝绿升级 | 并行准备新旧两组节点,迁移业务并观察后再删除旧节点 |
| soak duration / 观察期 | 某个升级阶段停留观察的时长,需区分控制面与 node pool 的观察阶段 |
| PVC / CSI | 持久存储申请 / 容器存储接口;升级需验证卷重新挂载与读写 |
集群内 namespace、工作负载身份、kubeconfig 与 context 的说明见 GKE 入门;私网管理机及 endpoint 的说明见 Standard 集群。
1. 选择路径#
| 场景 | 做法 |
|---|---|
| 补丁升级 | 固定完整 1.N.P-gke.BUILD;先控制面,再 Standard node pool,仍会重建节点 |
| minor 升级 N → N+1 | 检查 API/插件 → 控制面 → 节点 → 业务验收 |
| 跨多个 minor | N → N+1 → N+2,每跳完成节点和观察;不跨级升级控制面 |
| Autopilot | 可手动请求控制面升级,节点由 GKE 自动升级;持续检查节点/业务直到收敛 |
| 真正 1.x → 2.x / 版本断档 | 另查迁移政策;必要时新建集群迁移,不能假设原地升级兼容 |
不要把社区 Kubernetes 版本偏差上限直接当成 GKE 规则;本手册每跳先对齐当前 minor,升级后完成节点再继续。区域型 Standard/Autopilot 控制面具有冗余;zonal Standard 升级期间可能暂时无法操作 API。GKE 升级约束
2. 检查、备份、维护窗口#
网络验收与 Pod 地址容量检查见 GKE 网络详解,特别核对升级 surge 的地址余量,以及控制面和业务入口的不同路径。
升级前核对扩展:CRD 定义自定义资源,Operator 管理它们,webhook 参与 API 请求/转换;Helm 渲染应用清单,GitOps 同步 Git 中的配置。
节点侧核对 OS(COS / Ubuntu)、运行时 containerd、资源隔离机制 cgroup;调度检查 affinity / taint,存储检查临时卷 emptyDir 与节点 local SSD。
| 检查 | 放行条件 |
|---|---|
| API/插件 | GKE 升级建议、废弃 API 审计 + Git/Helm/Operator/CRD/webhook 检查;CSI、Mesh、Ingress、监控、安全组件支持目标版本 |
| 节点/OS | 核对 COS/Ubuntu、containerd、cgroup、GPU 驱动、架构和本地 SSD;不同时更换整套配置 |
| 数据 | Backup for GKE/既有工具的对象与卷备份在隔离环境恢复成功;Cloud SQL 等外部数据另备份 |
| 调度 | 多副本跨节点/区;PDB 可驱逐,readiness/退出/LB 摘流通过;检查 affinity、 taint、卷 AZ 和挂载限制 |
| 容量 | surge/蓝绿所需 vCPU、GPU、磁盘、节点和 Pod 次级 IP 范围有余量;各区实际容量也要满足 |
| 权限/网络 | 操作者 IAM + RBAC、备用入口、节点 SA、Workload Identity、镜像仓库、私网出口均验证 |
| 变更 | 同配置测试集群预演;冻结应用/Schema 变更,协调 GitOps 和自动缩容;设置停止阈值、恢复时限与负责人 |
PDB 不是无限保护:常规节点升级最多等待约 1 小时,然后可能强制驱逐。长任务先 checkpoint/迁走;单副本和 local SSD/emptyDir 数据不能依靠 PDB 保证安全。节点升级行为
export PROJECT_ID='替换项目'
export CLUSTER='替换集群'
export LOCATION='替换region或zone' # 必须与集群一致
gcloud auth list
gcloud container clusters describe "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
gcloud container get-server-config --project="$PROJECT_ID" --location="$LOCATION"
gcloud container clusters get-credentials "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
kubectl config current-context
kubectl get nodes -o wide
kubectl get pods,pdb,pvc -A
gcloud container clusters get-upgrade-info "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"get-credentials 更新 kubeconfig 并切换 context,升级前核对目标。--location 接受 Region 或 Zone;私网前提见 集群入口。
记录完整版本、release channel、node pool/镜像、维护策略和 API 风险;目标须为该 location/channel 可用版本,不用 latest。保存配置:
umask 077
export RECORD_DIR="gke-upgrade-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -m 700 "$RECORD_DIR"
gcloud container clusters describe "$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--format=yaml > "$RECORD_DIR/cluster-before.yaml"
export TARGET_VERSION='替换完整GKE版本'release channel 决定版本可用性和自动升级节奏,不应为一次升级随意换 channel。通过维护窗口/排除期协调自动升级;手动升级不受窗口拦截,安全/支持期例外也要考虑。维护策略
需要短期排除自动升级时,先与现有策略核对,用实际 RFC3339 UTC 时间替换(如 2026-10-12T08:00:00Z,结尾 Z 表示 UTC,不是本地时区);no_upgrades 最长 30 天,演练通常只需数小时:
export WINDOW_START='替换为开始时间,例如YYYY-MM-DDTHH:MM:SSZ'
export WINDOW_END='替换为结束时间'
gcloud container clusters update "$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--add-maintenance-exclusion-name=upgrade-runbook \
--add-maintenance-exclusion-start="$WINDOW_START" \
--add-maintenance-exclusion-end="$WINDOW_END" \
--add-maintenance-exclusion-scope=no_upgrades排除期不取消已开始的操作;Autopilot 节点依赖自动升级,演练结束按计划解除排除。
每一跳升级先填写 变更执行记录,明确节点/业务超时阈值、恢复负责人及最晚决策时间;回退资格以本篇恢复章节和当次平台查询结果为准。
3. 控制面:以下二选一#
A. 补丁,或已完整验证的单步 minor 升级#
gcloud container clusters upgrade "$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--master \
--cluster-version="$TARGET_VERSION"clusters upgrade --master 升级控制面,--cluster-version 指定核对过的完整目标版本。它不表示 Standard 的所有 node pool 已升级完成; node pool 需按第 4 节逐池处理。
单步 minor 完成后不能退回原 minor;必须有新集群恢复方案。
B. minor 两阶段升级:需要观察与有限回退窗口#
当前官方提供升级到 1.33+ 的两阶段机制,CLI 使用 beta 命令;先确认环境/工具支持及组织对该接口的使用要求:
gcloud beta container clusters upgrade "$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--master \
--cluster-version="$TARGET_VERSION" \
--control-plane-soak-duration=24hbinary version是控制面实际运行的软件版本;emulated version是当前模拟的 Kubernetes API 行为版本。两阶段升级先更换二进制,观察期仍模拟旧版本 API;观察期可设 6 小时到 7 天,结束后进入新 API 行为。观察期通过不代表移除 API 已验证,必须提前在目标版本测试集群演练。期间节点不能超过 emulated version;不要提前升级节点。具体回退见第 6 节。两阶段机制
两种方式均检查 operation 和业务;两阶段还需确认 emulated version 已推进:
gcloud container operations list --project="$PROJECT_ID" --location="$LOCATION"
gcloud container clusters get-upgrade-info "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
gcloud container clusters describe "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"operation 须无 error,且两阶段观察期结束、emulated version 推进后才升级节点。状态查询
4. Standard:试点 node pool,再逐池升级#
先选小 node pool 承载代表性业务;需要新建试点池时,复制 IAM、网络、标签、 taint、磁盘、架构等配置。节点标签应配置在 node pool,避免只在单节点 kubectl label 后重建丢失。
export POOL='替换节点池'
gcloud container node-pools describe "$POOL" \
--cluster="$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--format=yaml > "$RECORD_DIR/$POOL-before.yaml"策略二选一,配置成功后再发起升级:
# A:surge,小批滚动;额外资源要有实际配额/容量。
gcloud container node-pools update "$POOL" \
--cluster="$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--enable-surge-upgrade \
--max-surge-upgrade=1 \
--max-unavailable-upgrade=0Spot 容量可能被回收,不保证先建后删;关键业务保留按需容量。surge 按 node pool 的每个 Zone 计算配额。
# B:蓝绿,保留旧节点观察;先准备约双份节点资源和费用。
gcloud container node-pools update "$POOL" \
--cluster="$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--enable-blue-green-upgrade \
--standard-rollout-policy=batch-node-count=1,batch-soak-duration=300s \
--node-pool-soak-duration=3600s上面是实验参数,生产按业务调整。蓝绿进入删除旧池阶段后不能依靠旧节点回退;删除阶段不再按 PDB 无限等待。维护窗口结束也不保证蓝绿操作立即暂停。策略与阶段、配置参数
gcloud container clusters upgrade "$CLUSTER" \
--node-pool="$POOL" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--cluster-version="$TARGET_VERSION"
gcloud container node-pools describe "$POOL" --cluster="$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
kubectl get nodes -l "cloud.google.com/gke-nodepool=$POOL" -o wideclusters upgrade --node-pool 按预设策略替换指定池的节点;node-pools update 仅设置策略,不执行升级。
检查 operation 成功无 error、所有节点真实版本和业务测试;蓝绿还要看 updateInfo.blueGreenInfo.phase。试点通过后才操作下一池,不能只看 pool 的版本字段就认定全部完成。
**Autopilot 分支:**跳过本节的手动 node pool 操作,查看升级通知、节点版本和业务状态;解除本次排除后让 GKE 自动推进。容量/PDB/长任务仍由你准备,不能把控制面完成等同于全体节点完成。
5. 每批验收与停止条件#
operation 是云端异步操作记录,ID 用于查询或取消。业务停止阈值使用既定 SLO(服务目标)及 p95(95% 请求不超过的延迟)。
按 每批可执行检查 核对本批节点上的实际业务 Pod;使用本文的云端操作状态作为额外放行条件。
NetworkPolicy 限制 Pod 流量;DaemonSet 在符合条件的节点运行 Agent。Pending 表示尚未运行,CrashLoopBackOff 表示反复失败后退避,均需查事件和日志。
新节点上验证:镜像拉取、DNS、Service/跨节点网络、NetworkPolicy、Workload Identity、PVC 重挂载和读写、Ingress/Gateway/LB、外部真实请求。检查系统 DaemonSet、Pending、CrashLoop、错误率、p95、队列积压和数据一致性。
任何数据错误、关键交易失败或超过预定 SLO,停止发起下一批。找出操作 ID 后确认目标集群/池,再处理;不要删除 Pod 或放宽 PDB 强行“解卡”。
gcloud container operations list --project="$PROJECT_ID" --location="$LOCATION"
export OPERATION_ID='替换核对过的节点升级operation'
gcloud container operations describe "$OPERATION_ID" --project="$PROJECT_ID" --location="$LOCATION"
# 仅针对可取消的节点升级;取消不会还原已升级节点。
gcloud container operations cancel "$OPERATION_ID" --project="$PROJECT_ID" --location="$LOCATION"6. 恢复:按当前阶段选择#
| 情况 | 可用动作 |
|---|---|
| node pool 部分升级/取消/失败 | 操作停止后,核实仍可 rollback,再执行下方 node pool 回退 |
| node pool 已全部完成 | 不能套用部分升级 rollback;可选仍可用且满足 GKE 偏差政策的旧版本,按节点升级命令显式降级,会再次重建 |
| 控制面补丁问题 | 同 minor 的旧 patch 仍可用且节点兼容时可申请降级;先协调维护排除期 |
| 两阶段控制面观察期 | 仅 rollbackSafeUpgradeStatus 存在时,按其中 previousVersion 精确回退 |
| 单步 minor / 两阶段已完成 | 不能退回上一 minor;恢复兼容应用/插件,或迁移至已演练的新集群 |
node pool 回退(Standard;确认蓝绿尚未删除旧池或滚动升级仍部分完成):
gcloud container node-pools rollback "$POOL" --cluster="$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"两阶段控制面回退先查询资格,没有字段就停止,不猜版本重试:
gcloud container clusters get-upgrade-info "$CLUSTER" --project="$PROJECT_ID" --location="$LOCATION"
export PREVIOUS_VERSION='替换rollbackSafeUpgradeStatus.previousVersion'
gcloud container clusters upgrade "$CLUSTER" \
--master \
--cluster-version="$PREVIOUS_VERSION" \
--project="$PROJECT_ID" \
--location="$LOCATION"回退版本不恢复业务数据。新集群迁移需恢复对象、权限、网络和数据,验证后切 LB/Cloud DNS;最终同步前隔离写入,回切时处理新增数据,避免双写。
验收完成后更新 Terraform/GitOps 的版本、镜像和策略,保存结果与新备份,恢复暂停的自动化。若本次创建了排除期,按计划移除;不要删除他人已有排除:
gcloud container clusters update "$CLUSTER" \
--project="$PROJECT_ID" \
--location="$LOCATION" \
--remove-maintenance-exclusion=upgrade-runbook覆盖代表性流量与定时任务后再开始下一 minor;核对 release channel、支持期限、自动升级通知,确认无需回退才清理多余资源。
核对日期:2026-09-23。未在真实 GKE 集群执行;实际可用版本、功能和回退资格以集群返回为准,生产前先预演。