3. GKE集群架构与创建

在 GKE 上落地生产集群,第一步不是敲命令,而是把三个决策想清楚:用标准模式还是 Autopilot 模式、集群网络怎么划分、节点池怎么设计。这三件事决定了后续的成本结构、运维负担和扩展上限,一旦集群建好再改,代价往往很高。

标准模式与 Autopilot:控制权与运维负担的取舍

GKE 的两种运行模式本质上是“谁负责节点”的分工差异。标准模式(Standard)把节点层的控制权交给用户:你可以选择机器类型、配置节点池、设置自动扩缩、安装 DaemonSet、使用特权容器、SSH 登录节点排查问题。代价是你要为节点容量、升级窗口、镜像维护负责。Autopilot 模式则把节点管理完全托管给 Google:你只提交 Pod 的资源请求(requests),GKE 根据请求自动创建和回收节点,节点自动升级、自动修复,且默认启用一系列安全基线(如禁止特权容器、限制 hostPath、强制资源请求)。

选择依据可以归纳为几条判断线:如果工作负载需要 GPU、需要自定义内核参数、需要运行特权或 hostNetwork 组件(如某些 CNI 插件、监控 Agent 的特定采集方式),标准模式更合适;如果团队规模小、希望把运维精力集中在应用本身、且工作负载是常规无状态服务,Autopilot 能显著降低节点运维成本。需要注意的是,Autopilot 按 Pod 资源请求计费,若 requests 设置虚高,成本会明显上升,因此它对资源画像的准确性要求更高。

GKE 标准模式 vs Autopilot 模式:责任边界与能力差异 标准模式 Standard 用户负责 节点池机器类型 / 数量 / 自动扩缩配置 节点镜像、kubelet 参数、升级窗口 DaemonSet / 特权容器 / hostPath / SSH Google 负责 控制平面(API Server / 调度器 / etcd) 控制平面高可用与版本升级 适用:GPU / 自定义内核 / 特权组件 成本按节点计费,需自行控制节点利用率 Autopilot 模式 用户负责 提交 Pod 及资源 requests / limits 声明 HPA / PDB / 拓扑分布约束 Google 负责 节点创建 / 回收 / 自动修复 / 自动升级 安全基线:禁特权、限 hostPath、强制 requests 节点池抽象化,用户不直接管理节点 适用:常规无状态服务 / 小团队 按 Pod requests 计费,requests 需贴近真实用量

集群网络规划:VPC 原生与地址段划分

GKE 推荐使用 VPC 原生(VPC-native)集群,Pod 和 Service 直接从 VPC 子网分配 IP,而不是像路由型集群那样依赖静态路由。VPC 原生集群需要为节点、Pod、Service 分别规划三个不重叠的 CIDR 段。节点段决定集群最多能有多少节点,Pod 段决定最多能有多少 Pod,Service 段决定最多能有多少 Service。

以生产环境常见的规划为例:节点子网使用 10.10.0.0/20(约 4094 个可用地址),Pod 段使用 10.20.0.0/14(约 26 万个地址),Service 段使用 10.30.0.0/20(约 4094 个地址)。Pod 段之所以给得大,是因为每个节点会从 Pod 段中切出一个 /24 的二级子网(默认 110 个 Pod),节点数越多,消耗的 Pod 段越大。如果 Pod 段规划过小,集群扩容时会因 IP 耗尽而无法新增节点。

此外要提前考虑与本地数据中心、其他 VPC 的互联:如果使用 Cloud VPN 或 Interconnect,Pod 段和 Service 段不能与对端网络重叠,否则需要做 NAT 或重新规划。Service 段虽然不直接路由到 VPC 之外,但在使用 VPC 对等或共享 VPC 时仍需避免冲突。

节点池设计:按工作负载特征分组

节点池是标准模式下最核心的容量单元。生产集群通常不会只用一个节点池,而是按工作负载特征拆分:通用服务池使用 e2-standard-4,开启自动扩缩(min 2 / max 10);内存密集型池使用 n2-highmem-8;需要 GPU 的池使用 n1-standard-8 加 nvidia-tesla-t4,并设置 --node-taints 防止普通 Pod 调度上去。每个节点池可以独立设置升级策略,例如通用池用 surge 升级(先建新节点再删旧节点),GPU 池用蓝绿升级以控制风险。

节点池设计还要考虑拓扑分布:如果应用要求跨可用区高可用,节点池应分布在 3 个可用区,并配合 Pod 的 topologySpreadConstraints 让副本均匀分布。自动扩缩方面,集群级 autoscaler 根据 Pod 的 pending 状态触发扩容,缩容则依据节点利用率,默认阈值约为 50%,可通过 --scale-down-utilization-threshold 调整。

用 gcloud 创建生产级集群

下面是一条创建 VPC 原生标准集群的 gcloud 命令示例,包含网络规划、节点池和自动扩缩配置:

gcloud container clusters create prod-cluster \
  --region=asia-east1 \
  --num-nodes=2 \
  --machine-type=e2-standard-4 \
  --enable-autoscaling --min-nodes=2 --max-nodes=10 \
  --enable-autorepair --enable-autoupgrade \
  --network=prod-vpc --subnetwork=prod-subnet \
  --cluster-secondary-range-name=pods \
  --services-secondary-range-name=services \
  --enable-ip-alias \
  --release-channel=stable \
  --enable-shielded-nodes \
  --workload-pool=my-project.svc.id.goog

其中 --enable-ip-alias 表示启用 VPC 原生,--cluster-secondary-range-name 和 --services-secondary-range-name 引用子网中预先创建的二级 CIDR 范围。--release-channel=stable 让控制平面跟随稳定发布通道,--workload-pool 启用 Workload Identity,使 Pod 能以 KSA 身份访问 GCP 服务,避免挂载长期密钥。

用 Terraform 管理集群生命周期

生产环境更推荐用 Terraform 声明式管理,便于版本控制和变更审查。以下片段展示集群与独立节点池的定义:

resource "google_container_cluster" "primary" {
  name     = "prod-cluster"
  location = "asia-east1"
  release_channel { channel = "STABLE" }

  ip_allocation_policy {
    cluster_secondary_range_name  = "pods"
    services_secondary_range_name = "services"
  }

  workload_identity_config {
    workload_pool = "my-project.svc.id.goog"
  }

  remove_default_node_pool = true
  initial_node_count       = 1
}

resource "google_container_node_pool" "general" {
  name       = "general-pool"
  cluster    = google_container_cluster.primary.name
  location   = "asia-east1"
  node_count = 2

  autoscaling {
    min_node_count = 2
    max_node_count = 10
  }

  node_config {
    machine_type = "e2-standard-4"
    oauth_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
  }

  management {
    auto_repair  = true
    auto_upgrade = true
  }
}

注意 remove_default_node_pool = true 配合 initial_node_count = 1 是常见写法:先建一个最小默认池满足集群创建要求,随后删除它,改用显式定义的节点池,避免默认池规格不合适却难以移除。创建完成后,用 gcloud container clusters get-credentials prod-cluster --region=asia-east1 获取 kubeconfig,再用 kubectl get nodes -o wide 确认节点就绪、kubectl get pods -A 确认系统组件运行正常。若节点长时间处于 NotReady,优先检查节点子网的二级 CIDR 是否配置正确、防火墙规则是否放通 kubelet 与 API Server 通信。

规划阶段建议把 Pod 段留足余量:按“最大节点数 × 每节点 /24”估算,再乘以 2 倍冗余。例如最多 50 个节点,Pod 段至少需要 50 个 /24,即约 /18 以上,实际规划中常直接给 /14 以应对未来增长。