2026-08-04 22:34:32 +03:00
2026-08-02 17:00:11 +03:00
2026-08-02 17:42:54 +03:00
2026-08-04 22:34:32 +03:00

Оглавление

Введение

Что такое Talos OS

Talos Linux — минималистичный immutable-дистрибутив, спроектированный исключительно для запуска Kubernetes. Talos не имеет SSH, интерактивного шелла и пакетного менеджера — вся конфигурация узла и управление им происходят декларативно через API (talosctl) и файл machineconfig.

Ключевые особенности в сравнении с классическим разворотом кластера (kubeadm/ansible/kubespray поверх Ubuntu/Debian/RHEL):
  • Управление узлом только через API поверх mTLS, нет SSH и шелла - меньшая поверхность атаки
  • Конфигурация декларативная (machineconfig YAML), применяется атомарно, а не пошагово скриптами/ролями
  • Обновления ОС и компонентов кластера (etcd, kubelet, kube-apiserver) атомарные, по схеме A/B, с возможностью отката одной командой
  • Дополнительный функционал ОС подключается через System Extensions, встроенные в образ на этапе сборки (см. ниже), а не через установку пакетов после разворота
  • Конфигурация - единственный источник истины: узел либо соответствует заданному machineconfig, либо нет, что снижает риск конфигурационного дрейфа

Именно из-за этой модели первым шагом идёт сборка кастомного образа через Image Factory: дополнительные компоненты уровня ОС (iscsi, nfs, qemu-guest-agent и т.д.) нельзя доустановить после разворота - они должны быть встроены в образ заранее.

Подготовка к развороту кластера

Требуемые инструменты

Для выполнения команд из этого документа потребуются установленные talosctl (инструкция по установке), kubectl и helm.

Про пути в командах:

Все команды в этом документе выполнялись из директории examples/ - именно там лежат schematics/, patches/, test-cluster/, images/ и cilium-values.yaml. Перед копированием команд нужно перейти в эту директорию (cd examples).

Подготовка schematic.yaml для генерации образа через публичный/приватный Image Factory

customization:
  systemExtensions:
    officialExtensions:
      - siderolabs/iscsi-tools
      - siderolabs/nfs-utils
      - siderolabs/qemu-guest-agent
      - siderolabs/util-linux-tools
  extraKernelArgs:
    - net.ifnames=0
В образ добавляются расширения:
  • siderolabs/iscsi-tools - утилиты для работы с сетевыми дисками по протоколу iscsi
  • siderolabs/nfs-utils - утилиты для монтирования фс по протоколу nfs
  • siderolabs/qemu-guest-agent - гостевой агент для виртуальных машин, запущенных в среде QEMU/KVM (тестовый кластер разворачивается в Proxmox VE)
  • siderolabs/util-linux-tools - набор низкоуровневых утилит Linux, нужен для диагностики и для некоторых CSI драйверов
Дополнительные аргументы ядра:
  • net.ifnames=0 - отключает predictable naming сетевых интерфейсов (имена вида enp6s18), интерфейсы получают классические имена eth0, eth1 и т.д.

Отправка schematic.yaml в сторону Image Factory, получение ID образа и скачивание образа

Следующая команда отправляет файл в сторону Image Factory:

curl -X POST --data-binary @schematics/schematic.yaml https://factory.talos.dev/schematics

  • --data-binary @schematics/schematic.yaml - передача файла; в данном случае файл размещён в директории для удобства, но может быть размещён и в корне проекта
  • https://factory.talos.dev/schematics - URL публичного Image Factory
В ответ прилетит JSON с ID образа и информацией об установленных расширениях:
{
  "id": "e142ceb080fb243141b5b6891cfcf0c60bc9430d69be0adf803999d2b62dc885",
  "schematic": "customization:\n  extraKernelArgs:\n    - net.ifnames=0\n  systemExtensions:\n    officialExtensions:\n      - siderolabs/iscsi-tools\n      - siderolabs/nfs-utils\n      - siderolabs/qemu-guest-agent\n      - siderolabs/util-linux-tools\n"
}
Скачать образ можно командой:

