如何为GKE集群创建使用其他子网的新节点池?
解决GKE节点池指定自定义子网(Terraform实现)
问题背景
现有生产环境GKE集群使用10.100.100.0/24的US子网,因子网IP耗尽,创建新节点池时触发如下错误:
us-central1-a: Requested resource is exhausted: Not all instances running in IGM after 58.156203563s. Expected 2, running 0, transitioning 2. Current errors: [IP_SPACE_EXHAUSTED]: Instance 'gke-us-xxx-38de9507-wxwr' creation failed: IP space of 'projects/xxx-yyy/regions/us-central1/subnetworks/us' is exhausted. .; us-central1-b: Requested resource is exhausted: Not all instances running in IGM after 44.519059343s. Expected 2, running 0, transitioning 2. Current errors: [IP_SPACE_EXHAUSTED]: Instance 'gke-us-xxx-4f57c3c6-6zq4' creation failed: IP space of 'projects/xxx-yyy/regions/us-central1/subnetworks/us' is exhausted.
需创建10.100.101.0/24的US2子网并分配给新节点池,但之前尝试additional_node_network_configs仅添加附加子网,无法替换主子网。
解决方案
GKE节点池的主子网配置需通过google_container_node_pool资源的network_config块指定,而非node_config或additional_node_network_configs。该配置会覆盖集群级的子网设置,为节点池分配独立子网。
步骤1:准备新子网
确保US2子网(10.100.101.0/24)已创建,满足以下条件:
- 与现有集群同属一个VPC
- 子网区域与目标节点池的区域一致(如
us-central1) - 已启用私有IP(匹配集群
enable_private_nodes=true的配置)
步骤2:修改Terraform节点池配置
在google_container_node_pool资源中添加network_config块,指定新子网的资源ID。
基础修改(指定固定新子网)
如果仅需给某个特定节点池分配新子网,直接硬编码子网ID:
resource "google_container_node_pool" "nodes" { for_each = var.node_pools cluster = google_container_cluster.cluster.id name = each.key node_count = each.value.node_count max_pods_per_node = each.value.max_pods_per_node # 添加network_config块,指定新子网 network_config { subnetwork = "projects/xxx-yyy/regions/us-central1/subnetworks/us2" # 替换为你的新子网ID } management { auto_repair = true auto_upgrade = false } # 其余node_config等配置保持不变... }
灵活配置(支持多节点池自定义子网)
若需让不同节点池可配置不同子网,可先扩展var.node_pools的结构,给每个节点池添加subnetwork字段:
# 示例变量定义,添加subnetwork可选字段 variable "node_pools" { type = map(object({ node_count = number max_pods_per_node = number machine_type = string disk_size_gb = number labels = map(string) spot = bool taint = list(object({ key = string value = string effect = string })) subnetwork = optional(string) # 添加可选子网字段 })) }
然后在节点池资源中动态引用该字段,默认使用集群子网,指定时用自定义子网:
resource "google_container_node_pool" "nodes" { for_each = var.node_pools cluster = google_container_cluster.cluster.id name = each.key node_count = each.value.node_count max_pods_per_node = each.value.max_pods_per_node # 动态指定子网,未指定时使用集群默认子网 network_config { subnetwork = each.value.subnetwork != null ? each.value.subnetwork : var.subnetwork_id } management { auto_repair = true auto_upgrade = false } # 其余node_config等配置保持不变... }
验证变更
执行terraform plan确认变更仅针对目标新节点池,不会影响现有节点池。确认无误后执行terraform apply,新节点池的节点将自动从US2子网分配IP,不再占用原耗尽的子网资源。
注意事项
- 新子网必须与集群在同一VPC下,否则节点无法加入集群
- 节点池的区域必须与子网区域完全匹配
- 无需修改集群级的
subnetwork配置,节点池级配置会自动覆盖 - 生产环境操作前务必通过
plan确认变更范围,避免意外影响现有业务
内容的提问来源于stack exchange,提问作者a1dude
相关产品推荐
相关产品推荐

