You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform配置GCP外部负载均衡器失败:MIG健康检查异常

问题分析与解决方案

模块属性含义明确

针对你提出的5个问题,直接明确答案:

  1. MIG模块的named_ports:是给实例组内的服务端口设置别名,负载均衡会通过这个别名定位到VM上的服务端口,必须指向你的服务运行端口8080。
  2. MIG模块的health_check:是针对MIG内VM的健康检查,用于判断VM上的服务是否正常,其port属性必须设置为服务运行端口8080。
  3. LB模块的backends:确实指向MIG实例组,其中default的port需要和服务端口一致(8080),或者通过port_name关联MIG的named_ports别名来映射到8080。
  4. LB模块的health_check:可以和MIG的健康检查配置一致,指定的端口必须为8080,因为要直接检查VM上的服务状态。
  5. 允许健康检查的防火墙规则:需要应用到MIG的VM上,允许GCP健康检查的官方IP段访问VM的服务端口(8080),LB模块会自动创建该规则,但需确保target_tags与VM的标签匹配。

现有代码核心问题

你的代码中所有端口配置都设为了80,但VM上的服务实际运行在8080端口,导致健康检查无法触达服务,LB流量也无法转发到正确端口;同时防火墙规则未开放8080端口,进一步阻断了流量。

修正后的main.tf代码

data "external" "my_ip_addr" {
  program = ["/bin/bash", "${path.module}/getip.sh"]
}

resource "google_project_service" "project" {
  // 保留原有配置
}

resource "google_service_account" "service-acc" {
  // 保留原有配置
}

resource "google_compute_network" "vpc-network" {
  project = var.pro
  name = var.network_name
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "subnetwork" {
  name = "subnetwork"
  ip_cidr_range = "10.0.101.0/24"
  region = var.region
  project = var.pro
  stack_type = "IPV4_ONLY"
  network = google_compute_network.vpc-network.self_link
}

// 修正:允许内部流量访问8080端口(健康检查和LB转发用)
resource "google_compute_firewall" "allow-internal" {
  name    = "allow-internal"
  project = var.pro
  network = google_compute_network.vpc-network.self_link
  allow {
    protocol = "tcp"
    ports = ["8080"]
  }
  source_ranges = ["10.0.101.0/24"]
}

resource "google_compute_firewall" "allow-ssh" {
  project = var.pro
  name          = "allow-ssh"
  direction     = "INGRESS"
  network       = google_compute_network.vpc-network.self_link
  allow {
    protocol = "tcp"
    ports = ["22"]
  }
  target_tags   = ["allow-ssh"] 
  source_ranges = [format("%s/%s", data.external.my_ip_addr.result["internet_ip"], 32)]
}

// 新增:允许GCP健康检查流量访问8080端口
resource "google_compute_firewall" "allow-health-check" {
  name    = "allow-health-check"
  project = var.pro
  network = google_compute_network.vpc-network.self_link
  allow {
    protocol = "tcp"
    ports = ["8080"]
  }
  source_ranges = ["130.211.0.0/22", "35.191.0.0/16"] // GCP健康检查官方IP段
  target_tags   = ["template-vm"]
}

resource "google_compute_address" "static" {
  project = var.pro
  region = var.region
  name = "ipv4-address"
}

resource "google_compute_instance" "ssh-vm" {
  name = "ssh-vm"
  machine_type = "e2-standard-2"
  project = var.pro
  tags = ["allow-ssh"]
  zone = "europe-west1-b"

  boot_disk {
    initialize_params {
      image = "ubuntu-2004-focal-v20221213"
    }
  }

  network_interface {
    subnetwork = google_compute_subnetwork.subnetwork.self_link
    access_config {
      nat_ip = google_compute_address.static.address
    }
  }

  metadata = {
    startup-script = <<-EOF
        #!/bin/bash
        sudo snap install docker
        sudo docker version > file1.txt
        sleep 5
        sudo docker run -d --rm -p ${var.server_port}:${var.server_port} \
        busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; \
        echo 'yo'; } | nc -l -p ${var.server_port}; done"
        EOF
  }
}

module "instance_template" {
  source = "terraform-google-modules/vm/google//modules/instance_template"
  version = "7.9.0"
  region = var.region
  project_id = var.pro
  network = google_compute_network.vpc-network.self_link
  subnetwork = google_compute_subnetwork.subnetwork.self_link
  service_account = {
    email = google_service_account.service-acc.email
    scopes = ["cloud-platform"]
  }

  name_prefix = "webserver"
  tags = ["template-vm", "allow-ssh"]
  machine_type = "e2-standard-2"
  startup_script = <<-EOF
  #!/bin/bash
  sudo snap install docker
  sudo docker version > docker_version.txt
  sleep 5
  sudo docker run -d --rm -p ${var.server_port}:${var.server_port} \
  busybox sh -c "while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; \
  echo 'yo'; } | nc -l -p ${var.server_port}; done"
  EOF
  source_image = "https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20221213"
  disk_size_gb = 10
  disk_type = "pd-balanced"
  preemptible = true
}

module "vm_mig" {
  source  = "terraform-google-modules/vm/google//modules/mig"
  version = "7.9.0"
  project_id = var.pro
  region = var.region
  target_size = 3
  instance_template = module.instance_template.self_link
  // 修正:named_ports指向服务运行的8080端口
  named_ports = [{
    name = "http"
    port = 8080
  }]
  // 修正:健康检查端口设为8080
  health_check = {
    type = "http"
    initial_delay_sec = 30
    check_interval_sec = 30
    healthy_threshold = 1
    timeout_sec = 10
    unhealthy_threshold = 5
    response = ""
    proxy_header = "NONE"
    port = 8080
    request = ""
    request_path = "/"
    host = ""
  }
  network = google_compute_network.vpc-network.self_link
  subnetwork = google_compute_subnetwork.subnetwork.self_link
}

module "gce-lb-http" {
  source            = "GoogleCloudPlatform/lb-http/google"
  version           = "~> 4.4"
  project           = var.pro
  name              = "group-http-lb"
  target_tags       = ["template-vm"]
  firewall_networks = [google_compute_network.vpc-network.name]
  // 新增:限制LB的80端口仅允许你的IP访问
  source_ranges = [format("%s/%s", data.external.my_ip_addr.result["internet_ip"], 32)]
  backends = {
    default = {
      description                     = null
      // 修正:port设为8080,与服务端口一致
      port                            = 8080
      protocol                        = "HTTP"
      port_name                       = "http"
      timeout_sec                     = 10
      enable_cdn                      = false
      custom_request_headers          = null
      custom_response_headers         = null
      security_policy                 = null
      connection_draining_timeout_sec = null
      session_affinity                = null
      affinity_cookie_ttl_sec         = null

      // 修正:健康检查端口设为8080
      health_check = {
        check_interval_sec  = null
        timeout_sec         = null
        healthy_threshold   = null
        unhealthy_threshold = null
        request_path        = "/"
        port                = 8080
        host                = null
        logging             = null
      }

      log_config = {
        enable = true
        sample_rate = 1.0
      }

      groups = [
        {
          group                        = module.vm_mig.instance_group
          balancing_mode               = null
          capacity_scaler              = null
          description                  = null
          max_connections              = null
          max_connections_per_instance = null
          max_connections_per_endpoint = null
          max_rate                     = null
          max_rate_per_instance        = null
          max_rate_per_endpoint        = null
          max_utilization              = null
        },
      ]

      iap_config = {
        enable               = false
        oauth2_client_id     = null
        oauth2_client_secret = null
      }
    }
  }
}

关键修正点说明

  1. 端口统一对齐:所有涉及服务的配置(named_ports、MIG健康检查、LB后端、LB健康检查)均从80改为8080,与VM上的服务端口保持一致。
  2. 防火墙规则调整:
    • 修正allow-internal规则,开放8080端口,确保LB转发的流量能到达VM。
    • 新增allow-health-check规则,允许GCP健康检查的官方IP段访问VM的8080端口。
  3. LB访问限制:在LB模块中添加source_ranges,仅允许你的IP访问LB的80端口,满足需求。

内容的提问来源于stack exchange,提问作者SkogensKonung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:00:59