nelm-ci/NELM-CLOSED-LOOP.ru.md

10 KiB
Raw Permalink Blame History

Особенности билда/деплоя через nelm и правки репозиториев bitbucket/ под закрытый контур

1. Чем nelm отличается от привычного werf/helm в CI

Тема Как было (werf / common-ci) Как делаем (nelm + Jenkins)
Источник манифестов werf.yaml + .helm, converge только chart в .helm/, nelm release install
Секреты werf secret / тот же формат ключа secret-values.yaml + NELM_SECRET_KEY (nelm chart secret …)
Сборка образа часто встроенный werf build отдельный этап: docker build + docker push в Jenkins
Откуда код GitLab CI clone Jenkins сам клонирует Bitbucket на каждый job
Релиз имя/лейблы werf release name = <service>-<env>, namespace = env
Три контура разные values / stages --set env=… --set global.cluster=…, overlays через dig

Практические следствия:

  1. werf.yaml в закрытом контуре не нужен для деплоя. Его можно оставить для совместимости, но pipeline на него не опирается. Деплой идёт из .helm/.
  2. Ресурсы в кластере получают Helm-аннотации meta.helm.sh/release-name / release-namespace. Если объект уже создан руками или другим релизом — nelm откажется без --force-adoption (лучше удалить чужой объект или один раз осознанно adopt).
  3. Расшифровка секретов происходит на agent в момент install. Без NELM_SECRET_KEY job упадёт или зальёт ciphertext в Secret (если включить --no-decrypt-secrets — так делать нельзя).
  4. nelm ждёт Ready у workloads в пределах --timeout. В закрытом контуре таймауты чаще связаны с ImagePullBackOff (нет образа / нет pull secret), а не с самим nelm.

Типовые команды:

export NELM_SECRET_KEY=$(cat /secure/nelm_secret_key)

# проверка шаблонов без кластера
nelm chart render -n dev --set env=dev --set global.cluster=dev .helm

# деплой
nelm release install -n dev -r postgres-dev \
  --set env=dev --set global.cluster=dev \
  --timeout 5m \
  .helm

nelm release list -n dev
nelm release history -n dev -r postgres-dev

Шифрование значений:

# показать plaintext (только на защищённой машине)
nelm chart secret values-file decrypt .helm/secret-values.yaml

# зашифровать новый файл тем же ключом
nelm chart secret values-file encrypt plaintext-values.yaml > .helm/secret-values.yaml

2. Что поправить в репозиториях из папки bitbucket/

Ниже — конкретный чеклист по текущим сервисам (postgres, seaweedfs, ollama, keycloak, vllm).

2.1. Образы: только внутренний registry

Сейчас в values.yaml часто:

image:
  postgresql: 192.168.10.68:5000/library/postgres:16-alpine

У клиента заменить host на их registry, например:

image:
  postgresql: registry.client.local/library/postgres:16-alpine

То же для всех ключей image.* во всех пяти чартах.

values-public.yaml (ghcr/docker.io/quay) — не подключать в job (USE_PUBLIC_IMAGES=false). Файл можно оставить в repo как reference для открытых стендов или удалить, чтобы никто случайно не выкатил публичные теги.

2.2. Dockerfile FROM — без интернета

Сейчас:

FROM docker.io/library/postgres:16-alpine
FROM quay.io/keycloak/keycloak:26.4.0

В закрытом контуре:

FROM registry.client.local/library/postgres:16-alpine
FROM registry.client.local/keycloak/keycloak:26.4.0

Либо на этапе build в Jenkins делать docker pull уже с зеркала (если base заранее завезли), а в Dockerfile всё равно писать внутренний путь — иначе docker build на agent без интернета упадёт.

Заранее завезти в registry: postgres, postgres-exporter, seaweedfs, ollama, keycloak, vllm (и зависимости keycloak plugins, если тянутся с сети на build).

2.3. imagePullSecrets

В values:

imagePullSecrets:
  - name: registrysecret

