Наша команда добавила к себе в список доступных для установки новую ОС — Talos Linux. В этой статье мы постараемся рассказать, что такое Talos Linux, и в чем его удобство перед остальными OS для кластера Kubernetes. Дополнительно мы развернем тестовый кластер, на который задеплоим наше первое приложение!
Введение
Так что же из себя представляет «Talos»?
Talos Linux — это специализированная, иммутабельная и минималистичная операционная система, разработанная компанией Sidero Labs. Ее основная цель — предоставить безопасную и управляемую платформу для запуска кластеров Kubernetes. В отличие от традиционных дистрибутивов Linux, Talos исключает такие компоненты, как оболочка (shell), SSH-сервер, пакетные менеджеры и другие утилиты, что значительно снижает поверхность атаки и упрощает управление системой. Все взаимодействие с Talos осуществляется через API, используя утилиту talosctl.
Разработанная компанией Sidero Labs (основателями проекта Talos), она кардинально меняет подход к управлению инфраструктурой K8s, устраняя множество проблем традиционных ОС.
Серверы с ОС Talos Linux |
Преимущества Talos Linux
Иммутабельность: Корневая файловая система доступна только для чтения после загрузки, что обеспечивает целостность системы и предотвращает несанкционированные изменения.
Минимализм и безопасность: В системе присутствует только необходимый минимум компонентов для работы Kubernetes, что снижает количество потенциальных уязвимостей.
Управление через API: Взаимодействие с системой осуществляется исключительно через gRPC API, защищённый mTLS, что обеспечивает безопасное и централизованное управление.
Оптимизация под Kubernetes: Talos предназначен исключительно для запуска Kubernetes и его компонентов, что делает систему более стабильной и предсказуемой.
Как устроен деплой OC в HOSTKEY?
Talos имеет особый способ загрузки. При запуске OC она не устанавливается на диск, а запускается в RAM нашего сервера. По сути, это LIVE CD, который в дальнейшем устанавливает саму систему на диск после применения конфига.
По причине того, что система не устанавливается на диск сразу, мы решили облегчить деплой данной системы на сервер с помощью PXE. Ранее мы уже публиковали статью про Foreman и именно благодаря ему при заказе сервера с Talos вы получаете предзагруженный образ, с которым сможете работать практически сразу после заказа! Инструмент очень интересный, хоть и кажется по началу довольно сложным.
Конфиг под PXE и UEFI системы выглядит следующим образом:
PXE (Legacy):
<%#
kind: PXELinux
name: PXELinux_Talos
model: ProvisioningTemplate
%>
DEFAULT menu
MENU TITLE Booting into default OS installer (ESC to stop)
TIMEOUT 100
ONTIMEOUT <%= @host.operatingsystem.name %>
LABEL <%= @host.operatingsystem.name %>
KERNEL live-master/vmlinuz_talos talos.platform=metal slab_nomerge pti=on
MENU LABEL Default install Hostkey BV image <%= @host.operatingsystem.name %>
APPEND initrd=live-master/initramfs_talos.xz
UEFI:
<%#
kind: PXEGrub2
name: Talos_Linux_EFI
model: ProvisioningTemplate
%>
set default=0
set timeout=<%= host_param('loader_timeout') || 5 %>
menuentry '<%= template_name %>' {
linuxefi (tftp,<%= host_param('medium_ip_tftp') %>)/live-master/vmlinuz_talos talos.platform=metal slab_nomerge pti=on
initrdefi (tftp,<%= host_param('medium_ip_tftp') %>)/live-master/initramfs_talos.xz
}
Как вы могли заметить, у нас имеется пара параметров, и два файла загрузки (vmlinuz, initramfs). Дело в том, что при PXE загрузке мы решили использовать не ISO образ, а именно файл ядра и RAM FS. Дополнительно мы использовали параметры (talos.platform=metal slab_nomerge pti=on) которые указаны в документации разработчика для загрузки системы через PXE. Дополнительно о параметрах вы можете ознакомиться на сайте разработчика.
Подготовка к развертыванию кластера
1. Установка через talosctl
talosctl — это CLI-инструмент для взаимодействия с Talos API. Установите его с помощью следующей команды:
curl -sL https://talos.dev/install | sh
Убедитесь, что версия talosctl соответствует версии Talos Linux, которую вы планируете использовать.
В рамках статьи о развертывании кластера Kubernetes на Talos Linux также важно подробно рассмотреть сервис Image Factory — официальный инструмент от Sidero Labs для создания и загрузки кастомизированных образов Talos Linux. Он позволяет адаптировать образы под конкретные задачи и инфраструктуру, обеспечивая гибкость и удобство в управлении кластером.
Image Factory — это веб-интерфейс и API для генерации кастомизированных загрузочных образов Talos Linux. Он позволяет:
Выбирать версию Talos Linux и архитектуру (x86_64 или ARM64).
Добавлять системные расширения (например, siderolabs/gvisor, siderolabs/zfs, siderolabs/tailscale).
Настраивать дополнительные параметры ядра (kernel args).
Создавать образы в различных форматах: ISO, PXE, дисковые образы, установочные контейнеры.
Сервис поддерживает различные архитектуры (x86_64, ARM64) и платформы, включая bare-metal, облачные провайдеры (AWS, GCP, Azure) и одноплатные компьютеры (например, Raspberry Pi) . Для создания образа через него нужно выполнить следующие шаги:
Перейдите на factory.talos.dev.
-
Выберите параметры:
Версия Talos: например, v1.10.0.
Архитектура: amd64 или arm64.
Платформа: metal, sbc, vm и т. д.
Цель: metal, sbc, vm и т. д.
Добавьте системные расширения: отметьте необходимые, например, siderolabs/gvisor.
Настройте дополнительные параметры ядра: при необходимости добавьте или удалите параметры загрузки ядра.
Сгенерируйте схему: нажмите “Generate” для создания схемы.
Скачайте образы: после генерации схемы появятся ссылки для загрузки соответствующих образов (ISO, PXE и т. д.).
Рецепт приготовления
Изначально передо нами стояла задача развернуть кластер на трех Bare-metal серверах (2 мастер и 1 воркер нода). Постараемся максимально подробно отразить процесс подготовки кластера. Уточним заранее, что данный кластер тестовый, и предназначен только для подтверждения, что поднять кластер на Talos очень легко (Спасибо разработчикам!). Если вы хотите продовый кластер, то обязательно придерживайтесь кворума!
Для реализации мы решил взять сервер в конфигурации bm.v1-big. Можно взять конфигурацию и на одном диске, но на момент написания статьи таких не осталось в наличии.

