Terraform实战:如何自动化部署AKS与GKE的联合集群
DevOps工程师的云原生自动化挑战
跨云Terraform模块设计精髓
1. Provider的芭蕾舞步
2. 集群配置的"不对称之美"
网络互联的黑暗艺术
3. 打通VNet与VPC的四种姿势
部署验证的自动化陷阱
4. 用Terratest构建验证围墙
进阶玩家的双云秘籍
终极生存指南
DevOps工程师的云原生自动化挑战
当你的微服务需要同时跑在Azure和GCP上时,凌晨三点的跨云故障排查会让你深刻理解什么叫"云的代价"。上周我们团队就遇到这种噩梦场景——某个关键组件在AKS运行正常,但在GKE却频繁OOM。用Terraform实现基础设施双活部署,不只是为了简历上多一行炫技,而是真正能让你多睡两小时的生存技能。
跨云Terraform模块设计精髓
1. Provider的芭蕾舞步
# 这就像同时操作两台不同操作系统的笔记本
tprovider "azurerm" {
features {}
subscription_id = var.azure_sub_id
client_id = var.azure_client_id
client_secret = var.azure_client_secret
tenant_id = var.azure_tenant_id
}
tprovider "google" {
project = var.gcp_project_id
region = "us-central1"
credentials = file(var.gcp_cred_path)
}
常见坑点:AZ和Zone的命名差异会让模块复用变成灾难。GCP的"us-central1-a"对应Azure的"eastus",我曾在变量转换上浪费整整一天。最佳实践是抽象location映射表:
locals {
region_map = {
"eastus" = "us-central1"
"westus" = "us-west1"
}
aks_location = "eastus"
gke_location = local.region_map[local.aks_location]
}
2. 集群配置的"不对称之美"
Azure的节点池叫"node pool",GCP叫"node_pool"(注意下划线)。这些细微差别会导致:
# AKS配置
resource "azurerm_kubernetes_cluster_node_pool" "aks" {
kubernetes_cluster_id = azurerm_kubernetes_cluster.main.id
vm_size = "Standard_D2_v2"
}
# GKE配置
resource "google_container_node_pool" "gke" {
cluster = google_container_cluster.main.name
node_config {
machine_type = "e2-medium"
}
}
血泪经验:永远不要在两地使用相同的节点规格。Azure的Standard_D2_v2(2核7G内存)性能表现与GCP的e2-medium(2核8G内存)完全不同,我们的Java服务在GCP就因为这小1G内存频繁崩溃。
网络互联的黑暗艺术
3. 打通VNet与VPC的四种姿势
- VIP方案:用负载均衡器暴露服务,简单但延迟高
- VPN网关:适合初期验证,但带宽受限
- 专用互联(Azure ExpressRoute + GCP Partner Interconnect)
- 服务网格(Istio多集群方案)
# Azure VPN网关配置示例
resource "azurerm_virtual_network_gateway" "vpn" {
sku = "VpnGw1"
ip_configuration {
public_ip_address_id = azurerm_public_ip.vpn.id
}
}
# GCP对应配置
resource "google_compute_vpn_tunnel" "to_azure" {
peer_ip = azurerm_public_ip.vpn.ip_address
shared_secret = "supersecret"
}
真实案例:某电商大促期间,VPN带宽打满导致跨云订单同步延迟。后来我们改用GCP的Cloud Interconnect,月费$200但带宽提升10倍。
部署验证的自动化陷阱
4. 用Terratest构建验证围墙
func TestAKSandGKEConnectivity(t *testing.T) { terraformOptions := &terraform.Options{ TerraformDir: ".", } defer terraform.Destroy(t, terraformOptions) terraform.InitAndApply(t, terraformOptions) // 验证AKS pod能否访问GKE服务 kubeConfig := terraform.Output(t, terraformOptions, "aks_kubeconfig") podCmd := "curl -s http://${GKE_SERVICE_IP}:8080/health" _, err := RunKubectlWithConfigE(t, kubeConfig, "default", "exec", "test-pod", "--", "/bin/sh", "-c", podCmd) require.NoError(t, err) }
特别注意:Azure默认出站IP会被GCP防火墙拦截。我们曾在测试环境浪费三天,最后发现需要显式配置GCP防火墙规则:
resource "google_compute_firewall" "allow_azure" {
network = google_compute_network.main.name
source_ranges = ["${azurerm_public_ip.aks.outbound_ip}"]
}
进阶玩家的双云秘籍
成本杀手:用Terraform的
lifecycle
块实现GKE Spot节点与Azure Spot实例联动lifecycle { ignore_changes = [ node_count # 让Cluster Autoscaler接管 ] }
密钥管理:Vault的Azure Key Vault与GCP KMS联合引擎配置
监控统一:通过Terraform部署OpenTelemetry Collector,将指标同时发往Azure Monitor和GCP Cloud Monitoring
终极生存指南
当我第一次成功从AKS Pod直接ping通GKE Service时,那种快感堪比第一次写出能运行的Hello World。但有三个忠告:
- 永远在两个云上都保留独立的后备部署方案
- 跨云DNS解析延迟可能比你想象的更严重(我们遇到过的200ms延迟)
- 准备双倍预算——不是给云服务商,是给团队买咖啡缓解调试压力