MAATRIX / Блог / Talos Linux без SSH и пакетного менеджера: как это чинят, когда сломалось

Talos Linux без SSH и пакетного менеджера: как это чинят, когда сломалось

MAATRIX

Talos Linux ставят ради одной фразы из документации: «нет SSH, нет shell, нет пакетного менеджера — значит, нечего ломать и нечем взламывать». На старте кластер действительно выглядит образцово: ноды поднялись за несколько минут из одного YAML-файла, control plane собрался сам, поверхность атаки минимальна по построению. А потом одна нода уходит в NotReady, и первый рефлекс любого, кто десять лет администрировал Linux, — «зайду по SSH, посмотрю journalctl, гляну процессы» — просто не срабатывает, потому что SSH на ноде нет физически. Не «заблокирован политикой», не «отключён в конфиге» — его нет в образе системы вообще. Разбираем, что Talos реально даёт на старте и какой процесс диагностики придётся освоить взамен привычного.

Что такое Talos Linux и почему он устроен именно так

Talos Linux — это дистрибутив, спроектированный не как универсальная ОС, а как runtime исключительно для Kubernetes. У него нет init-системы вроде systemd в привычном виде, нет shell в базовом образе, нет пакетного менеджера — вместо apt install или yum install вы либо используете уже встроенные в образ компоненты, либо пересобираете образ целиком через Image Factory (сервис, который по запросу собирает установочный образ с нужным набором system extensions — например, для iSCSI, NVMe-дисков нестандартных облаков или специфичных сетевых драйверов).

Корневая файловая система Talos смонтирована в режиме только для чтения (squashfs), и это не настройка, которую можно откатить — это архитектурное решение. Изменяемых данных на ноде минимум: партиция STATE хранит применённый machine config, партиция EPHEMERAL (обычно смонтирована в /var) — то, что реально пишет kubelet, containerd и системные компоненты. Всё остальное — часть неизменяемого образа, который просто заменяется целиком при обновлении, а не патчится файл за файлом.

Управление нодой происходит не через shell-сессию, а через gRPC API, который слушает apid на порту 50000 (в дефолтной конфигурации). С этим API общается единственный официальный клиент — talosctl. Он же используется и для первоначальной генерации machine config, и для бутстрапа etcd, и для повседневной эксплуатации. Второй ключевой файл, talosconfig, — это аналог kubeconfig, но для доступа к самой ОС, а не к Kubernetes API: в нём сертификаты клиента, эндпоинты control plane и контекст кластера.

Что это реально даёт на старте

Прежде чем переходить к боли с диагностикой, стоит честно перечислить, за что Talos действительно стоит своих неудобств:

  • Минимальная поверхность атаки не на бумаге. Нет shell — нет постэксплуатационных техник, завязанных на интерактивный доступ: не из чего собрать reverse shell на самой ноде, нечем закрепиться через cron или systemd-юнит, нет пакетного менеджера, через который можно незаметно доустановить бэкдор-утилиту. Компрометация одного контейнера не даёт злоумышленнику привычного плацдарма на хосте.
  • Декларативность в буквальном смысле, а не в маркетинговом. Вся конфигурация ноды — сеть, диски, kubelet, control plane — это один YAML (machine config), который применяется атомарно. Нет дрейфа конфигурации от ручных правок «просто исправил один параметр и забыл записать это в Ansible» — исправить конфиг вручную на ноде физически негде, только через talosctl apply-config или talosctl edit machineconfig.
  • Воспроизводимость нод. Поднять новую worker-ноду — значит загрузить тот же образ и применить тот же (или почти тот же) machine config. Никакой накопленной за месяцы истории apt install и забытых правок в /etc, которая делает каждую ноду немного уникальной и непонятной, если её потерять.
  • Меньше площадь для CVE пакетного менеджера как такового. Если в системе нет package manager и общесистемных пакетов в привычном виде, часть класса уязвимостей (supply chain через скомпрометированный пакет, забытые пакеты с открытыми портами) просто отсутствует как вектор.

Это реальные преимущества, а не только строчка в чеклисте безопасности. Но у каждого пункта есть обратная сторона в разделе ниже — она касается не безопасности, а скорости, с которой вы находите причину проблемы в 3 часа ночи.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер под Kubernetes

Первая поломка: SSH нет, что теперь

Возьмём типичный сценарий: одна из worker-нод показывает NotReady в kubectl get nodes, поды на ней зависли в Terminating. Рефлекс «зайти по SSH и посмотреть, что происходит» здесь не работает в принципе — вместо этого нужен talosctl, настроенный на конкретный IP ноды:

# указываем ноду явно (можно и через export TALOSCONFIG / контекст)
talosctl -n 10.0.1.15 --talosconfig ./talosconfig version

# текстовый дашборд ноды: CPU, память, диски, сеть, топ процессов — 
# ближайший аналог htop, который есть "из коробки"
talosctl -n 10.0.1.15 dashboard

