Привет всем 👋,

Не так давно моё внимание привлёк достаточно интересный дистрибутив — Talos Linux.

Если коротко, это операционная система, спроектированная специально под Kubernetes.

Поддерживается практически на всех платформах: от облаков до bare metal. Взаимодействие с системой происходит через API-интерфейс, так как из дистрибутива удалены SSH и shell.

Что касается использования в продакшене, существует активно развивающееся сообщество, которое делится опытом применения Talos в крупных инсталляциях.

Собственно, эту заметку я решил посвятить гайду по развёртыванию K8s на Talos в виртуальной среде VMware.

Подготовка

Утилиты

Для работы потребуются следующие CLI-инструменты:

  • govc — взаимодействие с VMware ESXi/vCenter.
  • talosctl — управление узлами на Talos Linux.
  • kubectl — управление кластером Kubernetes.
  • helm — пакетный менеджер для Kubernetes.

Пример файловой структуры

Дополнительно, можно создать новый проект в Gitlab или просто на файлухе, структуру под хранения конфигов кастеров.

У меня организовано примерно так:

$ tree Git/talos/
.
├── Clusters
│   ├── SamleCluster
│   │   └── mconf
│   │       ├── patch.common.yaml
|   |       └── wrk.patch.yaml
│   └── SandboxCluster
│       ├── kubeconfig
│       ├── mconf
│       │   ├── controlplane.1.yaml
│       │   ├── controlplane.2.yaml
│       │   ├── controlplane.3.yaml
│       │   ├── patch.common.yaml
│       │   ├── worker.1.yaml
│       │   └── worker.2.yaml
│       ├── secrets.yaml
│       └── talosconfig
├── iSO
│   └── vmware-amd64.ova
├── manifests
│   └── csi
│       ├── 01-vsphere-cloud-controller-manager-1-31.yaml
│       ├── 02-namespace.yaml
│       ├── 03-vsphere-csi-driver.yaml
│       ├── 04-vsphere-sc.yaml
│       └── csi-vsphere.conf
└── README.md

Образ системы

На официальном сайте можно найти ссылки на готовые образы.

Также доступен генератор factory.talos.dev для создания кастомных образов с расширениями. В нашем случае подойдёт готовый OVA-образ с vmtoolsd.

Пример установки переменных окружения для подключения к vCenter:

export GOVC_URL=vc02.mydomain.local
export GOVC_USERNAME=sysadmin
export GOVC_DATACENTER='HO'
export GOVC_DATASTORE='NVME_VOL01'
export GOVC_RESOURCE_POOL='*/Resources'
export GOVC_PASSWORD='mypass'
export GOVC_INSECURE=true   # Исключить проверку сертификата 

Загрузка образа:

export TALOS_VERSION="v1.10.3"
curl -L -O https://factory.talos.dev/image/903b2da78f99adef03cbbd4df6714563823f63218508800751560d3bc3557e40/${TALOS_VERSION}/vmware-amd64.ova

Создание и импорт библиотеки:

govc library.create TalosLinux
govc library.import -n talos-${TALOS_VERSION} TalosLinux

Готовим конфиги

Создаём patch-файл конфигурации mc.patch.yaml с ручными настройками сети (без DHCP), инициализацией времени и VIP.

# vim mc.patch.yaml
---
machine:
#  env:
#    http_proxy: 'squid.mydomain.local:8080'
#    https_proxy: 'squid.mydomain.local:8080'
#    no_proxy: "127.0.0.1,10.8.190.0/24,.mydomain.local,192.168.10.0/24"
  time:
    bootTimeout: 2m
    servers:
      - 10.8.190.13

  network:
    hostname: snd-cp01
    interfaces:
      - interface: eth0 # The interface name.
        addresses:
          - 10.8.190.68/24
        routes:
          - network: 0.0.0.0/0 # The route's network.
            gateway: 10.8.190.40 # The route's gateway.
        dhcp: false
        vip:
          ip: 10.8.190.73

    nameservers:
      - 10.8.190.13

    extraHostEntries:
      - ip: 10.8.190.68
        aliases:
          - snd-cp01
      - ip: 10.8.190.69
        aliases:
          - snd-cp02
      - ip: 10.8.190.70
        aliases:
          - snd-cp03
      - ip: 10.8.190.71
        aliases:
          - snd-wrk01
      - ip: 10.8.190.72
        aliases:
          - snd-wrk02

cluster:
  clusterName: sandbox
  network:
    dnsDomain: mydomain.local
    podSubnets: 
      - 10.244.0.0/16
    serviceSubnets:
      - 10.96.0.0/12
  discovery:
    enabled: false

Здесь указываем локальные адреса для DNS/NTP служб, статические сетевые настройки интерфейса. Дополнительно добавил в локальные dns-записи адреса нод. А Также определили базовый пресет для кластера.

В проде рекомендуется начать, с создания файла секретов:

talosctl gen secrets

Генерация базовых конфигураций:

talosctl gen config --with-secrets secrets.yaml sandbox https://10.8.190.73:6443 --config-patch @mc.patch.yaml

Результатом выполнения команды будет,

  • controlplane.yaml/worker.yaml - Конфигурация для controlplane/worker узлов,
  • talosconfig - Конфигурационный файл клиента talosctl, который содержит информацию о кластере, ключах, и API endpoint.

Полученные конфиги (controlplane.yaml/worker.yaml) растиражировал, изменив внутри ip address и hostname для каждой ноды.

По итогу получаем пять machine-конфигураций:

├── mconf
│   ├── controlplane.1.yaml
│   ├── controlplane.2.yaml
│   ├── controlplane.3.yaml
│   ├── mc.patch.yaml
│   ├── worker.1.yaml
│   ├── worker.2.yaml
│   └── worker.3.yaml
├── secrets.yaml
└── talosconfig

