Этой статье более одного года. Старые статьи могут содержать устаревшую информацию. Проверьте, не утратили ли актуальность сведения на странице с момента публикации.

Простой способ установить Talos Linux на любую машину, у любого провайдера

Простой способ установить Talos Linux на любую машину, у любого провайдера

Talos Linux — это специализированная операционная система, предназначенная для запуска Kubernetes. На мой взгляд, она справляется с этой задачей лучше других. Прежде всего, она берёт на себя полное управление жизненным циклом компонентов control-plane Kubernetes.

С другой стороны, Talos Linux ориентирован на безопасность, сводя к минимуму возможность пользователя влиять на систему. Отличительная особенность этой ОС — почти полное отсутствие исполняемых файлов, включая отсутствие оболочки (shell) и невозможность входа по SSH. Вся конфигурация Talos Linux выполняется через Kubernetes-подобный API.

Обычно Talos Linux поставляется в виде набора готовых образов для различных окружений.

Стандартный способ установки предполагает, что вы возьмёте готовый образ для вашего конкретного облачного провайдера или гипервизора и создадите из него виртуальную машину. Что касается физических серверов, здесь возможны такие варианты, как загрузка образа Talos Linux методами ISO или PXE.

К сожалению, это не работает в случае провайдеров, которые предоставляют предварительно настроенный сервер или виртуальную машину, не позволяя загрузить собственный образ или даже использовать ISO для установки через KVM. В этом случае ваш выбор ограничен теми дистрибутивами, которые предоставляет облачный провайдер.

Обычно в процессе установки Talos Linux нужно ответить на два вопроса: (1) как загрузить и запустить образ Talos Linux и (2) как подготовить и применить machine-config (основной конфигурационный файл Talos Linux) к этому загруженному образу. Поговорим о каждом из этих шагов.

Загрузка в Talos Linux

Один из самых универсальных методов — использовать механизм ядра Linux под названием kexec.

kexec — это одновременно утилита и одноимённый системный вызов. Он позволяет загрузиться в новое ядро из уже работающей системы без физической перезагрузки машины. Это значит, что вы можете скачать нужные vmlinuz и initramfs для Talos Linux, затем указать необходимую cmdline ядра и сразу переключиться на новую систему. Всё выглядит так, будто ядро было загружено штатным загрузчиком при старте, только в этом случае роль загрузчика играет ваша существующая ОС.

По сути, всё, что вам нужно, — это любой дистрибутив Linux. Это может быть физический сервер, запущенный в режиме восстановления (rescue mode), или даже виртуальная машина с предустановленной операционной системой. Рассмотрим пример с Ubuntu, но это может быть буквально любой другой дистрибутив Linux.

Войдите по SSH и установите пакет kexec-tools — он содержит утилиту kexec, которая понадобится вам позже:

apt install kexec-tools -y

Далее нужно скачать Talos Linux, то есть kernel и initramfs. Их можно загрузить из официального репозитория:

wget -O /tmp/vmlinuz https://github.com/siderolabs/talos/releases/latest/download/vmlinuz-amd64
wget -O /tmp/initramfs.xz https://github.com/siderolabs/talos/releases/latest/download/initramfs-amd64.xz

Если у вас физический сервер, а не виртуальный, вам потребуется собрать собственный образ со всеми необходимыми прошивками с помощью сервиса Talos Factory. Как вариант, можно использовать готовые образы из проекта Cozystack (решение для построения облаков, которое мы создали в Ænix и передали в CNCF Sandbox) — эти образы уже включают все необходимые модули и прошивки:

wget -O /tmp/vmlinuz https://github.com/cozystack/cozystack/releases/latest/download/kernel-amd64
wget -O /tmp/initramfs.xz https://github.com/cozystack/cozystack/releases/latest/download/initramfs-metal-amd64.xz

Теперь вам нужна сетевая информация, которая будет передана Talos Linux при загрузке. Ниже приведён небольшой скрипт, который собирает всё необходимое и задаёт переменные окружения:

IP=$(ip -o -4 route get 8.8.8.8 | awk -F"src " '{sub(" .*", "", $2); print $2}')
GATEWAY=$(ip -o -4 route get 8.8.8.8 | awk -F"via " '{sub(" .*", "", $2); print $2}')
ETH=$(ip -o -4 route get 8.8.8.8 | awk -F"dev " '{sub(" .*", "", $2); print $2}')
CIDR=$(ip -o -4 addr show "$ETH" | awk -F"inet $IP/" '{sub(" .*", "", $2); print $2; exit}')
NETMASK=$(echo "$CIDR" | awk '{p=$1;for(i=1;i<=4;i++){if(p>=8){o=255;p-=8}else{o=256-2^(8-p);p=0}printf(i<4?o".":o"\n")}}')
DEV=$(udevadm info -q property "/sys/class/net/$ETH" | awk -F= '$1~/ID_NET_NAME_ONBOARD/{print $2; exit} $1~/ID_NET_NAME_PATH/{v=$2} END{if(v) print v}')

