Поднимаем кластер k8s на Talos Linux

от автора

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

Выбрать


ссылка на оригинал статьи https://habr.com/ru/articles/929018/