Статья для тех, кто пытался поставить k3s на Arch Linux (и основанные на нём дистрибутивы) и столкнулся с зависающим установщиком, проблемами DNS и отсутствующими systemd юнитами. Полное руководство по ручной установке с реальными командами и решениями.
В мире контейнеризации есть негласное правило:
-
хочешь учить Kubernetes локально — ставь minikube;
-
хочешь что-то ближе к production — бери k3s.
Документация обещает установку «в одну команду» и поддержку «большинства современных Linux-дистрибутивов».
Я использую CachyOS (Arch-based), изучаю инфраструктуру под DevOps/SRE и хотел локальный Kubernetes, который:
-
лёгкий;
-
быстрее minikube;
-
и ведёт себя ближе к настоящему кластеру.
И, честно говоря, хотелось не просто «поиграться», а настроить что-то production-like.
После нескольких часов борьбы с зависающим установщиком, отсутствующими systemd-юнитами, конфликтами DNS и даже несовместимостью shell’а, кластер всё-таки встал.
«Попробую k3s — он ведь лёгкий и современный. Что может пойти не так?»
Спойлер: всё.
Если вы тоже на Arch или другом rolling-release дистрибутиве — этот разбор сэкономит вам время и нервы. Я уже прошёл через все грабли, чтобы вам не пришлось.
Почему именно k3s?
Для DevOps/SRE Kubernetes сегодня — стандарт. Но:
-
полноценный Kubernetes на ноутбук (особенно с 8 GB RAM) — слишком тяжело;
-
minikube — хороший вариант, но это скорее «песочница».
K3s — лёгкий, но production-ready Kubernetes. Отлично подходит для edge-систем и локальных экспериментов. K3s упакован в виде одного двоичного файла ( меньше, чем 70 МБ), что сокращает зависимости и количество шагов, необходимых для установки, запуска и автоматического обновления рабочего кластера Kubernetes.
«Лёгкий» — да.
«Работает везде» — не совсем. Rolling-release дистрибутивы вроде Arch — отдельная история.
Часть 1. Установка по документации: молчание ягнят
Официальный Quick-Start Guide уверяет, что установка простая:
curl -sfL https://get.k3s.io | sh -
Я запускаю команду. И… Ничего.
Абсолютно ничего. Ни вывода. Ни ошибки. Терминал зависает. Ctrl+C не помогает — только закрывать окно. Попытки ещё раз — тот же результат.
И проблема в документации в том, что в разделе Requirements написано, что k3s будет работать на большинстве современных систем Linux. Однако не было ничего про Arch и ему подобных дистрибутивов.
AUR? Не сегодня
Пошёл Arch-way вариантом (скачать через AUR):
paru -S k3s
И получил ошибку о том, что не удалось собрать пакет:
==> ERROR: Failed to build k3s
Пакет на тот момент, видимо, был просто сломан. Однако это у меня был такой случай, вам, может быть, повезёт больше.
Часть 2. Ручная установка и системные грабли
Скачиваем бинарник
Предупреждение: вообще, если у вас сработала команда, которая предоставлена в Quick-Start Guide, то вам повезло в какой-то степени. Но в моём случае нет.
curl -L https://github.com/k3s-io/k3s/releases/download/v1.33.6%2Bk3s1/k3s -o k3s
chmod +x k3s
sudo mv k3s /usr/local/bin/
Файл на месте. Но…
Проблема: systemd unit отсутствует
Ни /etc/systemd/system/k3s.service, ни других юнитов не появилось. Без юнита — нет автозапуска, нет нормального управления. Пришлось писать вручную.
Рабочий systemd unit для k3s
создаём юнит в /etc/systemd/system/k3s.service:
sudo nano /etc/systemd/system/k3s.service
Пример минимального, но рабочего юнита:
[Unit]
Description=Lightweight Kubernetes
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/local/bin/k3s server
Restart=always
RestartSec=5s
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
Что здесь важно:
-
Type=notify— K3s сам сообщит systemd, когда действительно запустится -
LimitNOFILE=1048576— Kubernetes работает с тысячами файловых дескрипторов -
After=network-online.target— без сети Kubernetes бесполезен
Запускаем daemon-reload и k3s:
sudo systemctl daemon-reload
sudo systemctl enable --now k3s
Часть 3. Кластер стартует, но не работает
Проверяем API с помощью curl:
curl -k https://127.0.0.1:6443/healthz
Ответ в формате JSON:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
401 Unauthorized — это хорошо! Значит, API сервер запущен и слушает порт 6443, требует аутентификацию (как и должно быть). Но при попытке использовать kubectl:
sleep 30 # Ждём полной инициализации
kubectl get nodes
В ответ получаем ошибку:
Error from server (NotFound): the server could not find the requested resource
Смотрим логи journalctl:
journalctl -u k3s -n 100 --no-pager
И находим такие строки:
дек 03 20:08:36 cachyos-x8664 k3s[194987]: E1203 20:08:36.951520 194987 dns.go:153]
"Nameserver limits exceeded" err="Nameserver limits were exceeded, some nameservers have been omitted,
the applied nameserver line is: 8.8.8.8 1.1.1.1 1.1.1.1"
Что говорит эта ошибка на человеческом:
«В /etc/resolv.conf слишком много DNS-серверов, пришлось некоторые проигнорировать. Оставил: 8.8.8.8, 1.1.1.1, 1.1.1.1»
Проблема: В Arch Linux одновременно работают NetworkManager и systemd-resolved. Оба пишут в /etc/resolv.conf, создавая дубликаты. K3s (точнее, его компонент CoreDNS) видит эти дубликаты, сходит с ума и отказывается работать.
K3s запущен, но DNS сломан. Без работающего DNS Kubernetes — просто красивая абстракция.
Часть 4. DNS в Arch — отдельный квест
Arch и CachyOS используют systemd-resolved + NetworkManager. K3s — ожидает статический /etc/resolv.conf.
В итоге CoreDNS получает:
-
дублирующиеся nameserver;
-
конфликты;
-
и просто отказывается работать.
Решение: сказать NetworkManager «не трогай DNS»
sudo nano /etc/NetworkManager/NetworkManager.conf
Добавить строки:
# В /etc/NetworkManager/NetworkManager.conf
[main]
dns=none # Фикс для Arch: останавливаем NetworkManager от управления DNS
И перезагрузить сервисы (NetworkManager и k3s):
sudo systemctl restart NetworkManager
sudo systemctl restart k3s
Почему в Arch нужно dns=none?
Arch Linux использует современный стек управления сетью: NetworkManager для удобства + systemd-resolved для DNS. Оба хотят управлять /etc/resolv.conf, создавая «войну DNS».
Когда NetworkManager и systemd-resolved пытаются править один файл, в /etc/resolv.conf появляются дублирующиеся nameserver'ы (типа 8.8.8.8 1.1.1.1 1.1.1.1, как в моём примере вышло).
K3s (а точнее — его CoreDNS) видит этот бардак, паникует и выдаёт Nameserver limits exceeded. Pod'ы перестают резолвить домены, кластер ломается.
Параметр dns=none говорит NetworkManager: «Не трогай DNS, пусть этим занимается systemd-resolved». Это останавливает войну и даёт k3s стабильный DNS.
Часть 5. Shell: Fish против Bash
Большинство туториалов используют Bash:
export KUBECONFIG=~/.kube/config
Но у меня установлен Fish shell — альтернатива Bash с другим синтаксисом. При попытке выполнить bash-команды Fish ругается:
~/.bashrc (line 10): Unsupported use of '='. In fish, please use 'set PS1 '[u@h W]$ ''
Что здесь происходит:
-
Команда
export VAR=value— это синтаксис Bash -
Fish использует другой синтаксис:
set -x VAR value -
Когда Fish пытается «прочитать» bash-команды — он не понимает их
Поэтому:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
set -Ux KUBECONFIG ~/.kube/config
Пояснение каждой команды:
-
mkdir -p ~/.kube
Создаём директорию для конфигов Kubernetes. Флаг-pозначает: «создай родительские директории, если их нет; -
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
K3s при установке создаёт конфигурационный файл в/etc/rancher/k3s/k3s.yaml. Копируем его в домашнюю директорию, где у пользователя есть права на чтение; -
sudo chown $USER:$USER ~/.kube/config
Файл скопирован от root, поэтому меняем владельца на текущего пользователя. Иначеkubectlне сможет его читать; -
set -Ux KUBECONFIG ~/.kube/config(команда Fish).set— команда установки переменной в Fish (аналогexportв Bash).-U(universal) — переменная сохранится между перезапусками терминала.-x(export) — делает переменную доступной для дочерних процессов (включаяkubectl).KUBECONFIG— переменная, в которойkubectlищет путь к конфигурации кластера.
Почему это важно:
Без правильной переменной KUBECONFIG утилита kubectl не знает:
-
куда подключиться (адрес API-сервера);
-
какой сертификат использовать для аутентификации;
-
к какому кластеру обращаться.
Мы скопировали конфиг из системной директории в домашнюю, настроили права и сообщили Fish (а через него — kubectl), где искать настройки кластера.
Часть 6. Итог: кластер поднялся
Команда для вывода узлов (физических или виртуальных машин) в кластере:
kubectl get nodes
Вывод команды:
NAME STATUS ROLES AGE VERSION
cachyos-x8664 Ready control-plane,master 20m v1.33.6+k3s1
Разбираем по колонкам:
|
Колонка |
Значение |
Что означает |
|---|---|---|
|
NAME |
|
Имя ноды (берётся из hostname) |
|
STATUS |
|
Нода готова принимать Pod |
|
ROLES |
|
Нода выполняет обе роли (в K3s они объединены) |
|
AGE |
|
Кластер работает 20 минут |
|
VERSION |
|
Версия Kubernetes 1.33.6 с патчами K3s |
Что это значит на практике:
-
Ready— нода прошла все health-чеки, сеть работает, kubelet отвечает; -
control-plane,master— на этой же ноде работает и управляющая плоскость (API, scheduler, controller-manager); -
20m— кластер успел полностью инициализироваться; -
k3s1в версии — это именно K3s, а не ванильный Kubernetes.
Поды:
kubectl get pods -A
coredns Running
metrics-server Running
local-path-provisioner Running
traefik Running
Кластер жив и готов к работе. Теперь можно делать свой HomeLab.
Часть 7. Быстрая инструкция (если вам не нужна история)
-
Скачать бинарник (ссылка на свежий релиз в github):
curl -L https://github.com/k3s-io/k3s/releases/download/v1.33.6%2Bk3s1/k3s -o k3s
chmod +x k3s
sudo mv k3s /usr/local/bin/
-
Создать systemd unit (см. выше)
-
Исправить DNS /etc/NetworkManager/NetworkManager.conf:
[main]
dns=none
-
Настроить kubectl
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
-
Если Fish, то для экспорта:
set -Ux KUBECONFIG ~/.kube/config
-
Запуск сервиса k3s:
sudo systemctl enable --now k3s
kubectl get nodes
Выводы
-
Arch != «современный дистрибутив» в понимании документации. Rolling-release — это сила и боль одновременно;
-
Разница между «установилось» и «работает» — огромная. Особенно в Kubernetes;
-
Логи — главный инструмент диагностики,
journalctl -u k3sспасал снова и снова; -
Shell имеет значение. Если вы не на Bash — готовьтесь к особенностям;
-
Стоило ли это того?
Для обучения — да.
Для комфортной разработки — скорее нет. Minikube работает «из коробки».
Альтернатива: minikube на Arch
Если вам нужен просто обучающий кластер, то можно рассмотреть в сторону minikube, который имеет статью на ArchWiki:
paru -S minikube
minikube start --driver=docker
И всё.
Но если вам хочется именно лёгкий production-like Kubernetes — теперь вы знаете, как запустить k3s вручную.
Нашли ошибку в статье? Знаете более простой способ поставить k3s на Arch? Или прошли через такой же ад? Делитесь в комментариях — вместе сделаем мир Arch и Kubernetes менее болезненным.
Автор: DanLin