Эти параметры можно передать через cmdline ядра. Используйте параметр ip=, чтобы настроить сеть с помощью механизма конфигурации IP на уровне ядра. Этот способ позволяет ядру автоматически поднять интерфейсы и назначить IP-адреса во время загрузки на основе информации, переданной через cmdline ядра. Это встроенная возможность ядра, включаемая опцией CONFIG_IP_PNP. В Talos Linux она включена по умолчанию. Вам нужно лишь передать корректно отформатированные сетевые настройки в cmdline ядра.

Правильный синтаксис этой опции можно найти в документации Talos Linux. Также официальная документация ядра Linux содержит более подробные примеры.

Задайте переменную CMDLINE с опцией ip, содержащей настройки текущей системы, и выведите её:

CMDLINE="init_on_alloc=1 slab_nomerge pti=on console=tty0 console=ttyS0 printk.devkmsg=on talos.platform=metal ip=${IP}::${GATEWAY}:${NETMASK}::${DEV}:::::"
echo $CMDLINE

Вывод должен выглядеть примерно так:

init_on_alloc=1 slab_nomerge pti=on console=tty0 console=ttyS0 printk.devkmsg=on talos.platform=metal ip=10.0.0.131::10.0.0.1:255.255.255.0::eno2np0:::::

Убедитесь, что всё выглядит правильно, и загрузите наше новое ядро:

kexec -l /tmp/vmlinuz --initrd=/tmp/initramfs.xz --command-line="$CMDLINE"
kexec -e

Первая команда загружает ядро Talos в оперативную память, вторая переключает текущую систему на это новое ядро.

В результате вы получите работающий экземпляр Talos Linux с настроенной сетью. Однако сейчас он работает целиком в оперативной памяти, поэтому при перезагрузке сервера система вернётся в исходное состояние (загрузив ОС с жёсткого диска, например Ubuntu).

Применение machine-config и установка Talos Linux на диск

Чтобы установить Talos Linux на диск на постоянной основе и заменить текущую ОС, нужно применить machine-config, указав диск для установки. Для настройки машины можно использовать либо официальную утилиту talosctl, либо Talm — утилиту, поддерживаемую проектом Cozystack (Talm работает и с ванильным Talos Linux).

Сначала рассмотрим настройку с помощью talosctl. Прежде чем применять конфигурацию, убедитесь, что она содержит сетевые настройки для вашего узла; иначе после перезагрузки узел не сможет настроить сеть. Во время установки загрузчик записывается на диск и не содержит опции ip для автоконфигурации ядра.

Вот пример патча конфигурации с необходимыми значениями:

# node1.yaml
machine:
  install:
    disk: /dev/sda
  network:
    hostname: node1
    nameservers:
    - 1.1.1.1
    - 8.8.8.8
    interfaces:
    - interface: eno2np0
      addresses:
      - 10.0.0.131/24
      routes:
      - network: 0.0.0.0/0
        gateway: 10.0.0.1

Его можно использовать для генерации полного machine-config:

talosctl gen secrets
talosctl gen config --with-secrets=secrets.yaml --config-patch-control-plane=@node1.yaml  

Просмотрите получившуюся конфигурацию и примените её к узлу:

talosctl apply -f controlplane.yaml -e 10.0.0.131 -n 10.0.0.131 -i

После того как вы примените controlplane.yaml, узел установит Talos на диск /dev/sda, перезаписав существующую ОС, и затем перезагрузится.

Теперь остаётся лишь выполнить команду bootstrap, чтобы инициализировать кластер etcd:

talosctl --talosconfig=talosconfig bootstrap -e 10.0.0.131 -n 10.0.0.131

В любой момент вы можете посмотреть статус узла с помощью команды dashboard:

talosctl --talosconfig=talosconfig dashboard -e 10.0.0.131 -n 10.0.0.131

Как только все сервисы перейдут в состояние Ready, получите kubeconfig — и вы сможете пользоваться свежеустановленным Kubernetes:

talosctl --talosconfig=talosconfig kubeconfig kubeconfig
export KUBECONFIG=${PWD}/kubeconfig

Используйте Talm для управления конфигурацией

Когда конфигураций много, вам понадобится удобный способ ими управлять. Это особенно полезно с bare-metal-узлами, где у каждого узла могут быть разные диски, интерфейсы и специфические сетевые настройки. В результате может потребоваться держать отдельный патч для каждого узла.

