Материалы к экзамену · Урок 7
Как это вообще работает
Желаемое состояние, операторы и GitOps — четыре идеи, на которых держится всё остальное.
Последний урок — про идеи, а не про компоненты. Они лежат в основании всего, о чём шла речь раньше, и вопросы по ним формулируются просто: «почему это работает именно так».
Вы описываете результат, а не действия
Привычный подход к администрированию — последовательность шагов: поставь, настрой, запусти, проверь. Здесь иначе: вы описываете, как должно быть — желаемое состояние, desired state, а система сама решает, что для этого сделать.
Разница проявляется, когда что-то ломается. Скрипт, отработавший вчера, сегодня не поможет: он уже выполнен. А описание желаемого состояния действует постоянно — если реальность от него отклонилась, её вернут обратно.
Отсюда самолечение: удалённая копия приложения возвращается не потому, что кто-то заметил пропажу, а потому, что реальность разошлась с описанием.
Из чего состоит манифест
Описание желаемого состояния живёт в файле YAML, который называют манифестом. Какой бы объект вы ни описывали — тенант, базу, виртуальную машину, — верхнеуровневых полей всегда четыре, и путать их на экзамене не стоит.
| Поле | Что в нём |
|---|---|
apiVersion | к какой версии API относится тип, например apps.cozystack.io/v1alpha1 |
kind | сам тип: Tenant, Bucket, VMInstance |
metadata | паспортные данные: имя, пространство имён, метки, аннотации |
spec | желаемое состояние — всё, чем объект должен стать |
Пятое поле, status, вы не пишете никогда: его заполняет контроллер, и в нём написано, как
дела обстоят на самом деле. Отсюда простое правило чтения любого объекта: spec — это
ваше требование, status — ответ платформы на него. Цикл сверки выше — это и есть
непрерывное сведение одного к другому.
apiVersion: apps.cozystack.io/v1alpha1
kind: Bucket
metadata:
name: images # как объект зовут
namespace: tenant-lab # где он живёт
spec: # каким он должен стать
replicas: 2
Новые типы объектов и операторы
kubectl get tenants работает, хотя в самом Kubernetes никаких тенантов нет. Работает
потому, что Cozystack расширяет API Kubernetes, и API-серверу тип Tenant известен.
Расширяют API двумя разными способами, и экзамен различает их.
Определение своего типа — CRD (custom resource definition). Вы регистрируете новый тип,
и дальше его объекты хранит и отдаёт обычный API-сервер вместе со встроенными. Так в
платформе устроены, например, резервные копии (backups.cozystack.io) и шлюзы
(gateway.cozystack.io).
Агрегированный API-сервер. Отдельная программа берёт на себя целую группу API, а
основной API-сервер переадресует ей запросы. В Cozystack это cozystack-api в пространстве
имён cozy-system, и именно он отвечает за самые заметные группы — apps.cozystack.io
(тенанты, бакеты, базы, кластеры), core.cozystack.io, sdn.cozystack.io. CRD с именем
tenants.apps.cozystack.io в кластере вы не найдёте: этот тип не зарегистрирован, он
отдаётся агрегированным сервером.
Кто за какую группу отвечает, видно одной командой — в колонке SERVICE либо адрес
программы, либо слово Local, означающее «обычный API-сервер, тип из CRD»:
kubectl get apiservices | grep cozystack
Но тип сам по себе ничего не делает: это запись, которую кластер согласен хранить. Работу выполняет оператор (operator) — программа, которая следит за объектами своего типа и приводит мир в соответствие.
Отсюда практический вывод: если объект создан, а ничего не произошло, вопрос не к объекту, а к оператору. Он либо не запущен, либо не смог.
GitOps
Раз состояние описывается текстом, текст можно хранить в системе контроля версий. Тогда Git становится единственным источником истины, а специальная программа следит, чтобы кластер ему соответствовал.
Платформа использует FluxCD и применяет этот подход к самой себе: её компоненты описаны и разворачиваются тем же способом, каким вы разворачивали бы своё приложение.
Одна оговорка, чтобы не сказать лишнего. Желаемое состояние самой платформы задаёт не ваш репозиторий, а Platform Package — YAML-конфигурация установки; чарты FluxCD тянет из OCI-регистри. Агент внутри кластера непрерывно приводит кластер к описанному состоянию, поэтому изменение, сделанное мимо описания, живёт недолго.
У FluxCD два объекта, которые нужно знать по именам. HelmRepository — источник, откуда
берутся чарты. HelmRelease (короткое имя hr) — заявление «этот чарт такой-то версии с
такими значениями должен быть установлен и оставаться установленным».
Как временно отключить сверку
Непрерывная сверка мешает ровно в одном случае: когда нужно что-то починить руками. Правку, сделанную в обход описания, контроллер откатит через несколько секунд — он для этого и существует.
На такой случай у HelmRelease есть выключатель spec.suspend. Переведённый в suspend
релиз контроллер перестаёт сверять: он не переустанавливает чарт, не откатывает
изменения и вообще не трогает объект. При этом нагрузка продолжает работать — поды не
удаляются, приложение отвечает, — а ваши ручные правки сохраняются до тех пор, пока сверку
не включат обратно.
kubectl patch hr <имя> -n <пространство> --type merge -p '{"spec":{"suspend":true}}'
Обратная операция — "suspend": false. В момент возврата контроллер сверяет объект заново и
всё, что вы поправили руками мимо описания, откатывается. Поэтому suspend — инструмент
диагностики на время расследования, а не способ жить с ручными правками.
Helm
Один объект — это один объект. Приложение — это обычно десяток: развёртывание, сервис, настройки, секреты, правила доступа.
Helm упаковывает такой набор в чарт — шаблоны плюс значения. Меняя значения, вы получаете разные установки из одной упаковки.
В платформе Helm — не рекомендация, а несущая конструкция: каждая позиция каталога это
чарт, и заказ сервиса разворачивает именно его. Сама платформа тоже ставится Helm-чартом —
одной командой helm upgrade --install с чартом cozy-installer в пространство имён
cozy-system.
Складывается такая цепочка, и она стоит того, чтобы её запомнить целиком:
объект → HelmRelease → чарт → оператор → работающие поды
Всё, что делает платформа, проходит по ней. Заказали базу — прошло по ней. Создали тенант — прошло по ней. Установилась сама платформа — тоже.
Словарь Kubernetes, который спросят здесь же
Этот раздел экзамена описан как «седьмая тема плюс базовая терминология», поэтому шесть слов стоит проговорить. Английские названия — ровно те, что будут в вопросах.
| Объект | Что это и зачем |
|---|---|
Namespace | именованное пространство, группирует ресурсы; у каждого тенанта своё |
Pod | наименьшая единица нагрузки — один контейнер или несколько вместе |
Deployment | описывает желаемое: какой образ, сколько реплик, как обновлять |
ReplicaSet | его исполнитель: держит нужное число подов; руками его почти не трогают |
Service | стабильное имя и адрес перед меняющимся набором подов |
PVC | заявка на постоянное хранилище, которое переживает перезапуск пода |
Secret | хранит чувствительное: пароли, токены, ключи |
У Service три типа: ClusterIP — адрес виден только внутри кластера, это тип по
умолчанию; NodePort — открывает порт на каждом узле, годится для проб; LoadBalancer —
просит внешний адрес у платформы, на своём железе его даёт MetalLB из пятого урока.
И пять команд, которые экзамен спрашивает по написанию:
kubectl get pods -A— все поды во всех пространствах имён сразуkubectl describe pod <имя>— подробности пода и, главное, его событияkubectl api-resources— какие типы ресурсов кластер вообще знает, включая добавленные платформойkubectl apply -f manifest.yaml --dry-run=server— отдать манифест на проверку серверу, ничего не сохраняяhelm upgrade --install— идемпотентно: поставит, если релиза нет, обновит, если есть
Что спросят на экзамене
- Что описывается желаемое состояние, а не последовательность действий.
- Что контроллер непрерывно сверяет желаемое с фактическим и устраняет разницу.
- Что желаемое состояние объекта лежит в
spec, фактическое — вstatus, аapiVersion,kindиmetadataотвечают за версию API, тип и имя. - Что CRD добавляет тип, а работу выполняет оператор.
- Что
kubectl get tenantsработает потому, что Cozystack расширяет API Kubernetes: типTenantотдаёт агрегированный серверcozystack-api, а не CRD. - Что
suspendу HelmRelease останавливает сверку, но не удаляет нагрузку: поды продолжают работать, ручные правки сохраняются до возврата сверки. - Что платформа применяет GitOps к самой себе через FluxCD.
- Что желаемое состояние платформы задаёт Platform Package, а чарты FluxCD берёт из OCI-регистри.
- Два объекта FluxCD:
HelmRepository— источник чартов,HelmRelease— заявление об установленном чарте. - Что чарт — единица упаковки, и каждая позиция каталога это чарт.
- Что сам Cozystack ставится Helm-чартом
cozy-installer. - Цепочку: объект → HelmRelease → чарт → оператор → поды.
- Что такое Namespace, Pod, Deployment, ReplicaSet, Service, PVC и Secret — по одной фразе на каждый.
- Три типа Service: ClusterIP, NodePort, LoadBalancer.
- Команды:
kubectl get pods -A,kubectl describe podдля событий,kubectl api-resources,--dry-run=server,helm upgrade --install.
Подробнее: обзор платформы · концепции FluxCD