curl -L -o images/metal-amd64.iso "https://factory.talos.dev/image/e142ceb080fb243141b5b6891cfcf0c60bc9430d69be0adf803999d2b62dc885/v1.13.7/metal-amd64.iso"

  • e142ceb080fb243141b5b6891cfcf0c60bc9430d69be0adf803999d2b62dc885 - ID, полученный в ответе ранее
  • metal-amd64.iso - образ для bare metal и виртуальных машин без поддержки cloud-init

Подготовка виртуальных машин

Будет развернут кластер следующего вида:

  • 3 мастера: 1vcpu, 2G ram, 15G ssd
  • 3 воркера с доп диском под данные: 3vcpu, 6G ram, 15G + 30G ssd
  • 3 воркера без доп дисков: 3vcpu, 6G ram, 15G ssd
Для мастеров будут закреплены IP:
  • 10.255.200.201
  • 10.255.200.202
  • 10.255.200.203
Для воркеров будут закреплены IP:
  • 10.255.200.204
  • 10.255.200.205
  • 10.255.200.206
  • 10.255.200.207
  • 10.255.200.208
  • 10.255.200.209
Скрин со списком виртуальных машин:

vm

Скрин с настройками статики для сети в maintenance mode:

net По аналогии настройки сети нужно провести для всех виртуальных машин.

Сборка кластера

Сейчас узлы запущены в maintenance mode из iso образа и для первичной заливки machineconfig нужно в явном виде указать флаг --insecure.

Про флаг --insecure:

Он нужен только для самой первой отправки machineconfig - на этом этапе узел ещё не имеет сертификатов и не может поднять mTLS-соединение с talosctl. После применения конфигурации узел переходит в защищённый режим, и все дальнейшие обращения к API идут только по mTLS с использованием сертификата из talosconfig.

Генерация конфига кластера

Перед генерацией конфига отдельно генерируем bundle с секретами кластера (сертификаты, токены):

talosctl gen secrets -o test-cluster/secrets.yaml

Секреты вынесены в отдельный файл специально: controlplane.yaml, worker.yaml и talosconfig можно пересоздавать сколько угодно раз (например, при смене эндпоинта или структуры патчей) на основе одного и того же secrets.yaml, не перевыпуская сертификаты и токены и не теряя доступ к уже развернутому кластеру.

talosctl gen config test-cluster https://10.255.200.201:6443 -o ./test-cluster --with-secrets test-cluster/secrets.yaml

  • talosctl gen config - команда генерации конфига
  • test-cluster - имя кластера
  • https://10.255.200.201:6443 - эндпоинт, в данном случае первый мастер (может быть адрес/домен балансировщика)
  • -o ./test-cluster - сохранение конфигов для доступа к кластеру
  • --with-secrets test-cluster/secrets.yaml - использовать ранее сгенерированный bundle секретов вместо генерации нового
Пример выполнения команды:
generating PKI and tokens
Created test-cluster/controlplane.yaml
Created test-cluster/worker.yaml
Created test-cluster/talosconfig
  • test-cluster/talosconfig - конфиг с секретом для управления узлами после бутстрапа
  • test-cluster/controlplane.yaml - конфигурация для мастер узлов
  • test-cluster/worker.yaml - конфигурация для воркер узлов
Про хранение секретов:
  • test-cluster/secrets.yaml - самый чувствительный файл во всей связке: в нём лежат корневые сертификаты и токены, из которых выводится всё остальное (talosconfig, machineconfig узлов). Его нужно хранить в надёжном месте (менеджер секретов/зашифрованное хранилище) и не коммитить в git в открытом виде
  • test-cluster/talosconfig и весь каталог test-cluster/ также стоит сохранить - без secrets.yaml повторная генерация конфига перевыпустит все сертификаты и токены заново, и доступ к уже развернутому кластеру по старому talosconfig будет потерян

Патчи machineconfig для узлов кластера

Общий патч для установки ОС на диск:

machine:
  install:
    disk: /dev/sda
    image: factory.talos.dev/installer/e142ceb080fb243141b5b6891cfcf0c60bc9430d69be0adf803999d2b62dc885:v1.13.7