В каждом из манифестов, меняем значение в полях - hostname, addresses:

network:
    hostname: snd-cp01          # Имя хоста, у каждой ноды будет свое
    interfaces:
      - interface: eth0         
        addresses:
          - 10.8.190.68/24   # Адрес ноды

А в манифесте воркеров, удаляем настройки vip - адреса. В противном случаи, сетевой интерфейс на воркер-нодах не настроиться..

# vim worker.*.yaml
    interfaces:
      - interface: eth0 # The interface name.
        addresses:
          - 10.8.190.68/24
        routes:
          - network: 0.0.0.0/0 # The route's network.
            gateway: 10.8.190.40 # The route's gateway.
        dhcp: false
        vip:                    # Удаляем поле тут, 
          ip: 10.8.190.73    # только на воркер узлах

Базовая конфигурация нашего кластера готова, теперь можно перейти к его запуску.

Поднимаем виртуалки

Создаём виртуалки через govc library.deploy, список серверов с характеристиками выделил в этой табличке:

HostnameIPCPUMemoryDiskNetwork (PortGroup)
snd-cp0110.8.190.68x48Gb100gbVLAN2
snd-cp0210.8.190.69x48Gb100gbVLAN2
snd-cp0310.8.190.70x48Gb100gbVLAN2
snd-wrk0110.8.190.71x816Gb100gbVLAN2
snd-wrk0210.8.190.72x816GB100gbVLAN2

Дополнительный, будет нужен еще один ip (10.8.190.73), который будет использоваться в качестве Virtual IP между мастер-нодами.

Cоздаем новые виртуальные машины. Начнем с Control Plane узлов:

for i in 1 2 3; do govc library.deploy TalosLinux/talos-${TALOS_VERSION} talos-snd-cp0$i.mydomain.local; done

Bootstrap Control Plane - узлов

Меняем настройки виртуальных машин, выделяем ресурсы, согласно таблице. Также указываем сетевую порт группу и маппим machine-конфигурацию:

for i in 1 2 3; do
  vm_name="talos-snd-cp0$i.mydomain.local"
  govc vm.network.change -vm "$vm_name" -net 'VM TEST' ethernet-0
  govc vm.change -c 4 -m 8192 -e "guestinfo.talos.config=$(base64 mconf/controlplane.$i.yaml)" -e "disk.enableUUID=1" -vm "$vm_name"
  govc vm.disk.change -disk.name disk-1000-0 -size 100G -vm "$vm_name"
done

В данном случаи запускается цикл из трех иттераций, в процессе каждой на определенном узле меняются ресурсы.

Запускаем ноды Control Plane:

for i in 1 2 3; do govc vm.power -on talos-snd-cp0$i.mydomain.local; done

После того, как сервера забутились, начинаем инициализацию кластера:

talosctl --talosconfig talosconfig bootstrap -n 10.8.190.68 -e 10.8.190.68 

Мы используем первый сервер как начальную (bootstrap) ноду, поэтому указываем ее ip-адрес как для подключения (-e), так и как целевую ноду (-n).

После того, как кластер успешно запустится, первой ноде будет добавлен реальный кластерный ip.

Bootstrap Worker - узлов

Теперь создадим виртуальные машины для worker-узлов:

for i in 1 2; do govc library.deploy TalosLinux/talos-${TALOS_VERSION} talos-snd-wrk0$i.mydomain.local; done

Аналогично управляющим узлам, меняем характеристики и маппим конфигурацию:

for i in 1 2; do
  vm_name="talos-snd-wrk0$i.mydomain.local"
  govc vm.network.change -vm "$vm_name" -net 'VM TEST' ethernet-0
  govc vm.change -c 8 -m 16384 -e "guestinfo.talos.config=$(base64 mconf/worker.$i.yaml)" -e "disk.enableUUID=1" -vm "$vm_name"
  govc vm.disk.change -disk.name disk-1000-0 -size 100G -vm "$vm_name"
done

И запускаем виртуалки:

for i in 1 2; do govc vm.power -on talos-snd-wrk0$i.mydomain.local; done

Создаем Kubeconfig

Проверим статус кластера. Но предварительно нужно вытащить - kubeconfig.

talosctl config endpoint 10.8.190.73
talosctl config node 10.8.190.73
talosctl kubeconfig .

kubeconfig будет создан в текущей директории. Экспортируем его в окружение: export KUBECONFIG=kubeconfig

Для первичной проверки, обратимся к кластеру и отобразим список всех узлов:

[sysadmin@ SandboxCluster]$ kubectl get no -o wide
NAME        STATUS   ROLES           AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE          KERNEL-VERSION
snd-cp01    Ready    control-plane   33m     v1.31.1   10.8.190.68   <none>        Talos (v1.10.3)   6.12.28-talos
snd-cp02    Ready    control-plane   33m     v1.31.1   10.8.190.69   <none>        Talos (v1.10.3)   6.12.28-talos
snd-cp03    Ready    control-plane   33m     v1.31.1   10.8.190.70   <none>        Talos (v1.10.3)   6.12.28-talos
snd-wrk01   Ready    <none>          5m13s   v1.31.1   10.8.190.71   <none>        Talos (v1.10.3)   6.12.28-talos
snd-wrk02   Ready    <none>          5m39s   v1.31.1   10.8.190.72   <none>        Talos (v1.10.3)   6.12.28-talos

Как можно понять из вывода, статус нод в состоянии Ready. Можно переходить к установке CSI-драйвера, ingress-контроллеров и других аддонов.