K3s на arch linux: как поднять живой кластер без боли и проблем с Dns

Я поставил k3s на Arch, наступил на все возможные грабли — и собрал рабочую схему, которую можно повторить без боли. Ниже — подробный разбор, почему «одна команда из документации» зависает, откуда берутся проблемы с DNS, где потерялись systemd-юниты и как в итоге поднять живой кластер на Arch и производных.

---

Зачем вообще k3s, если есть minikube

Для локального Kubernetes обычно есть два популярных пути:

- нужен «песочничный» кластер — ставят minikube;
- хочется конфигурации, похожей на боевую, — смотрят в сторону k3s.

Полноценный Kubernetes-дистрибутив на ноутбук с 8 ГБ ОЗУ — страдание: прожорливый API-сервер, контроллеры, etcd, куча вспомогательных сервисов. Minikube эту боль сглаживает, но он больше про «поиграться в кластер», чем про отработку production-сценариев.

K3s — это облегчённый, но всё ещё «взрослый» Kubernetes:

- поставляется одним бинарником размером меньше ~70 МБ;
- тянет минимальное количество зависимостей;
- ближе к тому, что разворачивают на edge-нодах и маломощных серверах;
- удобен для DevOps/SRE-практики на локальной машине.

Идея казалась простой: взять Arch-based дистрибутив (в моём случае CachyOS), скачать бинарник, запустить, настроить пару сервисов — и работать как с почти настоящим кластером. На практике — ничего подобного.

---

Часть 1. Установка «в одну команду»: тишина в терминале

Официальный быстрый старт уверяет: установка k3s занимает одну команду и подходит для «большинства современных Linux-дистрибутивов». Arch формально подпадает под это определение, но на деле ближе к «отдельной экзотике».

Сценарий:

1. Запускается рекомендуемая однострочная команда установки.
2. Терминал замирает:
- нет вывода;
- нет ошибок;
- Ctrl+C не реагирует;
- остаётся только закрывать окно.

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

В разделе требований к системе нет ни слова о нюансах rolling-release-дистрибутивов. Про особенности Arch, systemd-resolved и конфигурации DNS тоже тишина. На уровне документации выглядит так, будто всё должно летать, а по факту инсталлятор встаёт колом.

---

Часть 2. Попытка через AUR и переход на «ручной» путь

Логичный шаг для Arch-пользователя — поиск пакета в AUR. На момент установки:

- пакет из AUR загружается;
- при сборке рушится с ошибкой;
- итог — собранного пакета нет.

Возможно, позже пакет поправят или у кого-то он соберётся без проблем, но в тот момент это был тупик. Пришлось двигаться классическим Arch-подходом: скачать бинарник, положить его в систему и всё собирать самому.

Скачивание и установка ручным способом:

1. Кладём бинарник k3s в /usr/local/bin (или другой каталог из `$PATH`).
2. Делаем его исполняемым.
3. Проверяем, что он запускается, выводит версию и не падает мгновенно.

На этом этапе выглядит, что всё хорошо: бинарник живой, запускается. Но сразу всплывает следующий сюрприз — никаких systemd-юнитов в системе не появилось.

---

Часть 3. Где systemd-юнит и почему его нет

После ручной установки обнаруживается, что:

- в /etc/systemd/system нет ни k3s.service, ни каких-либо связанных юнитов;
- в /usr/lib/systemd/system — тоже пусто по части k3s;
- автозапуска нет, удобного управления через systemctl — тоже.

K3s сам по себе может быть запущен напрямую из терминала, но для нормальной эксплуатации (даже локальной) нужен как минимум:

- запуск при старте системы;
- возможность перезапуска;
- интеграция с systemd для отслеживания статуса.

Приходится писать юнит-файл руками.

Минимальный, но рабочий вариант юнита для k3s может включать:

- `Type=notify` — чтобы k3s уведомлял systemd о готовности;
- `After=network-online.target` — кластер без сети не нужен;
- `LimitNOFILE=1048576` — Kubernetes активно расходует файловые дескрипторы.

После создания файла /etc/systemd/system/k3s.service:

1. Выполняем `systemctl daemon-reload`.
2. Запускаем сервис.
3. Включаем автозапуск.

На этом шаге API-сервер обычно действительно стартует, и это можно проверить простым curl-запросом к порту 6443.

---