Патч указывает на образ, который будет установлен на диск /dev/sda

Общие патчи для мастер- и воркер-нод с зависимостью от дополнительного диска:

  • patch-controlplane.yaml

machine:
  network:
    kubespan:
      enabled: true
      mtu: 1420
      advertiseKubernetesNetworks: false
cluster:
  discovery:
    enabled: true
  network:
    cni:
      name: none
  proxy:
    disabled: true
  • patch-worker-with-disk.yaml

machine:
  kernel:
    modules:
      - name: iscsi_tcp
  disks:
    - device: /dev/sdb
      partitions:
        - mountpoint: /var/lib/longhorn
  kubelet:
    extraMounts:
      - destination: /var/lib/longhorn
        type: bind
        source: /var/lib/longhorn
        options:
          - bind
          - rshared
          - rw
  network:
    kubespan:
      enabled: true
      mtu: 1420
      advertiseKubernetesNetworks: false
cluster:
  discovery:
    enabled: true
  network:
    cni:
      name: none
  proxy:
    disabled: true
  • patch-worker-without-disk.yaml

machine:
  network:
    kubespan:
      enabled: true
      mtu: 1420
      advertiseKubernetesNetworks: false
cluster:
  discovery:
    enabled: true
  network:
    cni:
      name: none
  proxy:
    disabled: true

В патчах для мастер- и воркер-нод заданы настройки для:

  • Kubespan - настройка wireguard mesh сети между узлами кластера
  • Отключение kube-proxy и установки дефолтного CNI (Flannel)
  • Для нод с доп диском дополнительно загружается модуль ядра iscsi_tcp - он нужен Longhorn для подключения томов по iSCSI
  • Для нод с доп диском описано монтирование доп диска и проброс его в контейнер kubelet для корректной работы
  • Точка монтирования /var/lib/longhorn подготовлена под будущую установку Longhorn CSI; установка и настройка Longhorn описаны в отдельном документе - README_LONGHORN.md

Патч для настроек сети - в качестве примера показан только для одного из мастеров, по аналогии такие патчи сделаны для всех узлов

machine:
  network:
    interfaces:
      - deviceSelector:
          hardwareAddr: "bc:24:11:80:a1:9b"
        addresses:
          - 10.255.200.201/24
        routes:
          - network: 0.0.0.0/0
            gateway: 10.255.200.1
        dhcp: false
    nameservers:
      - 9.9.9.9

Интерфейс выбирается через deviceSelector по MAC-адресу (hardwareAddr), а не по имени (eth0) - привязка к MAC не зависит от порядка обнаружения интерфейсов и не сломается при добавлении/замене сетевых карт. MAC-адрес каждой виртуальной машины можно посмотреть в настройках сетевого устройства в Proxmox VE.

Получение MAC-адреса через talosctl:

Пока узел работает в maintenance mode, MAC-адреса его интерфейсов можно узнать напрямую через API Talos (столбец HW ADDR в выводе):

talosctl get links -n 10.255.200.201 --insecure

На уже настроенном узле команда та же, но без --insecure и с указанием эндпоинта:

talosctl get links -n 10.255.200.201 -e 10.255.200.201

Вывод содержит все интерфейсы, включая служебные (lo, kubespan, siderolink и т.д.) - нужен физический интерфейс типа ether (обычно eth0).

Применение конфигурации к узлам кластера

Экспорт переменной TALOSCONFIG для работы с talosctl:

export TALOSCONFIG=$(pwd)/test-cluster/talosconfig

Применение machineconfig для всех узлов кластера с патчами

talosctl apply-config \
--insecure -n 10.255.200.201 \
--file ./test-cluster/controlplane.yaml \
--config-patch @patches/patch-install.yaml \
--config-patch @patches/patch-controlplane.yaml \
--config-patch @patches/patch-net-master-1.yaml

Остальные узлы по аналогии, нужно только указать соответствующие узлу и роли патчи

После применения machineconfig нужно выполнить bootstrap на первом мастере, адрес которого был указан при инициализации конфига

talosctl bootstrap -n 10.255.200.201 -e 10.255.200.201

