Локальный bootstrap и читаемый Git источник
В предыдущем уроке мы выбрали Git источником желаемого состояния. Теперь решим практическую проблему: repo-server работает в Pod и не читает произвольную папку ноутбука. Проект «Релиз» получит локальный Git Service внутри отдельного кластера, а читатель передаст в него Git bundle через Kubernetes API. Результат — полный путь от своей рабочей копии к доступной контроллеру revision без аккаунта GitHub или неизвестного registry.
Все команды этой главы предназначены для самостоятельного выполнения читателем. Автор не запускал Git, Docker, kind, kubectl или установку Argo CD. Архив содержит файлы bootstrap и исходники, но не готовую инфраструктуру. Перед каждым обращением к Kubernetes указан context kind-release, чтобы лаборатория имела определённый адрес и не зависела от случайно выбранного текущего кластера.
Рабочая копия остаётся вне кластера
Распакуйте комплект в отдельную папку вне другого Git repository. В ней создаётся main, первый commit и тег release-1. Remote не добавляется. Локальная рабочая копия хранит исходные commits и остаётся источником восстановления Git Service, если учебный кластер исчезнет. Сам ZIP содержит файлы начального состояния, а не уже созданные reader refs.
Docker образы API один, API два, web один и release-git один reader собирает из включённых каталогов. Git образ использует node:24-alpine и добавляет Git через apk. Команды сборки требуют доступных базового образа и пакетов; отсутствие внешнего Git аккаунта не означает полный bootstrap без сети. Автор не проверял доступность пакетов для конкретной архитектуры компьютера.
После kind create и kind load собственные образы окажутся доступны узлу лаборатории. Манифесты используют imagePullPolicy Never, поэтому контейнеры не пытаются угадать registry для этих имён. Если образ не загружен, дальнейшее состояние Pod должно объяснить проблему. Нельзя обещать готовность git Service только на основании наличия Deployment YAML.
Git repository хранится на отдельном PVC
Bootstrap/00-namespaces.yaml создаёт четыре именованные области. Bootstrap/01-git.yaml создаёт PVC git-data, Deployment git и Service git. PVC использует StorageClass по умолчанию: reader сначала просматривает её наличие. Если default provisioner отсутствует, нужно остановить этот этап и подготовить подходящее локальное хранилище, а не считать Pending ошибкой Git протокола.
Init container создаёт bare repository /repos/release.git, если каталога ещё нет. Это repository без рабочей копии, предназначенный для refs и Git объектов. Основной container запускает daemon и использует тот же том. Strategy Recreate соответствует одной копии, которая работает с этим локальным источником. PVC сохраняет импорт при пересоздании Pod в пределах действующего окружения.
Daemon предоставляет чтение по git протоколу. В Dockerfile не включён receive-pack, поэтому Argo CD и другие читатели не могут обычным push изменять refs. Протокол не имеет шифрования и индивидуальных учётных записей; Service остаётся внутри учебного кластера, а repository содержит только несекретные файлы. Это локальная демонстрация доступного источника, не шаблон публичного Git hosting.
Bundle переносит commits через явную границу
Git bundle содержит Git объекты и refs выбранной рабочей копии. Полный bundle --all позволяет импортировать main и теги без remote аккаунта. Скрипт bootstrap/publish-bundle.sh создаёт файл, определяет Pod по метке, передаёт bundle через kubectl cp и выполняет адресный fetch в bare repository. В конце HEAD указывает на main.
Ниже приведены центральные строки скрипта. Его выполняют после commit в своей отдельной рабочей копии и после готовности Git Pod; автор этот шаг не выполнял.
git bundle create /tmp/release-lab.bundle --all
task_git_pod=$(kubectl --context kind-release -n release-lab get pod -l app=release-git -o jsonpath='{.items[0].metadata.name}')
kubectl --context kind-release -n release-lab cp /tmp/release-lab.bundle "$task_git_pod:/tmp/release-lab.bundle" -c git
kubectl --context kind-release -n release-lab exec deploy/git -c git -- git --git-dir=/repos/release.git fetch /tmp/release-lab.bundle '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*'
Публикация bundle отличается от сохранения файла. Если изменения ещё не закоммичены, они не попадут в Git объекты и repo-server не увидит их как revision. Поэтому порядок «изменить YAML → commit → bundle → refresh» входит в регламент. Несколько владельцев не публикуют одновременно: скрипт рассчитан на последовательную работу одного читателя, а не на конкурентный Git hosting.
Право kubectl exec/cp в этот Pod позволяет изменять источник и рассматривается отдельно от read-only daemon. Отключённый receive-pack не ограничивает администратора Kubernetes. В production понадобились бы аутентифицированный Git сервис, ограниченные права публикации и выбранная политика защищённых refs; эту инфраструктуру курс не создаёт.
Установка контроллера не относится к выпуску приложения
Argo CD устанавливается из официального файла тега v3.5.4 после создания namespace argocd. Стандартная установка использует широкие кластерные полномочия; для серии она допустима только в отдельной локальной лаборатории. AppProject далее ограничит прикладные адреса, но не превратит ServiceAccount контроллера в минимальную Kubernetes роль автоматически.
Официальный Getting Started описывает установку и доступ. В README reader использует port-forward argocd-server 8081:443, получает начальный пароль по официальной процедуре и вводит его интерактивно. Пароль не помещается в Git, bundle или текст статьи. Локальный self-signed сертификат объясняет --insecure именно для этого endpoint.
Установка Argo CD создаёт CRD и компоненты управления, а не API/web «Площадки». Она должна завершиться до применения Application. Git Service также должен иметь refs и отвечать repo-server, иначе контроллер получит проблему источника. Эти зависимости задают bootstrap порядок и помогают отличить отсутствие инструмента от неправильной декларации приложения.
Какой результат ожидается перед следующим шагом
После самостоятельного bootstrap reader должен иметь свой kind-release, готовый Git Pod, импортированный main и работающие компоненты argocd. Git URL для Application будет git://git.release-lab.svc.cluster.local/release.git. Он доступен внутри кластера по Service DNS, а не через localhost браузера. Port-forward UI обслуживает человека, Git Service обслуживает repo-server.
Потеря Git Pod при сохранённом PVC не должна удалять commits. Удаление kind-кластера имеет другую границу и не обещает сохранения локального тома. Рабочая копия вне кластера остаётся необходимой: из неё можно снова собрать bundle и bootstrap. Ни одна из этих возможностей не считается выполненной автором резервной проверкой.
Официальные Git daemon и Git bundle задают возможности транспорта. Выбранная последовательность публикации — учебная организация локального примера. Теперь у контроллера есть конкретный читаемый источник, а у читателя — отдельное место создания commits. Следующая глава свяжет этот URL, путь overlay и namespace через Application и ограниченный AppProject.