Files
docs/infrastructure/test-contour/deploy-walkthrough.md
T
Valeriy Petrov 5814ece51e
docs-ci-cd / test (push) Has been skipped
docs-ci-cd / parse-tag (push) Successful in 1s
docs-ci-cd / build-and-push (push) Successful in 27s
docs-ci-cd / deploy-gitops (push) Successful in 1s
Add step-by-step deploy walkthrough for CLOUD-SITE-TEST-01.
Document bootstrap, post-deploy fixes, and day-to-day workflow on remote test contour.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 11:00:16 +03:00

12 KiB
Raw Permalink Blame History

Как развернуть test-контур на CLOUD-SITE-TEST-01

Пошаговый рассказ: что делали при переносе песочницы с локальной Multipass-VM на удалённый сервер CLOUD-SITE-TEST-01 (dev.sovamed.ru). Для справочника по архитектуре см. CLOUD-SITE-TEST-01, для общего плана — k3s/DEPLOY.md.


0. Что было до этого

Локально крутилась Multipass-ферма (vm-k8s-git, *.sova.local, NodePort). Для общего test-контура на железе решили:

  • один сервер, один k3s;
  • публичные домены *.dev.sovamed.ru;
  • Let's Encrypt вместо self-signed;
  • без Redmine (экономия RAM);
  • CI/CD и GitOps — как на локалке: Gitea → ArgoCD → Helm.

Исходники лежат в монорепо: оркестрация в k3s/, приложения и Helm — в k8s/.


1. Подготовка сервера и DNS

Сервер

Имя CLOUD-SITE-TEST-01
Публичный IP 46.243.172.227
VPN / SSH / kubectl 10.0.186.3
Пользователь petrov
RAM 12 GB (+ swap 8 GB)

DNS

A-записи на 46.243.172.227:

git.dev.sovamed.ru
argocd.dev.sovamed.ru
grafana.dev.sovamed.ru
api.dev.sovamed.ru
adm.dev.sovamed.ru
cabinet.dev.sovamed.ru
docs.dev.sovamed.ru

Порт 80 с интернета обязателен — без него Let's Encrypt (HTTP-01) не выпустит сертификаты.

VPN

SSH и kubectl с рабочей машины — через VPN на 10.0.186.3. Браузер — на публичные URL через DNS.


2. Настройка на Mac

cd k3s
cp remote.env.example remote.env

Заполнил remote.env (главное):

SERVER_IP=10.0.186.3          # VPN для SSH/kubectl
BASE_DOMAIN=dev.sovamed.ru
GITEA_DOMAIN=git.dev.sovamed.ru
API_DOMAIN=api.dev.sovamed.ru
# ... остальные домены
ENABLE_TLS=1
LETSENCRYPT_EMAIL=devops@sovamed.ru
CLUSTER_ISSUER=letsencrypt-prod
SWAP_GB=8
SKIP_REDMINE=1
KUBECONFIG_PATH=~/.kube/config-sova-remote-test

SSH-пароль и sudo — в remote.env (или ключ). SSH-пароль на сервере потом не меняли — только сервисные креды в k8s.

Права на скрипты:

chmod +x scripts/*.sh scripts/lib/*.sh
chmod +x ../k8s/scripts/*.sh

Проверка:

ssh petrov@10.0.186.3

3. Автоматический bootstrap (основной прогон)

cd k3s
./scripts/bootstrap-remote-test.sh

Скрипт bootstrap-remote-test.sh по шагам:

Шаг Что происходит
1 На сервере: swap 8 GB, apt, установка k3s (--disable traefik), скачивание kubeconfig на Mac
2 Platform: ingress-nginx (LB 80/443), cert-manager, sealed-secrets, ArgoCD, Prometheus/Grafana, Loki, Gitea; basic auth + ingress для git/argocd/grafana
3 Gitea: org sova, push репозиториев (backend, adminpanel, cabinet, docs, sova-deploy, sova-mocks)
4 Gitea Actions runner, CI secrets, registries.yaml на ноде для pull образов
5 PostgreSQL, MySQL, Redis, WireMock/Mailpit, db-init
6 ArgoCD: project, test-contour apps, ожидание Healthy
7 TLS: ClusterIssuer Let's Encrypt, выпуск сертификатов
8 Итог: список URL и паролей

Если упало на середине — продолжить:

BOOTSTRAP_FROM_STEP=4 ./scripts/bootstrap-remote-test.sh

Kubeconfig после шага 1:

export KUBECONFIG=~/.kube/config-sova-remote-test
kubectl get nodes

4. Что правили после bootstrap

Автомат не покрывает всё — ниже реальные доработки на этом контуре.

4.1. Домены в GitOps

В k8s/sova-deploy/apps/*/values-test.yaml выставили хосты *.dev.sovamed.ru, TLS, образы из Gitea registry:

ingress:
  host: api.dev.sovamed.ru
  tls:
    enabled: true
    clusterIssuer: letsencrypt-prod
image:
  repository: git.sova.local/sova/backend
  tag: backend-v1.0.13-test

Запушили ветку test в Gitea (sova/sova-deploy) → ArgoCD подхватил.

4.2. Registry и pull образов

CI пушит в registry под git.sova.local, нода должна резолвить registry:

  • /etc/hosts на сервере: 10.0.186.3 git.dev.sovamed.ru git.sova.local
  • /etc/rancher/k3s/registries.yaml — mirror + credentials
  • Скрипт: k8s/scripts/configure-k3s-registry-remote.sh

4.3. CI/CD под HTTPS

Обновили workflow build.yml в app-репозиториях и скрипты (gitea-url.sh, release-tag.sh, bootstrap-gitea-ci-secrets.sh) — Gitea с Mac/VPN через https://10.0.186.3 + заголовок Host: git.dev.sovamed.ru.

Проверка релиза:

cd k8s
export KUBECONFIG=~/.kube/config-sova-remote-test
export VM_IP=10.0.186.3 GITEA_SCHEME=https GITEA_HTTP_PORT=443 GITEA_INSECURE_TLS=1
export GITEA_HOST=git.dev.sovamed.ru

./scripts/release-tag.sh backend backend-v1.0.13-test

Цепочка: тег → Gitea Actions → образ в registry → commit в sova-deploy → ArgoCD sync → pod.

4.4. Ветки issues/27

Перенесли feature-ветки из монорепо в Gitea и смержили в test:

./scripts/migrate-issues-27-branches.sh
# merge issues/27 → test для backend, adminpanel, cabinet

4.5. TLS на приложениях

После sync ArgoCD ingress терял TLS — добавили блок tls в Helm-шаблоны sova-deploy/apps/*/templates/all.yaml и ingress.tls.enabled в values-test.

4.6. Redmine убрали

Redmine на этом сервере не нужен:

kubectl delete application redmine-test -n argocd

4.7. Пароли

Сгенерировали сложные пароли для Gitea, ArgoCD, Grafana, БД, app secrets. Применили:

  • helm/API для platform;
  • ALTER USER в PostgreSQL/MySQL;
  • GitOps (sova-deploy/data/test, apps/*/values.yaml);
  • bcrypt для seed-пользователей admin/cabinet.

Все креды — k8s/.generated/platform-credentials.env (не в git). SSH не трогали.

4.8. Admin Panel — API URL

Admin Panel не логинился: в values-test.yaml был ключ env: вместо runtimeEnv: → в pod уходил http://api.test.sova.local. Исправили:

runtimeEnv:
  API_BASE_URL: https://api.dev.sovamed.ru

4.9. Grafana + Loki

Grafana падала из-за двух default datasource. Решение:

  • Loki подключён через grafana.additionalDataSources в values-lite-12gb.yaml;
  • отдельный ConfigMap loki-loki-stack удаляется после helm loki-stack.

4.10. Basic Auth на периметре

Все публичные URL закрыты HTTP Basic Auth на ingress:

