346 lines
19 KiB
Markdown
346 lines
19 KiB
Markdown
# Оглавление
|
||
- [Введение](#введение)
|
||
- [Что такое Talos OS](#что-такое-talos-os)
|
||
- [Подготовка к развороту кластера](#подготовка-к-развороту-кластера)
|
||
- [Подготовка schematic.yaml для генерации образа](#подготовка-schematicyaml-для-генерации-образа-через-публичныйприватный-image-factory)
|
||
- [Отправка schematic.yaml, получение и скачивание образа](#отправка-schematicyaml-в-сторону-image-factory-получение-id-образа-и-скачивание-образа)
|
||
- [Подготовка виртуальных машин](#подготовка-виртуальных-машин)
|
||
- [Сборка кластера](#сборка-кластера)
|
||
- [Генерация конфига кластера](#генерация-конфига-кластера)
|
||
- [Патчи machineconfig для узлов кластера](#патчи-machineconfig-для-узлов-кластера)
|
||
- [Применение конфигурации к узлам кластера](#применение-конфигурации-к-узлам-кластера)
|
||
- [Сброс кластера](#сброс-кластера)
|
||
|
||
# Введение
|
||
|
||
## Что такое 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` ([инструкция по установке](https://www.talos.dev/latest/talos-guides/install/talosctl/)), `kubectl` и `helm`.
|
||
|
||
##### Про пути в командах:
|
||
Все команды в этом документе выполнялись из директории `examples/` - именно там лежат `schematics/`, `patches/`, `test-cluster/`, `images/` и `cilium-values.yaml`. Перед копированием команд нужно перейти в эту директорию (`cd examples`).
|
||
|
||
## Подготовка schematic.yaml для генерации образа через публичный/приватный Image Factory
|
||
```yaml
|
||
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 драйверов
|
||
|
||
## Отправка 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 образа и информацией об установленных расширениях:
|
||
```json
|
||
{
|
||
"id": "c0ad57b8eb60094dd2ebed394ae5e9dfb279c7661d6c1de5944ede4c16cbfc9d",
|
||
"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/c0ad57b8eb60094dd2ebed394ae5e9dfb279c7661d6c1de5944ede4c16cbfc9d/v1.13.7/metal-amd64.iso"`
|
||
|
||
- `c0ad57b8eb60094dd2ebed394ae5e9dfb279c7661d6c1de5944ede4c16cbfc9d` - 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`
|
||
|
||
##### Скрин со списком виртуальных машин:
|
||

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

|
||
По аналогии настройки сети нужно провести для всех виртуальных машин.
|
||
|
||
# Сборка кластера
|
||
|
||
|
||
Сейчас узлы запущены в 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 для узлов кластера
|
||
### Общий патч для установки ОС на диск:
|
||
```yaml
|
||
machine:
|
||
install:
|
||
disk: /dev/sda
|
||
image: factory.talos.dev/installer/c0ad57b8eb60094dd2ebed394ae5e9dfb279c7661d6c1de5944ede4c16cbfc9d:v1.13.7
|
||
```
|
||
#### Патч указывает на образ, который будет установлен на диск `/dev/sda`
|
||
|
||
### Общие патчи для мастер- и воркер-нод с зависимостью от дополнительного диска:
|
||
- #### patch-controlplane.yaml
|
||
```yaml
|
||
machine:
|
||
network:
|
||
kubespan:
|
||
enabled: true
|
||
mtu: 1420
|
||
advertiseKubernetesNetworks: true
|
||
cluster:
|
||
discovery:
|
||
enabled: true
|
||
network:
|
||
cni:
|
||
name: none
|
||
proxy:
|
||
disabled: true
|
||
```
|
||
- #### patch-worker-with-disk.yaml
|
||
```yaml
|
||
machine:
|
||
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: true
|
||
cluster:
|
||
discovery:
|
||
enabled: true
|
||
network:
|
||
cni:
|
||
name: none
|
||
proxy:
|
||
disabled: true
|
||
```
|
||
- #### patch-worker-without-disk.yaml
|
||
```yaml
|
||
machine:
|
||
network:
|
||
kubespan:
|
||
enabled: true
|
||
mtu: 1420
|
||
advertiseKubernetesNetworks: true
|
||
cluster:
|
||
discovery:
|
||
enabled: true
|
||
network:
|
||
cni:
|
||
name: none
|
||
proxy:
|
||
disabled: true
|
||
```
|
||
#### В патчах для мастер- и воркер-нод заданы настройки для:
|
||
- Kubespan - настройка wireguard mesh сети между узлами кластера
|
||
- Отключение kube-proxy и установки дефолтного CNI (Flannel)
|
||
- Для нод с доп диском описано монтирование доп диска и проброс его в контейнер kubelet для корректной работы
|
||
- Точка монтирования `/var/lib/longhorn` подготовлена под будущую установку Longhorn CSI; сама установка и настройка Longhorn в этом документе не описывается
|
||
|
||
### Патч для настроек сети - в качестве примера показан только для одного из мастеров, по аналогии такие патчи сделаны для всех узлов
|
||
```yaml
|
||
machine:
|
||
network:
|
||
interfaces:
|
||
- interface: eth0
|
||
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
|
||
```
|
||
|
||
## Применение конфигурации к узлам кластера
|
||
#### Экспорт переменной TALOSCONFIG для работы с talosctl:
|
||
`export TALOSCONFIG=$(pwd)/test-cluster/talosconfig`
|
||
|
||
### Применение machineconfig для всех узлов кластера с патчами
|
||
```sh
|
||
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`
|
||
|
||
#### Проверить, что кластер подает признаки жизни командами
|
||
```sh
|
||
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:
|
||
```sh
|
||
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
|
||
```yaml
|
||
ipam:
|
||
mode: kubernetes
|
||
|
||
routingMode: native
|
||
ipv4NativeRoutingCIDR: 10.244.0.0/16
|
||
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: 1420
|
||
```
|
||
|
||
#### Подключение репозитория helm для cilium и установка CNI:
|
||
```sh
|
||
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
|
||
```
|
||
|
||
#### Проверить доступность узлов кластера:
|
||
```sh
|
||
kubectl get node
|
||
```
|
||
|
||
## Сброс кластера
|
||
##### Внимание: операция необратима и стирает данные на диске узла, включая установленную ОС и все данные приложений (в т.ч. на дисках под Longhorn).
|
||
|
||
#### Если нужно вернуть узел(ы) обратно в maintenance mode и стереть данные:
|
||
```sh
|
||
talosctl reset -n 10.255.200.201 -e 10.255.200.201 --graceful=false --reboot
|
||
```
|
||
- `--graceful=false` - пропустить graceful-выход из etcd/кластера (нужно, если кластер уже неработоспособен)
|
||
- `--reboot` - перезагрузить узел после сброса, чтобы он снова загрузился в maintenance mode
|
||
|
||
Команду нужно выполнить отдельно для каждого узла кластера, который требуется сбросить - за один вызов сбрасывается только узел, указанный в `-n`.
|