Наша команда добавила к себе в список доступных для установки новую ОС — 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 и мгновенным деплоем.

Выбрать

Преимущества Talos Linux

  1. Иммутабельность: Корневая файловая система доступна только для чтения после загрузки, что обеспечивает целостность системы и предотвращает несанкционированные изменения.

  2. Минимализм и безопасность: В системе присутствует только необходимый минимум компонентов для работы Kubernetes, что снижает количество потенциальных уязвимостей.

  3. Управление через API: Взаимодействие с системой осуществляется исключительно через gRPC API, защищённый mTLS, что обеспечивает безопасное и централизованное управление.

  4. Оптимизация под 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) . Для создания образа через него нужно выполнить следующие шаги:

  1. Перейдите на factory.talos.dev.

  2. Выберите параметры:

    • Версия Talos: например, v1.10.0.

    • Архитектура: amd64 или arm64.

    • Платформа: metal, sbc, vm и т. д.

    • Цель: metal, sbc, vm и т. д.

  3. Добавьте системные расширения: отметьте необходимые, например, siderolabs/gvisor. 

  4. Настройте дополнительные параметры ядра: при необходимости добавьте или удалите параметры загрузки ядра.

  5. Сгенерируйте схему: нажмите “Generate” для создания схемы.

  6. Скачайте образы: после генерации схемы появятся ссылки для загрузки соответствующих образов (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
Арендуйте выделенный или виртуальный сервер с ОС Talos Linux и мгновенным деплоем.

Выбрать

Комментарии (1)


  1. vasyakrg
    18.07.2025 23:25

    Я вот тут как раз написал утилиту для работы с манифестами https://github.com/vasyakrg/talostpl и последующий сетап на подготовленные хосты