MIG:模板、自动修复与滚动发布
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
按 Instance template 维护 VM 数量;需要跨 Zone 时选择 Regional MIG。
推荐做法#
- 模板不可原地修改;发布新模板后执行明确的 rolling update,保留旧模板供回退。
- LB health check 控制转发,autohealing 控制重建,分别规划。
- surge 留足配额与地址;Regional 固定 surge 非零值须满足 Zone 数约束。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
ZONE='REPLACE_ZONE'
MIG='REPLACE_MIG'
# 以下查询 Zonal MIG;Regional MIG 改用 --region。
gcloud compute instance-groups managed list-instances "$MIG" \
--project="$PROJECT_ID" --zone="$ZONE"容易踩的坑#
- MIG 本身没有统一 LB 地址;创建 MIG 不会自动启用指标 autoscaling。
set-instance-template 不代表现有 VM 已更新。 还要执行并验收 rolling update;恢复旧模板不会恢复磁盘数据。
配置说明与完整示例(按需展开)
1. 先理解模板、实例组与负载均衡#
| AWS 经验 | GCP 对应概念 | 作用与边界 |
|---|---|---|
| Launch Template | Instance template | 定义机器规格、镜像、磁盘、网络、运行身份及启动脚本;模板本身不是 VM |
| Auto Scaling Group | Managed Instance Group(MIG) | 按模板维护一组 VM,支持扩缩容、自动修复与滚动更新 |
| ASG scaling policy | MIG 的 Autoscaler | 根据 CPU 等信号调整实例数;只创建 MIG 不会自动开启指标扩缩容 |
| ALB/NLB backend | LB 的实例组后端 | 提供统一流量入口;MIG 本身不提供一个负载均衡地址 |
本篇使用无状态 MIG,重建时不能依赖启动盘保存业务数据。Unmanaged instance group 仅组织已有 VM,不维护模板和期望数量。
Instance template 不可原地修改;新建 lab-mig-v2 后更新 MIG。与 AWS Launch Template 不同,GCP 不在同一模板 ID 下保存数字版本。模板说明
| 部署方式 | 范围 | 选择依据 |
|---|---|---|
| Zonal MIG | 一个 zone | 本篇实验使用,便于控制资源数量;不能抵御整个 zone 故障 |
| Regional MIG | 一个 region 内多个 zone | 用于跨 zone 冗余,还需为故障后的剩余容量留余量 |
模板可为 Global 或 Regional;本例虽为 Global,但绑定 Regional subnet,不能任意跨 Region 使用。Regional 模板用 --instance-template-region 创建并以含 Region 的路径引用。参数
2. 前置与实验边界#
完成 环境篇、网络与 NAT及 VM 与 IAP。保留 lab.env、lab-vpc、lab-subnet、lab-nat 和 lab-iap-ssh;ZONE 必须属于 REGION, subnet 也位于该区域。无公网 IP 的 VM 通过 NAT 安装软件,通过 IAP SSH 检查服务。
操作者需 Compute Instance Admin (v1)、Compute Load Balancer Admin、Compute Security Admin、Service Account Admin 等管理权限;登录需 IAP Tunnel Resource Accessor、Compute OS Admin Login,在本例 SA 上还需 Service Account User。管理权限不授予应用 SA。
常态 2 台 e2-micro,扩容/发布可到 3 台,须留 VM、CPU、磁盘、地址配额。NAT/VM/磁盘持续计费;步骤尚待云端验收。
source lab.env
gcloud config set project "$PROJECT_ID"
gcloud services enable compute.googleapis.com iam.googleapis.com iap.googleapis.com
export MIG_NAME='lab-mig'
export MIG_SA="lab-mig@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts create lab-mig
# 固定本次实验的具体镜像;v1/v2 使用同一镜像,避免同时改变操作系统。
export MIG_IMAGE=$(gcloud compute images describe-from-family debian-12 --project=debian-cloud --format='value(name)')3. 创建 v1 模板和实例组#
在实验工作目录创建启动脚本。这里只返回合成文本;脚本每次运行都写回相同文件,便于实例重建后恢复。
cat > mig-startup-v1.sh <<'EOF'
#!/bin/bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y nginx
printf 'version=v1\n' > /var/www/html/index.html
printf 'ok\n' > /var/www/html/healthz
systemctl enable --now nginx
EOF
gcloud compute instance-templates create lab-mig-v1 \
--machine-type=e2-micro --image="$MIG_IMAGE" --image-project=debian-cloud \
--boot-disk-size=10GB --boot-disk-type=pd-balanced \
--network=lab-vpc --subnet=lab-subnet --region="$REGION" --no-address \
--service-account="$MIG_SA" --scopes=cloud-platform \
--tags=iap-ssh,lab-mig --metadata=enable-oslogin=TRUE \
--metadata-from-file=startup-script=mig-startup-v1.sh
gcloud compute instance-groups managed create "$MIG_NAME" \
--zone="$ZONE" --template=lab-mig-v1 --size=2 --base-instance-name=lab-mig
gcloud compute instance-groups managed wait-until "$MIG_NAME" \
--zone="$ZONE" --stable --timeout=600
gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE"--template 指定创建 VM 的配置,--size=2 指定期望实例数,--base-instance-name 指定实例名称前缀。模板创建命令的 --region 用于解析 subnet 所在区域,创建区域模板要用另一个参数 --instance-template-region。模板里的 cloud-platform scope 不会自动授予业务 IAM 权限。修改本地脚本不会改变已经创建的模板。MIG 创建命令
从组中取一台 VM,通过 IAP 在实例内部请求 nginx:
export MIG_VM=$(gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE" --format='value(instance.basename())' | head -n 1)
test -n "$MIG_VM"
gcloud compute ssh "$MIG_VM" --zone="$ZONE" --tunnel-through-iap \
--command='curl --fail http://127.0.0.1/; curl --fail http://127.0.0.1/healthz'预期 version=v1 和 ok。--stable 仅说明组操作稳定;curl 失败时查 sudo journalctl -u google-startup-scripts.service -n 100、NAT 及 sudo systemctl status nginx,服务就绪再继续。
4. 自动修复:应用不健康后重建 VM#
MIG 会维护 VM 数量,但应用卡死不等于 VM 停止。要检测 HTTP 服务故障,需要额外配置应用健康检查和 autohealing。
gcloud compute firewall-rules create lab-mig-health \
--network=lab-vpc --allow=tcp:80 --target-tags=lab-mig \
--source-ranges=35.191.0.0/16,130.211.0.0/22
gcloud compute health-checks create http lab-mig-health \
--global --port=80 --request-path=/healthz \
--check-interval=10s --timeout=5s --healthy-threshold=2 --unhealthy-threshold=3
gcloud compute instance-groups managed update "$MIG_NAME" \
--zone="$ZONE" --health-check=lab-mig-health --initial-delay=300
gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE" --format=json防火墙只允许健康检查探针网段访问带 lab-mig tag 的 VM 的 80 端口。--initial-delay=300 为启动过程留出最多 300 秒的初始化宽限,避免软件尚未安装好就触发反复重建;应按实际启动时间调整。检查列表中的 instanceHealth,先等所有实例为 HEALTHY 再演练。自动修复说明
仅对本篇创建的实例注入故障:
gcloud compute ssh "$MIG_VM" --zone="$ZONE" --tunnel-through-iap \
--command='sudo systemctl stop nginx'
gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE" --format=json观察 instanceHealth 与 currentAction:不健康后重建 VM,启动脚本恢复 nginx。重建会断开 SSH,须刷新 MIG_VM 再验证响应;实例数量不变不足以证明 autohealing 成功。
LB 健康检查决定是否向后端发流量,autohealing 健康检查决定是否修复实例,二者目的不同。生产宜分别配置,避免短暂依赖故障造成大批 VM 同时重建。
5. 手动扩容与 CPU 自动扩缩容#
先在未配置 autoscaler 时验证期望数量:
gcloud compute instance-groups managed resize "$MIG_NAME" --zone="$ZONE" --size=3
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --stable --timeout=600
gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE"
gcloud compute instance-groups managed resize "$MIG_NAME" --zone="$ZONE" --size=2再启用 CPU 策略,让 autoscaler 在 2–3 台之间调整:
gcloud compute instance-groups managed set-autoscaling "$MIG_NAME" \
--zone="$ZONE" --min-num-replicas=2 --max-num-replicas=3 \
--target-cpu-utilization=0.6 --cool-down-period=120
gcloud compute autoscalers list --filter="target:$MIG_NAME"0.6 是平均 CPU 目标 60%,--cool-down-period 是新 VM 初始化周期;均非即时扩容触发器。用受控负载观察 CPU、期望与实际数量。参数
下面发布实验采用固定 2 台,先删除 autoscaler 并恢复数量,避免自动扩缩容与手动 resize 争用:
gcloud compute instance-groups managed stop-autoscaling "$MIG_NAME" --zone="$ZONE"
gcloud compute instance-groups managed resize "$MIG_NAME" --zone="$ZONE" --size=2
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --stable --timeout=6006. v2 滚动发布与回滚#
创建新脚本和新模板;保留 v1 模板供回滚使用:
sed 's/version=v1/version=v2/' mig-startup-v1.sh > mig-startup-v2.sh
gcloud compute instance-templates create lab-mig-v2 \
--machine-type=e2-micro --image="$MIG_IMAGE" --image-project=debian-cloud \
--boot-disk-size=10GB --boot-disk-type=pd-balanced \
--network=lab-vpc --subnet=lab-subnet --region="$REGION" --no-address \
--service-account="$MIG_SA" --scopes=cloud-platform \
--tags=iap-ssh,lab-mig --metadata=enable-oslogin=TRUE \
--metadata-from-file=startup-script=mig-startup-v2.sh
gcloud compute instance-groups managed rolling-action start-update "$MIG_NAME" \
--zone="$ZONE" --version=template=lab-mig-v2 \
--max-surge=1 --max-unavailable=0
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --version-target-reached --timeout=900
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --stable --timeout=900
gcloud compute instance-groups managed list-instances "$MIG_NAME" --zone="$ZONE" --format=json--max-surge=1 允许临时增 1 台,--max-unavailable=0 维持可用数量;仍需应用就绪、连接排空和容量支持。set-instance-template 只更新组模板,不替代现有实例滚动发布。滚动更新
验收:刷新实例列表,确认每台使用 v2 模板、HEALTHY 且返回 version=v2。wait-until 超时或非零时先查更新状态。
回滚是再次滚动替换成旧模板,不是原地恢复启动盘数据:
gcloud compute instance-groups managed rolling-action start-update "$MIG_NAME" \
--zone="$ZONE" --version=template=lab-mig-v1 \
--max-surge=1 --max-unavailable=0
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --version-target-reached --timeout=900
gcloud compute instance-groups managed wait-until "$MIG_NAME" --zone="$ZONE" --stable --timeout=900重新检查全部实例健康并返回 version=v1。生产应将操作系统和应用固化为可追溯镜像,避免每次启动临时安装到不同版本;数据库变更也必须兼容回滚。
7. Regional MIG 与负载均衡如何衔接#
跨 Zone 另建 Regional MIG,创建时用 --region 与 --zones,后续命令均使用 Region;已有 Zonal MIG 不能直接改成 Regional。模板、subnet 必须匹配 Region。
Regional MIG 固定 max-surge / max-unavailable 的非零值至少等于 Zone 数,三区可评估 3/0,不能照抄本例 1/0;另留故障后容量与配额。区域更新约束
MIG 接入 Application Load Balancer 时,需要按所选 LB 类型创建实例组后端、设置 named port(例如 http:80)、配置后端健康检查及防火墙,再建立 frontend。现有 负载均衡篇使用的是 Cloud Run serverless NEG,不能把 MIG 当成 serverless NEG 直接替换;MIG 后端需采用 VM 实例组路径。
8. 排查与清理#
| 表现 | 优先检查 |
|---|---|
| VM 反复重建 | 启动脚本日志、NAT、健康检查路径/端口、防火墙与初始化宽限 |
| 更新停住 | surge 所需配额与资源容量、新模板启动是否成功、健康检查是否放行 |
| 没有自动扩容 | autoscaler 是否启用、CPU 平均值和持续时间、初始化周期、最大实例数 |
| 手改 VM 后配置消失 | 实例重建会重新使用模板;应修改镜像/脚本并创建新模板 |
若另外接入了 LB,先解除后端对实例组的引用。本实验第 5 节已停止 autoscaling;若你重新启用过,先再次执行 stop-autoscaling。然后按依赖顺序删除:
gcloud compute instance-groups managed delete "$MIG_NAME" --zone="$ZONE"
gcloud compute instance-templates delete lab-mig-v1 lab-mig-v2
gcloud compute health-checks delete lab-mig-health --global
gcloud compute firewall-rules delete lab-mig-health
gcloud iam service-accounts delete "$MIG_SA"
gcloud compute instances list --filter='name~^lab-mig-'
gcloud compute disks list --filter='name~^lab-mig-'组删除会删除其管理的 VM;本例默认启动盘随 VM 删除。仍要核对磁盘清单,独立数据盘或保留策略可能留下资源。只执行到某一步时,只清理已经创建的资源。lab-vpc、NAT 与 IAP 防火墙是共享实验前置,确认其他篇不再使用后,按 网络篇清理,避免遗留 NAT 费用。