Пулы узлов Terraform GKE расширяются с уменьшенными областями доступа для аутентификации

Используя Terraform, я запускаю следующие ресурсы для своего основного сервера, используя уникальную учетную запись службы для этого кластера:

resource "google_container_cluster" "primary" {
  name     = var.gke_cluster_name
  location = var.region
  
  # We can't create a cluster with no node pool defined, but we want to only use
  # separately managed node pools. So we create the smallest possible default
  # node pool and immediately delete it.
  remove_default_node_pool = true
  initial_node_count       = 1

  ip_allocation_policy {}
  networking_mode = "VPC_NATIVE"

  node_config {
    service_account = google_service_account.cluster_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
  }

  cluster_autoscaling {
    enabled = true
    
    resource_limits {
      resource_type = "cpu"
      maximum = 40
      minimum = 3
    }

    resource_limits {
      resource_type = "memory"
      maximum = 100
      minimum = 12
    }
  }

  network    = google_compute_network.vpc.name
  subnetwork = google_compute_subnetwork.subnet.name
}

resource "google_container_node_pool" "primary_nodes" {
  name       = "${google_container_cluster.primary.name}-node-pool"
  location   = var.region
  cluster    = google_container_cluster.primary.name
  node_count = var.gke_num_nodes

  node_config {

    service_account = google_service_account.cluster_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]

    labels = {
      env = var.project_id
    }
    disk_size_gb = 150
    preemptible  = true
    machine_type = var.machine_type
    tags         = ["gke-node", "${var.project_id}-gke"]
    metadata = {
      disable-legacy-endpoints = "true"
    }
  }
}

Несмотря на то, что я предоставляю узлам соответствующие разрешения для извлечения данных из реестра контейнеров Google (roles/containerregistry.ServiceAgent), иногда я случайно получаю ImagePullError от kubernetes:

Unexpected status code [manifests latest]: 401 Unauthorized

После использования следующей команды для проверки учетных записей служб, назначенных пулам узлов:

gcloud container clusters describe master-env --zone = "europe-west2" | grep "serviceAccount"

Я вижу следующий вывод:

serviceAccount: default
serviceAccount: master-env@<project-id>.iam.gserviceaccount.com
serviceAccount: master-env@<project-id>.iam.gserviceaccount.com

Указание на то, что, хотя я указал правильную учетную запись службы для назначения узлам, по какой-то причине (я думаю, для пула primary) вместо этого назначается учетная запись службы default, которая использует неправильные области oauth:

oauthScopes:
    - https://www.googleapis.com/auth/logging.write
    - https://www.googleapis.com/auth/monitoring

Вместо https://www.googleapis.com/auth/cloud-platform.

Как я могу убедиться, что одна и та же учетная запись службы используется для всех узлов?

Редактировать 1:

После внедрения исправления от @GariSingh теперь все мои пулы узлов используют одно и то же Service Account, как и ожидалось, однако я все еще иногда получаю ошибку unexpected status code [manifests latest]: 401 Unauthorized при установке своих сервисов в кластер.

Это необычно, так как другие службы, установленные в кластере, без проблем извлекают свои изображения из gcr.

Описание событий модуля показывает следующее:

Events:
  Type     Reason       Age                  From               Message
  ----     ------       ----                 ----               -------
  Normal   Scheduled    11m                  default-scheduler  Successfully assigned default/<my-deployment> to gke-master-env-nap-e2-standard-2-<id>
  Warning  FailedMount  11m                  kubelet            MountVolume.SetUp failed for volume "private-key" : failed to sync secret cache: timed out waiting for the condition
  Warning  FailedMount  11m                  kubelet            MountVolume.SetUp failed for volume "kube-api-access-5hh9r" : failed to sync configmap cache: timed out waiting for the condition
  Warning  Failed       9m34s (x5 over 10m)  kubelet            Error: ImagePullBackOff

Редактировать 2:

Последней частью головоломки было добавление oauth_scopes к auto_provisioning_defaults аналогично конфигурации узла, чтобы ServiceAccount можно было использовать правильно.

Что на самом деле ImagePullError вы видите?

Gari Singh 23.03.2022 10:39

@GariSingh Я получаю 401 Unauthorized

CertainlyNotAdrian 23.03.2022 14:39
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
2
2
91
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не уверен, что вы намеревались использовать Автоматическая подготовка узла (NAP) (который я настоятельно рекомендую вам использовать, если он не соответствует вашим потребностям), но аргумент cluster_autoscaling для google_container_cluster фактически позволяет это сделать. Он не включает автомасштабирование кластера для отдельных пулов узлов.

Если ваша цель — включить автомасштабирование кластера для пула узлов, который вы создали в своей конфигурации, и не использовать NAP, вам нужно удалить блок cluster_autoscaling и добавить блок автомасштабирования под ваш ресурс google_container_node_pool и изменить node_count на initial_node_count:

resource "google_container_node_pool" "primary_nodes" {
  name       = "${google_container_cluster.primary.name}-node-pool"
  location   = var.region
  cluster    = google_container_cluster.primary.name
  initial_node_count = var.gke_num_nodes

  node_config {
    autoscaling {
      min_node_count = var.min_nodes
      max_node_count = var.max_nodes
    }
    service_account = google_service_account.cluster_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]

    labels = {
      env = var.project_id
    }
    disk_size_gb = 150
    preemptible  = true
    machine_type = var.machine_type
    tags         = ["gke-node", "${var.project_id}-gke"]
    metadata = {
      disable-legacy-endpoints = "true"
    }
  }
}

(вышеприведенное предполагает, что вы устанавливаете переменные для минимального и максимального узлов)

Если вы хотите использовать NAP, вам нужно добавить блок auto_provisioning_defaults и настроить свойство service_account:

resource "google_container_cluster" "primary" {
  name     = var.gke_cluster_name
  location = var.region
  
  # We can't create a cluster with no node pool defined, but we want to only use
  # separately managed node pools. So we create the smallest possible default
  # node pool and immediately delete it.
  remove_default_node_pool = true
  initial_node_count       = 1

  ip_allocation_policy {}
  networking_mode = "VPC_NATIVE"

  node_config {
    service_account = google_service_account.cluster_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
  }

  cluster_autoscaling {
    enabled = true
    
    auto_provisioning_defaults {
      service_account = google_service_account.cluster_sa.email
    }      

    resource_limits {
      resource_type = "cpu"
      maximum = 40
      minimum = 3
    }

    resource_limits {
      resource_type = "memory"
      maximum = 100
      minimum = 12
    }
  }

  network    = google_compute_network.vpc.name
  subnetwork = google_compute_subnetwork.subnet.name
}

абсолютно красивый!

CertainlyNotAdrian 25.03.2022 22:31

Хотя это решило проблему с учетной записью службы, похоже, я все еще получаю ту же ошибку unexpected status code [manifests latest]: 401 Unauthorized, несмотря на настройку правильной учетной записи службы.

CertainlyNotAdrian 25.03.2022 23:53

Хм.... это нехорошо. Я посмотрю, смогу ли я воспроизвести.

Gari Singh 27.03.2022 11:06

Я бы очень хотел наградить эту награду! У вас есть еще идеи по этому вопросу?

CertainlyNotAdrian 29.03.2022 18:38

Другие вопросы по теме