./scripts/bootstrap-ingress-basic-auth.sh   # secret contour-basic-auth
./scripts/deploy-platform-ingress.sh        # platform ingress

Логin: sova-contour, пароль — в platform-credentials.env.

Для Gitea — два Ingress: /api, /v2, /sova без auth (CI/git), веб-UI /с auth.


5. Типичный рабочий цикл после развёртывания

kubectl

export KUBECONFIG=~/.kube/config-sova-remote-test
kubectl get applications -n argocd
kubectl get pods -n sova-test

Выкат новой версии приложения

cd k8s
./scripts/release-tag.sh backend backend-v1.0.14-test
# аналогично: adminpanel, cabinet, docs

Выкат документации

./scripts/release-tag.sh docs docs-v1.0.15-test

ArgoCD sync вручную

kubectl annotate application backend-test -n argocd argocd.argoproj.io/refresh=hard --overwrite

Креды

cat k8s/.generated/platform-credentials.env
./scripts/print-credentials.sh

6. Проверка «всё живо»

export KUBECONFIG=~/.kube/config-sova-remote-test
source k8s/.generated/platform-credentials.env

# Basic auth + TLS
curl -sk -o /dev/null -w "%{http_code}\n" -u "${BASIC_AUTH_USER}:${BASIC_AUTH_PASS}" \
  -H "Host: api.dev.sovamed.ru" https://10.0.186.3/

# ArgoCD
kubectl get applications -n argocd

# Сертификаты
kubectl get certificate -A

# CI
curl -sk -u "gitea_admin:${GITEA_ADMIN_PASS}" -H "Host: git.dev.sovamed.ru" \
  "https://10.0.186.3/api/v1/repos/sova/backend/actions/runs?limit=1"

Чеклист:

  • kubectl get nodes — Ready
  • ArgoCD apps — Synced / Healthy
  • URL открываются (с basic auth → затем логин сервиса)
  • kubectl get certificate -A — Ready
  • CI по тегу *-test — success
  • Grafana Explore → Loki → {namespace="sova-test"}

7. Карта скриптов (что за что отвечает)

k3s/scripts/bootstrap-remote-test.sh     ← главная команда «развернуть всё»
k3s/remote.env                           ← IP, домены, TLS, SSH

k8s/scripts/deploy-platform-remote.sh  ← Helm: ingress, cert-manager, ArgoCD, Gitea…
k8s/scripts/deploy-platform-ingress.sh   ← Ingress git / argocd / grafana (+ basic auth)
k8s/scripts/bootstrap-ingress-basic-auth.sh
k8s/scripts/bootstrap-gitea.sh           ← org, repos, admin
k8s/scripts/bootstrap-gitea-runner.sh    ← Actions runner
k8s/scripts/bootstrap-gitea-ci-secrets.sh
k8s/scripts/configure-k3s-registry-remote.sh
k8s/scripts/deploy-test-stack.sh         ← БД + mocks (DATA_ONLY=1)
k8s/scripts/bootstrap-argocd.sh          ← GitOps apps
k8s/scripts/bootstrap-tls.sh            ← Let's Encrypt
k8s/scripts/release-tag.sh               ← тег → CI → deploy

8. Частые проблемы

Симптом Что делали
ImagePullBackOff configure-k3s-registry-remote.sh, /etc/hosts на ноде
ArgoCD «Failed to authenticate» к Gitea обновить secret repo-sova-deploy с новым паролем Gitea
Admin Panel не логинится runtimeEnv.API_BASE_URL, не env:
Grafana CrashLoop один default datasource; Loki через Helm additionalDataSources
Symfony «parameter 3Dbi6a» в REDIS_URL/DATABASE_URL удвоить %%% для GitOps
CI 403 на push проверить Gitea credentials, gitea_git_remote_url (URL-encode пароля)
Let's Encrypt pending DNS, порт 80, /.well-known/acme-challenge без auth

9. Ссылки


Документ описывает фактический процесс развёртывания test-контура на CLOUD-SITE-TEST-01 (2026).