Часть 4. Кластер вроде бы поднялся, но kubectl не работает

Проверка через curl даёт ожидаемый результат:

- порт 6443 открыт;
- API отвечает JSON;
- в ответе — статус 401 Unauthorized.

И это как раз хороший знак: сервер жив, просто требует корректную аутентификацию, как и положено. Однако дальше приходит очередь kubectl — и тут начинается вторая серия проблем.

Типичный сценарий:

1. Конфиг под kubectl создаётся (либо берётся из /etc/rancher/k3s, либо копируется в ~/.kube/config).
2. Запуск любой команды kubectl (например, `get nodes`) приводит к ошибкам.
3. Логи k3s через `journalctl -u k3s` указывают не на сам API, а на проблемы с DNS и CoreDNS.

Чаще всего в логах встречаются сообщения о том, что:

- в /etc/resolv.conf обнаружено слишком много DNS-серверов;
- часть из них игнорируется;
- в качестве итоговых остаются несколько публичных адресов (например, 8.8.8.8 и 1.1.1.1).

На первый взгляд это не кажется критичным, но для k3s, а точнее для его DNS-компоненты CoreDNS, это уже повод «сойти с ума» и сломать весь кластер.

---

Часть 5. DNS в Arch: systemd-resolved против NetworkManager

Корень конфликта — архитектура сети в Arch и его производных. В типичной установке:

- работает NetworkManager;
- параллельно включён systemd-resolved;
- оба пытаются управлять /etc/resolv.conf или связанным с ним symlink.

В результате:

- список nameserver’ов дублируется;
- одни и те же адреса могут попадать в файл несколько раз;
- конфигурация выглядит непротиворечиво для обычных приложений, но Kubernetes-компоненты начинают вести себя нестабильно.

CoreDNS в k3s ожидает более предсказуемый, статичный /etc/resolv.conf. Когда он видит:

- несколько источников DNS;
- дубликаты записей;
- динамически меняющийся файл;

он периодически перестаёт обслуживать запросы корректно. Для пользователя это выглядит как «кластер поднялся, но сервисы не резолвятся, kubectl ведёт себя странно, поды не могут достучаться друг до друга по именам».

---

Часть 6. Почему в Arch необходимо dns=none

Для того чтобы k3s чувствовал себя стабильно, нужно убрать конкурирующее управление DNS со стороны NetworkManager и оставить единый предсказуемый сценарий.

Практический шаг:

1. Открываем глобальный конфиг NetworkManager, обычно это /etc/NetworkManager/NetworkManager.conf.
2. В секции `[main]` добавляем или меняем строку:

```ini
dns=none
```

3. Перезапускаем NetworkManager и systemd-resolved (или перезагружаем систему целиком).

Что это даёт:

- NetworkManager перестаёт править /etc/resolv.conf;
- источник DNS остаётся один (systemd-resolved или ваша статическая конфигурация);
- содержимое resolv.conf становится стабильным и понятным для CoreDNS.

После этого:

- перезапускаем k3s через systemctl;
- смотрим логи — сообщения о конфликтующих DNS-серверах должны исчезнуть;
- kubectl перестаёт падать на ровном месте при попытке получить список нод или подов.

---

Часть 7. Нюанс с оболочкой: fish против bash

Ещё один неожиданный камень — используемый shell. На Arch и производных многие любят fish за удобство, автодополнение и дружелюбный интерфейс. Но:

- официальные установки и скрипты k3s пишутся с расчётом на POSIX-совместимый shell (sh/bash);
- fish не всегда корректно интерпретирует конструкции из установочных скриптов;
- переменные окружения и подстановки могут вести себя иначе.

Если запускать команды установки или скрипты запуска из-под fish, часть логики может просто не отработать. Визуально это будет выглядеть как «скрипт отработал, но ничего не поставилось» или «команда повисла».

Решение простое:

- для установки и обслуживания k3s используйте bash или sh;
- fish можно оставить для повседневной работы, но критичные инсталляции лучше выполнять в более предсказуемой оболочке.

---

Часть 8. Проверка кластера после правки DNS

Когда:

- systemd-юнит создан;
- NetworkManager не трогает DNS;
- оболочка не вмешивается в работу скриптов;

можно перейти к проверке самого кластера.

Минимальный чек-лист:

1. `systemctl status k3s` — сервис в состоянии active (running), без лавины ошибок.
2. `kubectl get nodes` — нода видна, в статусе Ready.
3. `kubectl get pods -A` — все системные поды (включая CoreDNS) в состоянии Running или Completed.
4. Простой тестовый POD:
- создать deployment с nginx или busybox;
- проверить, что под успешно стартует и резолвит внешние домены.

Если всё это работает, основная проблема с DNS и запуском кластера решена.

---

Часть 9. Быстрая инструкция: k3s на Arch пошагово

Для тех, кому не нужна вся история, а важен алгоритм:

1. Отключить управление DNS в NetworkManager
В файл конфигурации NetworkManager добавить `dns=none` в секцию `[main]`, затем перезапустить службы сети или систему.

2. Скачать бинарник k3s
Положить его в /usr/local/bin, выдать права на исполнение.

3. Создать systemd-юнит
Описать k3s.service в /etc/systemd/system с:
- `Type=notify`;
- `After=network-online.target`;
- повышенным лимитом файловых дескрипторов.

4. Перезагрузить конфигурацию systemd и запустить k3s
`systemctl daemon-reload`, затем `systemctl enable --now k3s`.

5. Проверить API
Через curl достучаться до порта 6443 и убедиться, что сервер отвечает (даже 401 будет признаком жизни).

6. Настроить kubectl
Взять kubeconfig, который k3s создаёт по умолчанию, скопировать в ~/.kube/config, выставить права.

7. Проверить состояние кластера
Посмотреть ноды и поды, убедиться, что CoreDNS и остальные системные компоненты запущены.

---

Часть 10. Дополнительные рекомендации по эксплуатации

Чтобы кластер не только запускался, но и был удобен в дальнейшей работе, имеет смысл:

- Ограничить потребление ресурсов:
- выставить разумные requests/limits для системных подов;
- не запускать тяжёлые сервисы на машине с 8 ГБ ОЗУ без оглядки.
- Настроить хранение данных:
- определиться с использованием встроенного хранилища или внешнего;
- помнить, что локальный кластер легко потерять вместе с ноутбуком.
- Поддерживать бинарник k3s в актуальном состоянии:
- rolling-release-дистрибутивы обновляются часто;
- несовместимости возможны, особенно с сетевыми стеками и cgroup’ами.

---

Часть 11. Безопасность и доступ к API

Даже локальный кластер — всё равно кластер, в котором:

- действует RBAC;
- хранится чувствительная информация в секретах;
- работает API, доступный по сети.

Несколько практичных шагов:

- держать kubeconfig только у нужных пользователей;
- не пробрасывать порт 6443 наружу без реальной необходимости;
- при экспериментах с ролью cluster-admin понимать, что ошибки манифестов могут легко «уронить» весь кластер.

---

Часть 12. K3s vs minikube на Arch: когда что выбирать

Если цель — просто пощупать kubectl и базовые объекты:

- minikube часто проще, особенно на нестандартных дистрибутивах;
- он умеет абстрагироваться от особенностей хостовой системы за счёт драйверов (VM/контейнеров).

K3s же имеет смысл выбирать, когда:

- нужен максимально лёгкий, но близкий к production Kubernetes;
- хочется управлять кластером как обычной службой systemd;
- важно понимать, как устроен сетевой стек, DNS и конфигурация в реальной системе.

На Arch k3s требует чуть больше ручной работы: придётся разрулить DNS, systemd-юниты и следить за тем, как обновления системы влияют на кластер.

---

Итог

На бумаге k3s выглядит как «маленький аккуратный Kubernetes, который работает где угодно». На практике rolling-release дистрибутивы вроде Arch добавляют слоёв сложности:

- установщик может зависать без явных ошибок;
- системные юниты нужно писать вручную;
- DNS-конфигурация по умолчанию конфликтует с ожиданиями CoreDNS;
- некоторые оболочки (fish) мешают корректному выполнению скриптов.

Но после того как:

- запретить NetworkManager вмешиваться в DNS;
- развёрнуть k3s через собственный systemd-юнит;
- запустить установку в обычном bash;

кластер начинает вести себя стабильно и становится отличной площадкой для локальной отработки DevOps/SRE-навыков — в окружении, куда больше похожем на реальное, чем типичный «кластер в коробке» из одной команды.

4
2
Прокрутить вверх