Проверить, что кластер подает признаки жизни командами

talosctl etcd members -n 10.255.200.201 -e 10.255.200.201,10.255.200.202,10.255.200.203
talosctl health -n 10.255.200.201 -e 10.255.200.201,10.255.200.202,10.255.200.203
talosctl get members -n 10.255.200.201 -e 10.255.200.201,10.255.200.202,10.255.200.203
Про флаг -e:

Указывает конечные точки API Talos, к которым обращается talosctl. Для отказоустойчивости стоит перечислять все мастера через запятую (как в примерах выше) либо использовать адрес балансировщика/VIP перед мастерами - тогда потеря одного мастера не блокирует управление кластером.

Получить и добавить в переменную kubeconfig:

talosctl kubeconfig ./kubeconfig -n 10.255.200.201 -e 10.255.200.201,10.255.200.202,10.255.200.203
export KUBECONFIG=$(pwd)/kubeconfig

Установка CNI cilium в кластер через helm

cilium-values.yaml

ipam:
  mode: kubernetes

routingMode: tunnel
tunnelProtocol: vxlan
autoDirectNodeRoutes: false

kubeProxyReplacement: true
k8sServiceHost: localhost
k8sServicePort: 7445

bpf:
  masquerade: true

cgroup:
  autoMount:
    enabled: false
  hostRoot: /sys/fs/cgroup

securityContext:
  capabilities:
    ciliumAgent:
      - CHOWN
      - KILL
      - NET_ADMIN
      - NET_RAW
      - IPC_LOCK
      - SYS_ADMIN
      - SYS_RESOURCE
      - DAC_OVERRIDE
      - FOWNER
      - SETGID
      - SETUID
    cleanCiliumState:
      - NET_ADMIN
      - SYS_ADMIN
      - SYS_RESOURCE

hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true

MTU: 1370
Ключевые моменты конфигурации:
  • routingMode: tunnel + tunnelProtocol: vxlan - трафик между подами инкапсулируется в VXLAN
  • kubeProxyReplacement: true с k8sServiceHost: localhost и k8sServicePort: 7445 - cilium заменяет kube-proxy (он отключен в патчах) и обращается к kube-apiserver через локальный KubePrism-балансировщик Talos на порту 7445
  • cgroup.autoMount.enabled: false - Talos уже монтирует cgroup fs, повторное монтирование не требуется
  • MTU: 1370 - MTU Kubespan (1420) минус накладные расходы VXLAN-инкапсуляции (50 байт)

Подключение репозитория helm для cilium и установка CNI:

helm repo add cilium https://helm.cilium.io/
helm repo update cilium
helm install cilium cilium/cilium --version 1.19.6 --namespace kube-system -f cilium-values.yaml

Проверить доступность узлов кластера:

kubectl get node

Доступ к Hubble UI:

В cilium-values.yaml включены Hubble, Hubble Relay и Hubble UI (hubble.enabled, hubble.relay.enabled, hubble.ui.enabled) - web-интерфейс для наблюдения за сетевыми потоками между подами. Наружу UI не опубликован; для доступа можно пробросить порт:

kubectl -n kube-system port-forward svc/hubble-ui 12000:80

После этого UI доступен на http://localhost:12000 - в нём видна карта сервисов и сетевые потоки в реальном времени с вердиктами (forwarded/dropped).

Сброс кластера

Внимание: операция необратима и стирает данные на диске узла, включая установленную ОС и все данные приложений (в т.ч. на дисках под Longhorn).

Если нужно вернуть узел(ы) обратно в maintenance mode и стереть данные:

talosctl reset -n 10.255.200.201 -e 10.255.200.201 --graceful=false --reboot
  • --graceful=false - пропустить graceful-выход из etcd/кластера (нужно, если кластер уже неработоспособен)
  • --reboot - перезагрузить узел после сброса, чтобы он снова загрузился в maintenance mode

Команду нужно выполнить отдельно для каждого узла кластера, который требуется сбросить - за один вызов сбрасывается только узел, указанный в -n.

S
Description
No description provided
Readme
325 KiB
Languages
Markdown 100%