Kubernetes и управляемые платформы — Примеры

Пример 1 — Кластер, плоскостью управления которого управляете вы

Команда сама ведёт Kubernetes и владеет инструкцией по обновлению, не имеющей отношения к их приложению: латать сервер API, выводить узлы из эксплуатации, обновлять их по одному и держать интерфейс доступным. Объявите кластер, плоскостью управления которого управляет провайдер, и скажите, какая работа остаётся.

# инструкция для плоскости управления, которой владеем мы
upgrade control-plane
drain <node> --one-at-a-time
upgrade <node>
verify api-server reachable

Решение

resource "google_container_cluster" "api" {
  name     = "<cluster-name>"
  location = "<region>"

  # плоскость управления обновляет, наблюдает и аутентифицирует провайдер
  node_pool {
    name               = "default"
    initial_node_count = 3
  }
}

Остаётся рабочая ёмкость и нагрузки на ней — та часть, что масштабируется по спросу и о которой команда может рассуждать. Инструкция исчезает, и те же манифесты работают локально и против управляемого кластера, потому что API не изменился. Обычная ошибка — продолжать управлять плоскостью управления по привычке: эта работа не даёт ничего, что увидел бы пользователь, а для нагрузки без собственных операторов управляемая среда выполнения на ступень выше убрала бы и узлы.

Пример 2 — Ключ, смонтированный в нагрузку

Нагрузка в кластере обращается к сервису данных с долгоживущим ключом, хранимым как секрет кластера, поэтому любой, кто может читать пространство имён, может прочитать ключ. Дайте нагрузке идентичность платформы вместо этого и назовите, какая часть привязки не переживёт переезда к другому провайдеру.

resource "google_service_account_key" "api" {
  # долгоживущий ключ, смонтированный в нагрузку как секрет кластера
}

Решение

resource "google_service_account" "api" {
  account_id = "<api-identity>"
}

resource "google_service_account_iam_member" "api_workload" {
  role   = "<workload-identity-role>"
  member = "serviceAccount:<api-identity>"
  # кластер отображает эту идентичность на нагрузку: ключ не хранится
}

Нагрузка теперь получает токен во время работы, и в пространстве имён не живёт ничего секретного, поэтому одна и та же модель идентичности покрывает задание запроса, контейнер и функцию. Манифест, который её использует, переезжает к другому провайдеру без изменений, а эта привязка — нет: идентичность, балансировщики и классы хранилища — стыки, которые каждый провайдер реализует по-своему. Обычная ошибка — ожидать переносимости всей платформы, потому что переносимо приложение, и встретить переписывание посреди миграции.