Чтобы решить эту задачу, мы разработали Talm — менеджер конфигураций для Talos Linux, работающий подобно Helm.

Идея проста: у вас есть общий шаблон конфигурации с lookup-функциями, и когда вы генерируете конфигурацию для конкретного узла, Talm динамически обращается к Talos API и подставляет значения в итоговую конфигурацию.

Talm включает почти все возможности talosctl, добавляя ещё несколько. Он умеет генерировать конфигурации из Helm-подобных шаблонов и запоминать параметры узла и endpoint для каждого узла в итоговом файле, так что вам не нужно указывать эти параметры каждый раз при работе с узлом.

Покажу, как выполнить те же шаги для установки Talos Linux с помощью Talm:

Сначала инициализируйте конфигурацию для нового кластера:

mkdir talos-config
cd talos-config
talm init --preset generic --name talos

Настройте значения для вашего кластера в values.yaml:

endpoint: "https://10.0.0.131:6443"
podSubnets:
- 10.244.0.0/16
serviceSubnets:
- 10.96.0.0/16
advertisedSubnets:
- 10.0.0.0/24

Сгенерируйте конфигурацию для вашего узла:

talm template -t templates/controlplane.yaml -e 10.0.0.131 -n 10.0.0.131 > nodes/node1.yaml

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

# talm: nodes=["10.0.0.131"], endpoints=["10.0.0.131"], templates=["templates/controlplane.yaml"]
# ЭТОТ ФАЙЛ СГЕНЕРИРОВАН АВТОМАТИЧЕСКИ. ПРЕДПОЧТИТЕЛЬНЕЕ РЕДАКТИРОВАТЬ ШАБЛОНЫ, А НЕ ПРАВИТЬ ВРУЧНУЮ.
machine:
  type: controlplane
  kubelet:
    nodeIP:
      validSubnets:
        - 10.0.0.0/24
  network:
    hostname: node1
    # -- Обнаруженные интерфейсы:
    # eno2np0:
    #   hardwareAddr:a0:36:bc:cb:eb:98
    #   busPath: 0000:05:00.0
    #   driver: igc
    #   vendor: Intel Corporation
    #   product: Ethernet Controller I225-LM)
    interfaces:
      - interface: eno2np0
        addresses:
          - 10.0.0.131/24
        routes:
          - network: 0.0.0.0/0
            gateway: 10.0.0.1
    nameservers:
      - 1.1.1.1
      - 8.8.8.8
  install:
    # -- Обнаруженные диски:
    # /dev/sda:
    #    model: SAMSUNG MZQL21T9HCJR-00A07
    #    serial: S64GNG0X444695
    #    wwid: eui.36344730584446950025384700000001
    #    size: 1.9 TB
    disk: /dev/sda
cluster:
  controlPlane:
    endpoint: https://10.0.0.131:6443
  clusterName: talos
  network:
    serviceSubnets:
      - 10.96.0.0/16
  etcd:
    advertisedSubnets:
      - 10.0.0.0/24

Остаётся лишь применить её к вашему узлу:

talm apply -f nodes/node1.yaml -i

Talm автоматически определяет адрес узла и endpoint из «modeline» (специального комментария в начале файла) и применяет конфигурацию.

Точно так же можно выполнять и другие команды, не указывая опции адреса узла и endpoint. Вот несколько примеров:

Посмотреть статус узла с помощью встроенной команды dashboard:

talm dashboard -f nodes/node1.yaml

Инициализировать кластер etcd на node1:

talm bootstrap -f nodes/node1.yaml

Сохранить kubeconfig в текущий каталог:

talm kubeconfig -f nodes/node1.yaml

В отличие от официальной утилиты talosctl, сгенерированные конфигурации не содержат секретов, что позволяет хранить их в git без дополнительного шифрования. Секреты хранятся в корне вашего проекта и только в этих файлах: secrets.yaml, talosconfig и kubeconfig.

Итог

Это наша полная схема установки Talos Linux практически в любой ситуации. Краткое резюме:

  1. Используйте kexec, чтобы запустить Talos Linux на любой существующей системе.
  2. Убедитесь, что у нового ядра правильные сетевые настройки, собрав их из текущей системы и передав через параметр ip в cmdline. Это позволит подключиться к только что загруженной системе через API.
  3. Когда ядро загружено через kexec, Talos Linux работает целиком в оперативной памяти (RAM). Чтобы установить Talos на диск, примените свою конфигурацию с помощью talosctl или Talm.
  4. Применяя конфигурацию, не забудьте указать сетевые настройки для вашего узла, поскольку конфигурация загрузчика на диске не получает их автоматически.
  5. Наслаждайтесь свежеустановленным и полностью работоспособным Talos Linux.

Дополнительные материалы