Я поставил 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-навыков — в окружении, куда больше похожем на реальное, чем типичный «кластер в коробке» из одной команды.



