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

199 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Особенности билда/деплоя через 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.
Типовые команды:
```bash
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
```
Шифрование значений:
```bash
# показать 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` часто:
```yaml
image:
postgresql: 192.168.10.68:5000/library/postgres:16-alpine
```
У клиента заменить host на **их** registry, например:
```yaml
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` — без интернета
Сейчас:
```dockerfile
FROM docker.io/library/postgres:16-alpine
FROM quay.io/keycloak/keycloak:26.4.0
```
В закрытом контуре:
```dockerfile
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:
```yaml
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.