Дашборд — первое, что стоит открыть: показывает загрузку ресурсов и последние сообщения ядра в реальном времени, без необходимости знать, какой конкретно ресурс запрашивать. Talos не прячет диагностическую информацию — он просто отдаёт её через другой интерфейс, а не через привычный терминал на хосте.

Дальше — состояние системных сервисов Talos (аналог systemctl status, но для внутренних компонентов самой ОС: kubelet, etcd, containerd, apid и так далее):

talosctl -n 10.0.1.15 services

Команда покажет каждый сервис, его текущее состояние (Running, Failed, Waiting) и время последнего изменения состояния. Если kubelet в Failed — вот и объяснение, почему нода NotReady, и дальше уже понятно, куда смотреть логи.

Как реально читать логи и состояние ноды

Вместо journalctl -u <service> -ftalosctl logs:

# логи конкретного сервиса Talos с "хвостом" в реальном времени
talosctl -n 10.0.1.15 logs kubelet -f

# логи containerd, если проблема на уровне запуска контейнеров
talosctl -n 10.0.1.15 logs containerd

# сообщения ядра — аналог dmesg, полезно при проблемах с диском или сетью
talosctl -n 10.0.1.15 dmesg

Отдельно стоит различать логи системных сервисов Talos (kubelet, etcd, apid) и логи контейнеров, которые Kubernetes запускает через containerd:

# список system-контейнеров (не Kubernetes-подов, а внутренних процессов Talos)
talosctl -n 10.0.1.15 containers

# список контейнеров именно уровня Kubernetes/CRI на этой ноде
talosctl -n 10.0.1.15 containers -k

# логи Kubernetes-контейнера напрямую через Talos (полезно, если под уже не отвечает kubectl)
talosctl -n 10.0.1.15 logs -k <container-id>

Ключевая перестройка: вы больше не думаете «зайду и посмотрю файл лога», а думаете «какой сервис или ресурс мне нужен и какой командой его запросить». Первые недели это медленнее привычного tail -f /var/log/..., потому что нужно помнить не путь к файлу, а имя сервиса.

Resource API: internal state, который заменяет привычные конфиг-файлы

Внутри Talos построен вокруг COSI — типизированного resource API, похожего по духу на сам Kubernetes API: внутреннее состояние ноды (сеть, адреса, состояние дисков, участники etcd, сертификаты) — это не файлы конфигурации, разбросанные по /etc, а строго типизированные ресурсы, которые можно запросить и понаблюдать за их изменением:

# список типов ресурсов, которые вообще можно запросить
talosctl -n 10.0.1.15 get --help

# сетевые адреса, которые Talos видит на ноде
talosctl -n 10.0.1.15 get addresses

# участники etcd с точки зрения этой конкретной ноды
talosctl -n 10.0.1.15 get etcdmembers

# состояние дисков, которые Talos обнаружил и с которыми работает
talosctl -n 10.0.1.15 disks

# смонтированные файловые системы
talosctl -n 10.0.1.15 mounts

Это удобно, когда вы уже понимаете, какой ресурс искать. Проблема в обратную сторону: раньше опыт подсказывал «посмотри в /etc/resolv.conf, в вывод ip a», а в Talos эквивалента «просто открой файл» нет — нужно знать имя ресурса в номенклатуре COSI. Это осваивается за несколько реальных инцидентов, но не с первого дня, и это честная цена декларативной модели.

Типовые поломки и как их лечат без shell

Нода NotReady, control plane недоступен. Проверяем talosctl services на всех control-plane нодах, смотрим на etcd и kube-apiserver. Если etcd потерял кворум — та же логика, что в любом Kubernetes на etcd (нечётное число узлов, работоспособность большинства), но проверка идёт через talosctl get etcdmembers и talosctl etcd status, а не через etcdctl вручную на хосте, потому что вручную зайти и запустить etcdctl попросту негде.

Диск EPHEMERAL заполнился. Поскольку изменяемых данных мало, а /var (партиция EPHEMERAL) хранит логи контейнеров, образы и данные kubelet, переполнение этой партиции — частый сценарий на маленьких нодах. Смотрим через:

talosctl -n 10.0.1.15 df

и дальше разбираемся, что ест место — неубранные образы containerd, разросшиеся логи подов без лимитов. Почистить руками командой вроде rm тоже негде — придётся либо настраивать лимиты через machine config и Kubernetes, либо (в крайнем случае) выполнять talosctl reset на ноде с последующим переприсоединением к кластеру.

Проблема с сетью на ноде. talosctl get addresses, talosctl get routes, talosctl netstat — набор, заменяющий привычные ip a, ip r, ss -tlnp. Разница не в возможностях, а в том, что вы обращаетесь к ноде удалённо через API, а не сидите в терминале на ней самой — интерактивная отладка методом «потыкать и посмотреть» получается медленнее.

Ошибка применения machine config. Talos проверяет конфиг перед применением, но не все ошибки ловятся статически — часть всплывает уже в рантайме (например, недоступный NTP-сервер или неверный CIDR подсети). talosctl apply-config -f config.yaml -n 10.0.1.15 --mode=no-reboot позволяет применить конфиг без немедленной перезагрузки, если правки не требуют ребута, и таким образом проверить эффект до того, как нода уйдёт в цикл рестарта.