Выбираем в разделе Операционная система нашу ОС, и делаем имя хоста таким, как нам будет удобно. В нашем случае у нас будет три хоста: m-01, m-02, w-01. На самом деле можем поставить любое имя, так как внутри системы оно будет другое.

Дополнительно если мы зайдем в KVM/IPMI Viewer, то увидим картину, как на скрине ниже. На нем мы видим статус STAGE. Он отображает текущий статус системы. Сейчас мы видим статус Maintenance так как только загрузились с образа. Дополнительно мы наблюдаем дополнительный индикатор Ready — по нему мы ориентируемся готова ли система к дальнейшим действиям.

После того как мы закажем все три сервера начинается самое интересное: настройка. Для взаимодействия с OS нам необходима утилита talosctl. Скачать ее (как и образ системы) можно в официальном GitHub репозитории во вкладке Release.
Приступим!
Для начала генерируем для удобства отдельно secret файл. В нем будут содержаться сертификаты для взаимодействия с кластером.
1. Генерация секретов
Создайте файл secrets.yaml, содержащий сертификаты и ключи для кластера:
talosctl gen secrets --output-file secrets.yaml
После чего нам необходимо создать базовые config файлы. Для примера возьмем нашу первую машину (m-01), и выполним следующую команду:
talosctl gen config --with-secrets ./secrets.yaml us-k8s https://10.10.10.10:6443
Важное уточнение: наш пул адресов в статье будет с 10.10.10.10-11 (m-01 и m-02) до 10.10.10.12 (w-01), вы можете использовать любые IP, главное, чтобы между ними была связанность.
После выполнения команды в нашей директории появится три файла: controlplane.yaml, worker.yaml, talosconfig.
Далее нам необходимо создать патчи для файла controlplane.yaml. Патч-файл, в котором мы размещаем основную информацию о ноде встраивается в основной конфиг, для того чтобы создать измененную конфигурацию (которая в последующем будет использоваться нашими нодами. Первое что нам нужно узнать, чтобы составить правильный файл патча — какой у нас сетевой интерфейс и диск. Узнать два этих параметра можно командами:
talosctl -n 10.10.10.10 -e 10.10.10.10 get disks –insecure
в результате мы увидим следующее:
NODE NAMESPACE TYPE ID VERSION SIZE READ ONLY TRANSPORT ROTATIONAL WWID MODEL SERIAL
10.10.10.10 runtime Disk loop0 1 4.1 kB true
10.10.10.10 runtime Disk loop1 1 74 MB true
10.10.10.10 runtime Disk sda 1 960 GB false sata naa.5002538c409b0b6a SAMSUNG MZ7LM960
10.10.10.10 runtime Disk sdb 1 960 GB false sata naa.5002538c4070a76f SAMSUNG MZ7LM960
Нас интересует sda диск, на него установится система, если мы пропишем его в патче. Можем выбрать и sdb, но мы не будем так делать.
talosctl -n 10.10.10.10 -e 10.10.10.10 get links –insecure
В выводе мы можем наблюдать все интерфейсы, которые нам доступны, но нас интересует один единственный в статусе up (именно он будет прописан в патче). Дополнительно советуем убедиться по MAC-адресу наш ли это интерфейс.
NODE NAMESPACE TYPE ID VERSION TYPE KIND HW ADDR OPER STATE LINK STATE
10.10.10.10 network LinkStatus dummy0 1 ether dummy 11:22:33:44:55:66 down false
10.10.10.10 network LinkStatus enp2s0f0 2 ether 11:22:33:44:55:66 down false
10.10.10.10 network LinkStatus enp2s0f1 3 ether 11:22:33:44:55:66 up true
10.10.10.10 network LinkStatus lo 2 loopback 00:00:00:00:00:00 unknown true
10.10.10.10 network LinkStatus sit0 1 sit sit 00:00:00:00:00:00 down false
В принципе на этом все. Мы узнали параметры железа нашей машины, и можем приступать к написанию патча для m-01 ноды. Ниже приведен пример, который мы написали:
machine:
type: controlplane
network:
hostname: m-01
interfaces:
- interface: enp2s0f1
addresses:
- 10.10.10.10/24
routes:
- network: 0.0.0.0/0
gateway: 10.10.10.1
nameservers:
- 8.8.8.8
time:
disabled: false
servers:
- ntp.ix.ru
bootTimeout: 2m0s
install:
disk: /dev/sda #Прописываем сюда тот диск что получили из вывода
image: factory.talos.dev/installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.9.5 #https://factory.talos.dev/
wipe: true
extraKernelArgs:
- talos.platform=metal #Подробнее о параметрах на сайте разработчика
cluster:
controlPlane:
endpoint: https://10.10.10.10:6443 #Тут IP адрес нашей ноды
network:
dnsDomain: cluster.local
podSubnets:
- 10.64.0.0/16
serviceSubnets:
- 10.128.0.0/16
Собственно, вот мы написали патч, что далее? А далее мы должны соединить патч с controlplane файлом. На выходе мы получим запатченный .yaml файл, который уже сможем применить на нашу первую ноду. Делаем это следующей командой:
talosctl machineconfig patch controlplane.yaml --patch @m-01-patch.yaml -o m-01-patched.yaml
Теперь с уверенностью можем применить пропатченный файл к нашей первой машине. Делаем это командой:
talosctl apply-config -n 162.120.19.9 -e 162.120.19.9 --file ./m-01-patched.yaml --insecure
После чего смотрим в VNC консоль. В процессе установки системы мы увидим следующее поведение машины: STAGE машины изменится на Installing, после чего машина перезагрузится. После перезагрузки мы увидим STAGE Booting. В этот момент нам нужно смотреть логи пока не увидим строку с предложением ввести команду talosctl bootstrap. Выглядит это примерно так:

Когда увидели эту запись в логах- пишем следующее:
talosctl bootstrap --nodes 10.10.10.10 -e 10.10.10.10 --talosconfig ./talosconfig
После выполнения команды STAGE изменится на Running. Дополнительно появится состояние компонентов APISERVER, CONTROLLER-MANAGER, SCHEDULER. Выглядит это примерно так:

Дополнительно мы наблюдаем название кластера, кол-во машин в кластере, и то что у READY стоит флаг False. Наш кластер не станет READY True пока мы не добавим еще одну мастер ноду. (Можно поднять контролплейн и на одной мастер ноде, но в данной статье мы разбираем именно несколько мастер нод). А вообще правильно делать кворум (но наша статья затрагивает основу).
Важное уточнение: команда talosctl bootstrap выполняется только на первой мастер ноде в кластере, на остальных ее выполнять не нужно!
Теперь очередь второй мастер ноды. По сути, мы выполняем те же действия что были описаны выше, главное проверить параметры в патче. Пример патча:
machine:
type: controlplane
network:
hostname: m-02
interfaces:
- interface: enp2s0f0
addresses:
- 10.10.10.11/24
routes:
- network: 0.0.0.0/0
gateway: 10.10.10.1
nameservers:
- 8.8.8.8
time:
disabled: false
servers:
- ntp.ix.ru
bootTimeout: 2m0s
install:
disk: /dev/sda
image: factory.talos.dev/installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.9.5
wipe: true
extraKernelArgs:
- talos.platform=metal
cluster:
controlPlane:
endpoint: https://10.10.10.10:6443
network:
dnsDomain: cluster.local
podSubnets:
- 10.64.0.0/16
serviceSubnets:
- 10.128.0.0/16
Совмещаем патч с controlplane командой:
talosctl machineconfig patch controlplane.yaml --patch @m-02-patch.yaml -o m-02-patched.yaml
И применяем получившийся конфиг к серверу:
talosctl apply-config -n 10.10.10.11 -e 10.10.10.11 --file ./m-02-patched.yaml --insecure
В процессе установки машина так же перезагрузится, после чего отобразит информацию о кластере (READY будет в True).

Теперь мы можем получить kubeconf файл. Для этого мы пропишем в нашем talosconfig файле ноды и эндпоинты:
talosctl config node 10.10.10.10 10.10.10.11 --talosconfig ./talosconfig
talosctl config endpoint 10.10.10.10 10.10.10.11 --talosconfig ./talosconfig
(После выполнения этих двух команд мы можем не прописывать каждый раз -n и -e чтобы указывать ноды и эндпоинты. Пример:
До выполнения:
talosctl stats -n 10.10.10.10 10.10.10.11 -e 10.10.10.10 10.10.10.11 stats –talosconfig ./talosconfig
После выполнения:
talosctl stats --talosconfig ./talosconfig
Рекомендация: если вы любите зайти посмотреть, что происходит с кластером через KVM (не надо так!), то используйте команду:
talosctl dashboard --talosconfig ./talosconfig . Она отобразит ту же самую информацию, и позволит вам переключаться между нодами!
И теперь получаем наш заветный кубконф:
talosctl kubeconfig kubeconf -e 10.10.10.10 -n 10.10.10.10 --talosconfig ./talosconfig
Обратите внимание: доступ к кластеру (эндпоинт) идет через первую мастер ноду, т.к у нас не настроен vip.
Теперь добавим первую воркер ноду! Мы составили следующий патч:
machine:
type: worker
network:
hostname: w-01
interfaces:
- interface: enp2s0f1
addresses:
- 80.209.242.166/25
routes:
- network: 0.0.0.0/0
gateway: 80.209.242.129
nameservers:
- 8.8.8.8
time:
disabled: false
servers:
- ntp.ix.ru
bootTimeout: 2m0s
install:
disk: /dev/sda
image: factory.talos.dev/installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.9.5
wipe: true
extraKernelArgs:
- talos.platform=metal
После его применения на сервер (аналогично командам выше по статье) получаем следующее:

root@taxonein:~/talos# kubectl get nodes --kubeconfig ./kubeconf
NAME STATUS ROLES AGE VERSION
m-01 Ready control-plane 7h24m v1.33.0
m-02 Ready control-plane 4h24m v1.33.0
w-01 Ready <none> 48m v1.33.0
По выводу видим, что наша воркер нода на месте. На этом подготовка кластера завершена, и мы можем использовать свой кластер для деплоя.
Пример деплоя
В качестве сервиса для теста мы решили использовать простой nginx, который будет выводить содержимое html файла.
Структура следующая:
.
├── index.html
├── kustomization.yaml
├── namespace.yaml
├── nginx-deployment.yaml
└── nginx-service.yaml
Подробнее по содержимому. Самый главный файл: kustomization.yaml. Именно в нем содержится список остальных yaml файлов, которые используются для деплоя. Его содержимое:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- nginx-deployment.yaml
- nginx-service.yaml
configMapGenerator:
- name: nginx-index-html
files:
- index.html
namespace: nginx
Мы можем наблюдать в списке ресурсов основные конфиги, которые будут использоваться для деплоя. Пройдемся по ним подробнее:
В файле namespace.yaml мы указали следующее:
apiVersion: v1
kind: Namespace
metadata:
name: nginx
Указывать namespace отдельным файлом на деле показалось нам довольно хорошей практикой, и так довольно удобно управлять всеми деплоями, особенно если их у вас больше 10.
В файле nginx-deployment.yaml мы указали такую структуру:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
volumes:
- name: html-volume
configMap:
name: nginx-index-html
И в файле nginx-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
По сервису все довольно легко. Доступ на этот сервис будет по 30080 порту через ip ноды (в нашем случае m-01).
Теперь деплоим это в куб командой:
kubectl --kubeconfig ./kubeconf apply -k .
В выводе мы получим примерно следующее:
namespace/nginx created
configmap/nginx-index-html-g8kh5d4dm9 created
service/nginx created
deployment.apps/nginx created
После чего следующей командой узнаем ip нашей ноды m-01 (если забыли):
kubectl --kubeconfig ./kubeconf get nodes -o wide
И переходим по данному ip в браузере, добавив порт, который указали в nginx-service.yaml (30080). Получаем ссылку: http://10.10.10.10:30080. При переходе мы видим содержимое нашего html файла:

После того как проверили, что все работает, удаляем наш деплой одной командой:
kubectl --kubeconfig ./kubeconf delete -k .
Итог
Несмотря на первоначальное впечатление сложности, Talos Linux на практике оказывается одной из самых удобных и простых систем для развертывания Kubernetes-кластеров. Его ключевое преимущество — минимализм и готовность к работе «из коробки».
В отличие от традиционных дистрибутивов, здесь нет необходимости вручную настраивать плейбуки для отключения лишних сервисов или собирать кастомные образы «идеальной системы». Talos предоставляет готовое решение, сочетающее в себе скорость, простоту и иммутабельность.
Попробовав Talos в production-среде, вы вряд ли захотите возвращаться к классическим подходам — настолько убедительным оказывается опыт работы с этой системой.
А каково ваше мнение о Talos OS?
Серверы с ОС Talos Linux |
vasyakrg
Я вот тут как раз написал утилиту для работы с манифестами https://github.com/vasyakrg/talostpl и последующий сетап на подготовленные хосты