--- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: processing resources: - ../base patches: # --- Состав: только api и engine-low --------------------------------------- # engine удалён: в base у него replicaCount 0, то есть он и там выключен, а # образ прибит к тегу с опечаткой в имени (workflows-endigne_prod). Рабочий # обработчик — engine-low, он же на более свежем образе contour_*. - target: {kind: HelmRelease, name: engine} patch: | $patch: delete apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: engine namespace: processing # frontend идёт из base без патчей. Адреса бэкендов вшиты в бандл на этапе # сборки (константа __BUILD_ENV__), но сборка ugok2 обращается к тому же # origin относительными путями — иначе в остальных кластерах не понадобился # бы отдельный маршрут /workflows/api/ перед /workflows/. Поэтому фронтенд # публикуется на домене платформы, а не на своём поддомене: маршруты в # infrastructure/istio-config/aero, VirtualService platform. # --- workflows-api ---------------------------------------------------------- - target: {kind: HelmRelease, name: workflows-api} patch: | # S3 приезжает из Vault отдельным ФАЙЛОМ, а не парой переменных: # приложение читает по этому пути целый JSON. В base путь ведёт в # /etc/sarex/yc-s3/, куда в контуре ничего не смонтировано. - op: test path: /spec/values/services/backend/envs/3/name value: S3_SERVICE_ACCOUNT - op: replace path: /spec/values/services/backend/envs/3/value/_default value: /vault/secrets/processing-s3 - op: add path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-s3 value: secrets/data/minio/apps/processing - op: add path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-s3 value: |- {{- with secret "secrets/data/minio/apps/processing" -}} { "host": "{{ index .Data.data "host" }}", "bucket": "{{ index .Data.data "bucket" }}", "access_key_id": "{{ index .Data.data "access_key_id" }}", "secret_access_key": "{{ index .Data.data "secret_access_key" }}", "region": "{{ index .Data.data "region" }}", "verify": false } {{- end -}} # --- engine-low ------------------------------------------------------------- # Патчи адресуются по индексу, поэтому перед каждым replace идёт op: test на # имя переменной. Если в base порядок envs изменится, сборка упадёт явно, # вместо того чтобы молча перезаписать соседнее значение. - target: {kind: HelmRelease, name: engine-low} patch: | # Sentry — внешний домен, из контура недостижим. Значение прокидывается # ещё и в каждый под задачи, поэтому зануляем в одном месте. - op: test path: /spec/values/services/backend/envs/2/name value: WORKFLOWS_SENTRY_DSN - op: replace path: /spec/values/services/backend/envs/2/value/_default value: "" # В base адрес django неверный даже для кластеров, где он есть: сервис # называется backend-svc и слушает 80, а не backend:8000. У api то же # значение уже правильное. - op: test path: /spec/values/services/backend/envs/5/name value: DJANGO_HOST - op: replace path: /spec/values/services/backend/envs/5/value/_default value: http://backend-svc.django.svc.cluster.local:80 # S3 — как у api выше. - op: test path: /spec/values/services/backend/envs/6/name value: S3_SERVICE_ACCOUNT - op: replace path: /spec/values/services/backend/envs/6/value/_default value: /vault/secrets/processing-s3 # SMTP выключаем целиком: почтового релея в контуре нет. Вместе с флагом # убираем аннотацию инжекции secrets/vault/common/smtp_auth — секрета в # Vault нет, а vault-agent-init на несуществующем секрете не отрендерит # шаблон и оставит под в Init:Error, до флага дело не дойдёт. - op: test path: /spec/values/services/backend/envs/23/name value: ENABLE_SMTP - op: replace path: /spec/values/services/backend/envs/23/value/_default value: "0" - op: remove path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-smtp - op: remove path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-smtp # Смежные сервисы, которых в контуре нет: documentations (PDM, # filestream), resources, bim-api, workspace, issues, comparisons, # mailgun. Оставляем только S3 — единственное внешнее хранилище, которое # в aero действительно есть. - op: test path: /spec/values/services/backend/envs/22/name value: ENABLE_PDM_STORAGE - op: replace path: /spec/values/services/backend/envs/22/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/26/name value: ENABLE_BIM_API_V2_DB - op: replace path: /spec/values/services/backend/envs/26/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/27/name value: ENABLE_WORKSPACE_API_DB - op: replace path: /spec/values/services/backend/envs/27/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/28/name value: ENABLE_ISSUE_API_DB - op: replace path: /spec/values/services/backend/envs/28/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/29/name value: ENABLE_RESOURCES_API - op: replace path: /spec/values/services/backend/envs/29/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/31/name value: ENABLE_PDM_API_DB - op: replace path: /spec/values/services/backend/envs/31/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/32/name value: ENABLE_COMPARISONS_API_DB - op: replace path: /spec/values/services/backend/envs/32/value/_default value: "0" - op: test path: /spec/values/services/backend/envs/33/name value: ENABLE_MAIL_GUN - op: replace path: /spec/values/services/backend/envs/33/value/_default value: "0" # Планирование подов задач. engine работает kubernetes-исполнителем и сам # создаёт Job'ы, подставляя им nodeSelector dedicated=processing и # соответствующий toleration. Выделенных нод в контуре нет — все три # равнозначны, — поэтому поды задач висли бы в Pending с # didn't match Pod's node affinity/selector # ровно как это было у postgresql (см. postRenderers в его релизе). # # ENABLE_TOLERATION ЗДЕСЬ НЕ ВЫКЛЮЧАТЬ. Сначала я поставил его в "0" — и # это тихо сломало запуск задач совсем: в движке классы ресурсов # регистрируются ПОД ЭТИМ ЖЕ ФЛАГОМ, # if resCfg.EnableToleration { services[HighResources] = ... } # (pkg/kube_services/services.go), поэтому задача с service_request # "high-resources" падала не на планировании, а раньше — на разборе: # ERROR create k8s job: create k8s job: unknown service # Ни одного пода при этом не создавалось, и в логе не было ни слова про # nodeSelector, так что связь с этим флагом неочевидна. # # Вместо выключения переводим селектор на метку, которая есть на всех # нодах, — kubernetes.io/os=linux. Класс сервисов остаётся # зарегистрированным, nodeSelector совпадает с любой нодой, а toleration # на несуществующий taint безвреден. Запрашиваемые ресурсы трогать не # надо: в base это 1 CPU и 1Gi. # # IGNORE_TAINTS_AND_NODE_SELECTOR (появился в base из master) полагаться # на него не стоит: в master workflows-engine такой переменной нет. Образ # при этом contour_a03d37da-dirty2 — ручная сборка, поднятая тем же # коммитом master, что добавил переменную, так что она там, вероятно, # поддержана. Проверить нечем, поэтому селектор задан явно, а не через # неё; вреда от того, что она выставлена в base, нет. - op: test path: /spec/values/services/backend/envs/53/name value: TOLERATION_KEY - op: replace path: /spec/values/services/backend/envs/53/value/_default value: kubernetes.io/os - op: test path: /spec/values/services/backend/envs/54/name value: TOLERATION_VALUE - op: replace path: /spec/values/services/backend/envs/54/value/_default value: linux - op: test path: /spec/values/services/backend/envs/55/name value: TOLERATION_KEY_HIGH_MEM - op: replace path: /spec/values/services/backend/envs/55/value/_default value: kubernetes.io/os - op: test path: /spec/values/services/backend/envs/56/name value: TOLERATION_VALUE_HIGH_MEM - op: replace path: /spec/values/services/backend/envs/56/value/_default value: linux - op: test path: /spec/values/services/backend/envs/57/name value: TOLERATION_KEY_PERSISTENT - op: replace path: /spec/values/services/backend/envs/57/value/_default value: kubernetes.io/os - op: test path: /spec/values/services/backend/envs/58/name value: TOLERATION_VALUE_PERSISTENT - op: replace path: /spec/values/services/backend/envs/58/value/_default value: linux - op: test path: /spec/values/services/backend/envs/70/name value: DEFAULT_NODE_SELECTOR_KEY - op: replace path: /spec/values/services/backend/envs/70/value/_default value: kubernetes.io/os - op: test path: /spec/values/services/backend/envs/71/name value: DEFAULT_NODE_SELECTOR_VALUE - op: replace path: /spec/values/services/backend/envs/71/value/_default value: linux # --- Vault для ПОДОВ ЗАДАЧ, а не для самого движка ---------------------- # В сборке contour_a03d37da-dirty2 движок умеет не монтировать в Job # готовый Secret, а вешать на него аннотации vault-agent — тогда файл # с кредами кладёт агент, и Secret в namespace задач не нужен вовсе. # Именно так это работает в UGMK, где никакого yc-s3 в namespace нет. # # В master workflows-engine этого кода нет (сборка с невлитой ветки), # поэтому набор переменных восстановлен по строкам бинарника: # VAULT_ROLE, VAULT_SA, VAULT_MOUNT_PATH # vault.hashicorp.com/{role,secret-volume-path,agent-inject-file-*, # agent-inject-secret-*,agent-inject-template-*} # yc-s3, yc-s3-service-account.json, /etc/sarex/yc-s3 # # В base задан только VAULT_USE=true — остальных трёх нет НИ В ОДНОМ # кластере репозитория, поэтому аннотации выходили неполными, агент в под # задачи ничего не клал, и файл читался как пустой: # ValueError: SERVICE_S3 is not valid # Expecting value: line 1 column 1 (char 0) # # Переменных нет в base, поэтому op: add с "-" (добавление в конец # списка), а не replace по индексу. - op: add path: /spec/values/services/backend/envs/- value: name: VAULT_ROLE value: _default: processing - op: add path: /spec/values/services/backend/envs/- value: name: VAULT_SA value: _default: processing-vault # VAULT_MOUNT_PATH — вопреки имени НЕ корень KV, а ПОЛНЫЙ путь секрета: # движок подставляет значение в шаблон целиком. Проверено по аннотациям # созданного пода задачи: # agent-inject-secret-yc-s3: # agent-inject-template-yc-s3: # {{- with secret "" -}} # {{ index .Data.data "yc-s3-service-account.json" }} # Отсюда два следствия: путь пишется в форме чтения KV v2 (с /data/), а в # секрете обязан быть ключ с именем ФАЙЛА. # # Путь ОДИН НА ВСЕ ФАЙЛЫ, которые движок кладёт в поды задач: он # подставляет VAULT_MOUNT_PATH в каждую аннотацию, меняя только имя # ключа. Так, для django-auth аннотация ссылается на этот же путь и ищет # в нём ключ django-auth.json. Поэтому имя пути нейтральное (job-files), # а не по имени одного из файлов, — иначе оно врёт о содержимом. # Сам секрет кладёт ansible, vault_app_secrets. - op: add path: /spec/values/services/backend/envs/- value: name: VAULT_MOUNT_PATH value: _default: secrets/data/apps/processing/job-files # S3 из Vault, как у api. - op: add path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-secret-processing-s3 value: secrets/data/minio/apps/processing - op: add path: /spec/values/services/backend/podAnnotations/_default/vault.hashicorp.com~1agent-inject-template-processing-s3 value: |- {{- with secret "secrets/data/minio/apps/processing" -}} { "host": "{{ index .Data.data "host" }}", "bucket": "{{ index .Data.data "bucket" }}", "access_key_id": "{{ index .Data.data "access_key_id" }}", "secret_access_key": "{{ index .Data.data "secret_access_key" }}", "region": "{{ index .Data.data "region" }}", "verify": false } {{- end -}}