Когда штатных команд talosctl не хватает

Иногда диагностики через отдельные команды недостаточно — например, при подготовке репорта в поддержку или для более глубокого разбора инцидента постфактум. Для этого есть talosctl support — команда, которая собирает единый архив: логи всех системных сервисов, dmesg, состояние ресурсов, версии компонентов — всё, что обычно приходится собирать вручную десятком разных команд:

talosctl -n 10.0.1.15 support -o node-15-support.zip

Это ближайший аналог «снял полный дамп состояния системы», который в обычном Linux собирают скриптом из journalctl, dmesg, ps aux и нескольких конфигов — здесь это одна встроенная команда, потому что Talos заранее знает, что из него может понадобиться для диагностики.

Второй инструмент — на случай, когда нужно реально «залезть внутрь» файловой системы, а не самой хост-ОС, — стандартный механизм Kubernetes, а не Talos-специфичный:

kubectl debug node/worker-3 -it --image=busybox:stable -- chroot /host sh

Это создаёт эфемерный под с доступом к файловой системе хоста через hostPath, и здесь уже можно пользоваться привычным shell — но важно понимать разницу: это доступ через Kubernetes-под с примонтированной хостовой файловой системой, а не полноценная shell-сессия на самой Talos-ноде. Часть системных вызовов и точек монтирования будет вести себя иначе, и полагаться на этот способ как на замену администрирования не стоит — это инструмент точечной диагностики, а не рутинной эксплуатации.

Обновления и откат без пакетного менеджера

Раз пакетов нет, обновление системы — это не apt upgrade, а замена всего образа целиком на новую версию установочного образа:

# обновление самой Talos на ноде до нового установочного образа
talosctl -n 10.0.1.15 upgrade --image factory.talos.dev/installer/<schematic-id>:<talos-version>

# отдельно обновление версии компонентов Kubernetes (kubelet, kube-apiserver и так далее)
talosctl upgrade-k8s --to <k8s-version>

Разделение обновления самой ОС и обновления Kubernetes — намеренное архитектурное решение: это разные жизненные циклы, и связывать их в одну операцию было бы источником лишнего риска. Talos хранит предыдущую версию образа и умеет откатиться, если новая версия не проходит проверку загрузки:

talosctl -n 10.0.1.15 rollback

Это работает надёжнее, чем ручной откат пакетов в традиционном дистрибутиве, именно потому, что обновление атомарно на уровне всего образа — не бывает промежуточного состояния «половина пакетов новая, половина старая», которое иногда встречается после прерванного apt upgrade.

Если проект ещё присматривается к переезду на Kubernetes вообще, стоит сначала понять, нужен ли Kubernetes конкретно вашему проекту и когда переход с docker compose на Kubernetes оправдан — Talos имеет смысл обсуждать только после того, как решён более базовый вопрос. А если кластер уже есть на классическом дистрибутиве и k3s, полезно свериться с разбором managed Kubernetes против своего k3s: Talos не заменяет это решение, а меняет его условия — сам факт immutable-ОС не отменяет вопрос, кто администрирует control plane.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер под Kubernetes

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли добавить SSH-доступ на Talos-ноду, если очень нужно?

Нет штатного способа установить и включить SSH-демон — в образе физически нет SSH-сервера и нет пакетного менеджера, чтобы его туда добавить. Формально можно собрать кастомный образ через Image Factory с system extension, добавляющим отладочные инструменты, но это осознанный отказ от одного из главных преимуществ Talos, а не рекомендуемая практика.

Что делать, если talosctl не может достучаться до ноды вообще?

Проверьте сетевую доступность порта API (по умолчанию 50000) и актуальность talosconfig — сертификаты в нём привязаны к конкретному кластеру и могут быть отозваны при пересоздании control plane. Если нода физически недоступна по сети, диагностика через talosctl невозможна в принципе, как и SSH-доступ к обычному серверу без консоли провайдера.

Насколько сложнее эксплуатировать Talos по сравнению с k3s или обычным Kubernetes на Ubuntu?

Сложнее не по числу операций, а по необходимости переучить рефлексы: команд talosctl для типовых задач не больше, чем systemctl/journalctl/apt, но они другие, и первые несколько инцидентов уходят на то, чтобы вспомнить нужную вместо привычной. После адаптации скорость диагностики сопоставима.

Стоит ли ставить Talos на один-два сервера ради проекта среднего размера?

Overhead на изучение talosctl оправдан, если вы уже цените воспроизводимость нод и минимальную поверхность атаки выше привычности администрирования через shell. Для одного-двух серверов без выделенного DevOps-времени классический дистрибутив с k3s часто прагматичнее.

Работает ли kubectl exec в под на Talos-ноде как обычно?

Да, без изменений — Talos не меняет поведение Kubernetes API и подов, ограничения касаются только доступа к хост-ОС, а не к контейнерам. kubectl logs, kubectl exec, kubectl debug в под работают так же, как на любом другом дистрибутиве.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →