Используя 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
.
Как я могу убедиться, что одна и та же учетная запись службы используется для всех узлов?
После внедрения исправления от @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
Последней частью головоломки было добавление oauth_scopes
к auto_provisioning_defaults
аналогично конфигурации узла, чтобы ServiceAccount
можно было использовать правильно.
@GariSingh Я получаю 401 Unauthorized
Не уверен, что вы намеревались использовать Автоматическая подготовка узла (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
}
абсолютно красивый!
Хотя это решило проблему с учетной записью службы, похоже, я все еще получаю ту же ошибку unexpected status code [manifests latest]: 401 Unauthorized
, несмотря на настройку правильной учетной записи службы.
Хм.... это нехорошо. Я посмотрю, смогу ли я воспроизвести.
Я бы очень хотел наградить эту награду! У вас есть еще идеи по этому вопросу?
Что на самом деле
ImagePullError
вы видите?