google MIG 中的云平台实例无法访问工件注册表

google cloud platform instance in MIG cannot access artifact registry

我正在尝试部署一个带有负载均衡器的托管实例组,它将是 运行 一个网络服务器容器。 容器存储在 google artifcat 注册表中。

如果我手动创建一个 VM 并定义容器使用,它可以成功拉取和激活容器。

当我尝试通过 Terraform 创建托管实例组时,VM 既不拉取也不激活容器。 当我通过 ssh 连接到 VM 并尝试手动拉取容器时,出现以下错误:

Error response from daemon: Get https://us-docker.pkg.dev/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

我手动创建的 VM 与 terraform 创建的 VM 之间唯一显着的区别是手动 VM 具有外部 IP 地址。不确定这是否重要,也不确定如何将其添加到 terraform 文件中。

下面是我的 main.tf 文件。谁能告诉我我做错了什么?

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
       version = "3.53.0"
    }
     google-beta = {
        source  = "hashicorp/google-beta"
        version = "~> 4.0"
    }
  }
}

provider "google" {
  credentials = file("compute_lab2-347808-dab33a244827.json")

  project = "lab2-347808"
  region  = "us-central1"
  zone    = "us-central1-f"
}

locals {
  google_load_balancer_ip_ranges = [
    "130.211.0.0/22",
    "35.191.0.0/16",
  ]
}

module "gce-container" {
  source = "terraform-google-modules/container-vm/google"
  version = "~> 2.0"

  cos_image_name = "cos-stable-77-12371-89-0"

  container = {
    image = "us-docker.pkg.dev/lab2-347808/web-server-repo/web-server-image"

    volumeMounts = [
      {
        mountPath = "/cache"
        name      = "tempfs-0"
        readOnly  = false
      },
    ]
  }
volumes = [
    {
      name = "tempfs-0"

      emptyDir = {
        medium = "Memory"
      }
    },
  ]

  restart_policy = "Always"
}

resource "google_compute_firewall" "rules" {
  project     = "lab2-347808"
  name        = "allow-web-ports"
  network     = "default"
  description = "Opens the relevant ports for the web server"

  allow {
    protocol  = "tcp"
    ports     = ["80", "8080", "5432", "5000", "443"]
  }

  source_ranges = ["0.0.0.0/0"]
  #source_ranges = local.google_load_balancer_ip_ranges
  target_tags = ["web-server-ports"]
}

resource "google_compute_autoscaler" "default" {
  name   = "web-autoscaler"
  zone   = "us-central1-f"
  target = google_compute_instance_group_manager.default.id

  autoscaling_policy {
    max_replicas    = 10
    min_replicas    = 1
    cooldown_period = 60

    cpu_utilization {
      target = 0.5
    }
  }
}
resource "google_compute_instance_template" "default" {
  name           = "my-web-server-template"
  machine_type   = "e2-medium"
  can_ip_forward = false

  tags         = ["ssh", "http-server", "https-server", "web-server-ports"]


  disk {
   #source_image =  "cos-cloud/cos-73-11647-217-0"
    source_image = module.gce-container.source_image
  }

  network_interface {
   network = "default"
  }


  service_account {
    #scopes = ["userinfo-email", "compute-ro", "storage-ro"]
    scopes = ["cloud-platform"]
  }
  metadata = {
    gce-container-declaration = module.gce-container.metadata_value
  }
}

resource "google_compute_target_pool" "default" {
  name = "web-server-target-pool"
}

resource "google_compute_instance_group_manager" "default" {
  name = "web-server-igm"
  zone = "us-central1-f"

  version {
    instance_template  = google_compute_instance_template.default.id
    name               = "primary"
  }

  target_pools       = [google_compute_target_pool.default.id]
  base_instance_name = "web-server-instance"
}

您的 VM 模板没有 public IP,因此您无法访问 public IP。

但是,您有 3 种方法可以解决该问题:

  • 在 VM 模板上添加 public IP(坏主意)
  • 在您的 VM 私有 IP 范围上添加 Cloud NAT 以允许传出流量到 Internet(好主意)
  • 在托管 VM 私有 IP 范围的子网中激活 Google 私有访问。它创建了一个无需 public IP 即可访问 Google 服务的桥梁(我的首选想法)-> https://cloud.google.com/vpc/docs/configure-private-google-access

显然我在 google_compute_instance_template 的 network_interface 中遗漏了以下 acecss_config,如下所示:

network_interface {
   network = "default"
   access_config {
     network_tier = "PREMIUM"
   }