Перейти к основному содержанию Перейти к навигации Перейти к нижнему колонтитулу

Kubernetes

Работайте с Kubernetes в духе репозиториев Rediacc: форкайте или переносите работающий кластер вместе с его данными на другую машину или в другой дата-центр с коротким переключением.

Kubernetes

Rediacc привносит Kubernetes в продукт, не отказываясь от мышления репозитория, на котором построена вся остальная платформа. Отличительное утверждение прямое: вы можете форкнуть или перенести работающий кластер, включая его данные, на другую машину или в другой дата-центр с коротким переключением. Это не миграция через остановку-и-восстановление, и это не магия нулевого простоя. Рабочие нагрузки перезапускаются на месте назначения, переключение измеряется в секундах, а данные едут вместе.

Kubernetes работает на базе сертифицированного дистрибутива Kubernetes k3s, встроенного в renet так же, как и другие серверные бинарные файлы.

Модель объектов

Rediacc переворачивает привычную картину «кластер оборачивает всё», чтобы мышление репозитория по-прежнему применялось:

  • Кластер представляет собой контейнер. Машина размещает Docker-репозитории (без изменений) и/или кластеры. Кластер из одного узла на одной машине сохраняет на уровне кластера историю «один файл перемещает всю систему». Состояние кластера (каталог данных k3s: его встроенное хранилище данных и containerd) хранится в поддерживаемых хранилищем данных copy-on-write файлах-образах, по одному на узел, с --data-dir k3s, смонтированным внутри точки монтирования образа.
  • Kubernetes-репозиторий представляет собой пространство имён. rdc repo create <repo> -m <name> создаёт репозиторий, рабочим домом которого является пространство имён Kubernetes <repo> внутри этого кластера.
  • Постоянные тома представляют собой отдельные copy-on-write единицы. PV представляют собой RBD-образы на Ceph, или небольшие файлы-образы хранилища данных через локальный провайдер PV renet на локальном бэкенде. Это никогда не каталоги внутри одного непрозрачного образа кластера: внутренняя файловая система не имеет reflink’ов, поэтому независимые форки на уровне репозитория требуют независимых образов PV.

Именно это разделение делает возможными оба обещания одновременно физически: всегда copy-on-write форки пространств имён (данные каждого репозитория клонируются независимо) и портативность кластера целиком (образы кластера плюс каждый образ PV перемещаются вместе).

ПонятиеDocker-репозиторийKubernetes-репозиторий
Рабочий домИзолированный Docker-демонПространство имён в кластере
Внедряемая переменнаяDOCKER_HOSTKUBECONFIG
Обёртка развёртыванияrenet composerenet kube
Единица данныхОдин образ LUKSОбразы кластера плюс образы на PV
Единица форкаОбраз репозиторияПространство имён плюс его клоны PV
Клонирование целиком(репозиторий и есть место)rdc cluster fork / rdc cluster migrate

Объявление и создание кластера

Кластер представляет собой именованный набор пулов узлов в приватной сети. Сначала объявите его в конфигурации, затем провизионируйте.

# Объявить кластер с пулами (пока ничего не провизионируется)
rdc cluster create prod --declare-only \
  --provider my-linode \
  --pool ceph:ceph:3 \
  --pool k8s:k8s-server:3

# Провизионировать участников пулов, инициализировать renet на каждом, установить компоненты (сначала Ceph)
rdc cluster create prod

Роли пулов: ceph, k8s-server, k8s-agent и hyperconverged (явное согласие, поскольку целевые показатели памяти Ceph и пороги вытеснения kubelet конкурируют за одну и ту же RAM). Каждый пул несёт аппаратную асимметрию в виде размера пула и параметров диска: узлы Ceph с упором на диск, узлы Kubernetes с упором на CPU/RAM.

Участники пулов материализуются в resources.machines как <cluster>-<pool>-<n> с обратной ссылкой, поэтому работают все существующие команды -m: rdc machine status, rdc term connect, команды репозиториев и стратегии резервного копирования видят узлы кластера как обычные машины.

Облачные провайдеры провизионируют через OpenTofu, следуя тому же реестру ProviderMapping, который использует rdc machine provision, расширенному блоком приватной сети (VLAN или VPC, MTU для установки, именование приватного сетевого интерфейса). Локальный KVM представляет собой всегда доступный путь для тестирования через rdc ops.

# Просмотр кластеров
rdc cluster status                 # список всех кластеров
rdc cluster status prod     # полная конфигурация одного кластера

# Увеличение или уменьшение пула (добавляет/удаляет машины, присоединяет/выводит узлы)
rdc cluster scale prod --pool k8s --count 5


# Демонтаж провизионированных участников и удаление кластера из конфигурации
rdc cluster destroy prod

Получение kubeconfig

Kubeconfig никогда не сохраняется в вашем файле конфигурации (он большой и ротируется). Он получается по запросу через SSH и кешируется локально с правами 0600, следуя тому же паттерну бокового состояния, что и рабочие каталоги OpenTofu и кеш сертификатов.

rdc cluster kubeconfig prod
# Выводит: export KUBECONFIG=~/.config/rediacc/kube/prod.yaml

Репозитории Kubernetes

Флаг цели определяет runtime. Флага типа нет.

# Docker-репозиторий (без изменений): изолированный Docker-демон на машине
rdc repo create shop -m server-1 --size 10G

# Kubernetes-репозиторий: пространство имён "shop" плюс его хранилище, внутри кластера
rdc repo create shop --datastore prod --size 10G

Глаголы репозитория являются единой поверхностью для работы в рамках репозитория. Благодаря воронке разрешения цели практически весь набор команд репозитория принимает --cluster и становится совместимым с кластерами: fork, migrate, push, pull, up, down, resize, diff, commit, branch, checkout, merge, trim, cat, mount, sync, list, status и log. Цель-кластер разрешается в его управляющий узел плюс контекст KUBECONFIG, закреплённый на пространство имён репозитория, что аналогично разрешению машины в DOCKER_HOST плюс рабочий каталог.

rdc repo sync upload shop --local ./config
rdc cluster kubeconfig prod           # экспортировать KUBECONFIG, затем использовать kubectl напрямую

Узлы кластера также материализуются в resources.machines, поэтому вы можете подключиться по SSH к конкретному узлу обычной командой rdc term connect <cluster>-<pool>-<n>.

Rediaccfile с двойным runtime

Портативность между Docker и Kubernetes опирается на соглашение, а не на автоматическое преобразование манифестов. Репозиторий, предоставляющий как путь renet compose, так и путь renet kube под одними и теми же функциями up() и down(), свободно мигрирует в обоих направлениях, потому что соглашения о каталоге данных идентичны. renet внедряет DOCKER_HOST при цели-машине и KUBECONFIG при цели-кластере; up() считывает, какая переменная задана, и действует соответственно.

up() {
  if [ -n "$KUBECONFIG" ]; then
    renet kube apply -f manifests/     # runtime Kubernetes
  else
    renet compose -- up -d             # runtime Docker
  fi
}

Репозиторий, у которого нет целевого runtime, получает чёткий отказ после этапа переноса данных: образы перемещаются, а шаг развёртывания сообщает, что репозиторий не объявляет путь Kubernetes (или Docker), вместо того чтобы повредить состояние.

Форк репозитория

rdc repo fork для Kubernetes-репозитория всегда копирует данные, всегда мгновенно. Нет флага --full и вариантов.

rdc repo fork shop --tag joseph

Это создаёт пространство имён shop-joseph в том же кластере, клонирует каждый том по схеме copy-on-write (клон RBD на Ceph, reflink файлов-образов PV на локальном бэкенде) и разворачивает там рабочие нагрузки. URL форка активен мгновенно под wildcard-сертификатом родителя, поэтому новый сертификат или DNS-запись не выпускаются.

Эскалация назначения:

  • --to-cluster <name> форкает в другой существующий кластер. Тот же бэкенд Ceph: клон RBD остаётся copy-on-write. Другой бэкенд: механизм push перемещает образы.
  • --provider <p> сначала провизионирует новый кластер, со спецификациями пулов, по умолчанию зеркалирующими форму пулов исходного кластера (флаги переопределяют).

Измерено в тестовой лаборатории KVM: форк пространства имён завершается примерно за одну-пять секунд, при этом рабочая нагрузка родителя не затрагивается, а два пространства имён расходятся независимо.

Форк или перенос целого кластера

Операции над кластером целиком находятся в группе rdc cluster, потому что они действуют над другим объектом (всё место со всеми его репозиториями) и не могут быть выражены через команду, принимающую одно имя репозитория. Это флагманская история.

# Клонировать целый кластер, включая данные его репозиториев, в новый кластер
rdc cluster fork prod --to spare --tag staging

# Перенести целый кластер, включая данные его репозиториев, на другую машину или в другой дата-центр
rdc cluster migrate prod --to spare

Обе операции координируют copy-on-write образов кластера плюс каждого образа PV репозитория, а затем переписывают идентичность узлов, чтобы клон или перенесённый кластер поднялся исправно на своих новых адресах. Поскольку k3s хранит состояние control plane в своём встроенном хранилище данных, сам образ кластера и есть снапшот. Порядок консистентности таков: сначала control plane, затем PV, затем агенты.

Честные цифры, измеренные end-to-end в тестовой лаборатории KVM:

ОперацияЧто делаетИзмерено
Форк пространства имёнКлонирует пространство имён одного репозитория плюс его PV на месте~1–5 с
Форк одного RBD-образаCopy-on-write одного клона PV на базе Ceph~5 с
Форк целого кластера из 2 узловДренаж, reflink control plane и агента, переписывание идентичности на новые IP, родитель не затронут~46 с
Миграция кластера между машинамиГорячее предварительное копирование плюс переключение стоп-и-перезапуск~16 с переключения

По умолчанию консистентность устойчива к сбою и референциально целостна: это та же семантика, что и при перезагрузке по питанию, и именно её видят рабочие нагрузки. Снапшоты, консистентные на уровне приложения, доступны, когда файловые системы рабочей нагрузки заморожены во время копирования. Это намеренно не преподносится как нулевой простой. Больше никто не предлагает «форкнуть работающий кластер вместе с его данными» вообще; честная формулировка звучит так: короткое, измеренное переключение, а не маркетинговый абсолют.

Хранение: ceph-csi и постоянные тома

Ceph провизионируется через cephadm-процесс renet на пуле ceph, вне какого-либо кластера Kubernetes, и кластеры потребляют его через шаблонизированные renet манифесты ceph-csi. Каждый экземпляр кластера (и каждый форк) получает собственное пространство имён RBD/RADOS, которое и является примитивом изоляции на уровне арендатора. Хранение находится ниже всех кластеров, поэтому оно также поддерживает обычные Docker-репозитории и бэкенд хранилища данных, а форк кластера клонирует RBD-образы ниже уровня Kubernetes, а не форкает собственный бэкенд хранения.

На локальном бэкенде (без Ceph) локальный провайдер PV renet поддерживает каждый PV небольшим copy-on-write файлом-образом в хранилище данных, клонируемым через reflink при форке. См. Справочник по серверу для структуры на диске и команд renet.

Выбор дистрибутива

Дистрибутив представляет собой абстракцию с небольшим, реальным интерфейсом (установка, присоединение, kubeconfig, проверка состояния, обновление и так далее):

  • k3s: дистрибутив по умолчанию и единственный встроенный. Он под лицензией Apache-2.0, сертифицирован CNCF, представляет собой единый переносимый бинарный файл, и как его встроенный Traefik, так и ServiceLB отключены в пользу прокси Rediacc. Его --data-dir монтируется при старте, что как раз и нужно для форка и миграции кластера при изменении пути монтирования образа. k3s помечен как repoEmbeddable.
  • external: принесите свой собственный kubeconfig. Реальную работу выполняют только getKubeconfig и healthcheck; глаголы жизненного цикла возвращают полноценные результаты «неприменимо» вместо ошибок.
  • RKE2: запланированный третий бэкенд для клиентов с требованиями FIPS/CIS, не входит в этот релиз.

Форк и миграция кластера отказываются работать на дистрибутиве без repoEmbeddable с чёткой ошибкой вместо повреждения состояния, поскольку встраивание состояния кластера в образы хранилища данных требует data-dir, который монтируется при старте.

Реестр

Две разные проблемы с образами, два инструмента:

  • Проблема с апстримом (лимиты скорости Docker Hub, отклонённые pull’ы, офлайн): встроенный pull-through-кеш zot работает на управляющем пуле с sync.onDemand против нескольких апстримов (docker.io, ghcr.io, quay.io). Он встроен в renet так же, как и другие бинарные файлы, и заменяет тестовый реестр ops, так что каждый запуск его задействует.
  • Распространение внутри кластера: встроенное зеркало реестра k3s позволяет узлам делиться уже полученными образами друг с другом (peer-to-peer).

Подключение прозрачно и не требует перезапуска благодаря certs.d/hosts.toml containerd и registries.yaml k3s. Хранилище containerd для каждого репозитория внутри образа кластера остаётся источником истины, который используют форки и миграции; реестр представляет собой кеш перед интернетом, а не состояние.

Сети и URL

URL Kubernetes-репозиториев следуют плоской схеме, с идентичностью пространства имён, свёрнутой в самую левую метку, и кластером в качестве второй стабильной метки:

{service}--{repo}.{cluster}.{machine}.{base}          Kubernetes-репозиторий (пространство имён = repo)
{service}--{repo}-{tag}.{cluster}.{machine}.{base}    форк (пространство имён = repo-tag)

Каждое пространство имён и каждый форк наследуют wildcard-сертификат и DNS-запись родителя, поэтому URL форков активны мгновенно, а новые сертификаты выпускаются только при создании нового кластера или репозитория. Роутер обнаруживает сервисы Kubernetes, опрашивая кластер на предмет Services с аннотацией rediacc.*, что является Kubernetes-аналогом чтения меток Docker. См. Сетевое взаимодействие для модели маршрутизации и Архитектуру для бэкендов хранения.

Атрибуция

Rediacc передаёт несколько сторонних бинарных файлов (k3s, zot и другие, которые встраивает renet). Выведите их версии, идентификаторы лицензий SPDX и URL архивов исходного кода в любой момент:

rdc credits
rdc credits --licenses    # полный текст THIRD_PARTY_LICENSES, включённый в релизы