В каждом namespace деплоя должен существовать Secret этого имени (тип kubernetes.io/dockerconfigjson) до первого install, либо чарт должен его создавать из зашифрованных данных (сейчас обычно ожидается снаружи).
Иначе: ErrImagePull / ImagePullBackOff.

2.4. Секреты приложения

Файлы:

  • postgres/.helm/secret-values.yaml — пароль БД
  • keycloak/.helm/secret-values.yaml — admin / DB
  • seaweedfs/.helm/secret-values.yaml — S3 keys

Действия у клиента:

  1. Сгенерировать свой NELM_SECRET_KEY (не lab-ключ).
  2. Перешифровать все secret-values.yaml новым ключом (nelm chart secret key rotate или encrypt заново).
  3. Положить ключ только в Jenkins credentials / vault агента.
  4. Заменить lab-пароли (admin123) на боевые до шифрования.

Репозитории без secret-values (ollama, частично vllm) — проверить, нет ли plaintext секретов в обычном values.yaml / TLS файлах.

2.5. TLS и вложенные секреты в git (vllm)

В vllm/.helm/secret/{dev,preprod,prod}/ лежат tls.crt / tls.key.
Для клиента:

  • либо заменить на клиентские сертификаты;
  • либо убрать из git и монтировать из внешнего Secret / cert-manager;
  • не коммитить боевые private key в публичные зеркала.

2.6. StorageClass и scheduling

В чартах lab:

  • storageClassName: localpath (или аналог)
  • nodeSelector: node-role.kubernetes.io/worker: ""

У клиента:

  • имя StorageClass из их кластера (ceph-rbd, nfs-client, …);
  • nodeSelector/tolerations под GPU-ноды для ollama / vllm (gpu.enabled уже есть флагом — выставить true и нужные taints только если ноды готовы);
  • ресурсы (CPU/memory) под квоты namespace.

2.7. Ingress / DNS

У keycloak, ollama, vllm есть Ingress. Поправить:

  • hosts под клиентскую зону;
  • TLS (cert-manager annotations или уже существующие секреты);
  • класс Ingress (ingressClassName), если не default.

В закрытом контуре без внешнего DNS — либо внутренние имена, либо временно ClusterIP + port-forward для приёмки.

2.8. Убрать/игнорировать зависимости от GitLab CI и werf

В репозиториях могут остаться:

  • werf.yaml
  • .gitlab-ci.yml / include на common-ci

Для клиентского Bitbucket+Jenkins:

  • pipeline из Bitbucket не должен вызывать werf converge;
  • достаточно .helm/ + Dockerfile;
  • CI logic — в Jenkins (Jenkinsfile / freestyle), см. CLIENT-SETUP.ru.md.

2.9. Имена release и namespace

Соглашение lab/клиента:

  • namespace = dev | preprod | prod
  • release = <chartName>-<env> (например postgres-dev)

Шаблоны используют .Values.env для overlays. Не хардкодить namespace в templates.

2.10. Экспортёры и sidecar-образы

У postgres отдельный образ postgresqlExporter. Его тоже нужно завезти во внутренний registry и прописать в values.yaml.
Нельзя подставлять образ postgres как exporter (так ломается readiness).

3. Рекомендуемый порядок миграции репо под клиента

  1. Завести project в Bitbucket, запушить пять сервисов.
  2. Заменить registry host + Dockerfile FROM.
  3. Создать registrysecret в dev.
  4. Сгенерировать клиентский NELM_SECRET_KEY, перешифровать secret-values.yaml, обновить пароли.
  5. Поправить StorageClass / Ingress / nodeSelector.
  6. Прогнать nelm chart render локально.
  7. Подключить Jenkins job с checkout из Bitbucket, USE_PUBLIC_IMAGES=false.
  8. build-and-deploy для postgres на dev, затем остальные сервисы.

4. Критерий «готово для закрытого контура»

  • Job клонирует актуальный commit из Bitbucket (в логе виден HEAD=… после checkout).
  • docker build не ходит в интернет (все FROM и base — внутренние).
  • nelm release install без values-public.yaml.
  • Секреты в кластере — расшифрованный plaintext, ключ не в git.
  • Поды Running/Ready, образы с клиентского registry.