k3s на Ubuntu 24.04: пошаговая установка
Полноценный Kubernetes на одном VPS ставится полдня и съедает пару гигабайт ещё до первого пода. k3s — тот же сертифицированный Kubernetes API в одном бинарнике, и на Ubuntu 24.04 он разворачивается примерно за минуту. Ниже — установка по шагам с граблями, специфичными именно для 24.04: nftables, systemd-resolved, needrestart и заблокированные реестры.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что вы получаете и что нужно от сервера
k3s — дистрибутив Kubernetes от SUSE в одном файле примерно на 70 МБ. Внутри уже лежит всё, что обычно ставится отдельно: containerd, Flannel, CoreDNS, балансировщик ServiceLB, ingress-контроллер Traefik, metrics-server и провайдер томов local-path. Состояние хранится в SQLite через слой kine, а не в etcd, поэтому одиночный узел не платит за консенсус. API стандартный — манифесты и Helm-чарты работают как в «большом» кластере.
Критично проверить до установки тип виртуализации: k3s требует KVM, а на контейнерных VPS (OpenVZ, LXC без вложенности) он либо не стартует, либо падает на cgroups.
systemd-detect-virt
stat -fc %T /sys/fs/cgroup/
Первая команда должна ответить kvm, вторая — cgroup2fs. Ответы lxc или openvz означают, что нужен другой сервер, настройками это не лечится. Ядро подойдёт любое штатное — и 6.8 в GA-варианте, и 6.14 в HWE-сборке. Минимум по памяти — 2 ГБ, раскладка в материале сколько RAM нужно для k3s.
Подготовка Ubuntu 24.04: пять проверок до установки
Имя узла. k3s берёт имя ноды из hostname, и если у провайдера оба ваших сервера называются ubuntu, второй не присоединится к кластеру: sudo hostnamectl set-hostname k3s-uk-1. Затем sudo apt update && sudo apt full-upgrade -y, и если приехало новое ядро — перезагрузитесь до установки k3s, а не после.
Swap. k3s, в отличие от ванильного kubelet, стартует и со свопом, но учёт памяти тогда врёт: под с лимитом 512 МБ уезжает в своп вместо честного рестарта. Если swapon --show непуст — sudo swapoff -a и закомментировать строку swap в /etc/fstab.
Бэкенд iptables. Ubuntu 24.04 использует nftables через обёртку iptables-nft, и k3s с ним дружит. Ломается всё, если остались правила в legacy-режиме от старого Docker: пакеты обрабатывают две подсистемы вперемешку, трафик подов теряется без причины.
iptables -V
sudo iptables-legacy -S | wc -l
Первая команда должна ответить iptables v1.8.10 (nf_tables), вторая на чистой системе — 3 (три дефолтные политики). Больше — чистите: sudo iptables-legacy -F, затем sudo update-alternatives --set iptables /usr/sbin/iptables-nft.
Время. Расхождение часов ломает проверку сертификатов kubelet: timedatectl должен показывать System clock synchronized: yes.
needrestart. Специфика именно 24.04: пакет в неинтерактивном режиме перезапускает службы после каждого apt upgrade — для k3s это 20–40 секунд недоступности API ночью. Приведите строку в /etc/needrestart/needrestart.conf к виду $nrconf{restart} = 'l';, а в /etc/apt/apt.conf.d/50unattended-upgrades выключите Unattended-Upgrade::Automatic-Reboot.
Про rootless-режим: в 24.04 включено ограничение AppArmor на непривилегированные user namespaces, и k3s server --rootless падает с rootlesskit: failed to setup UID/GID map: newuidmap ... Operation not permitted. Снимается через kernel.apparmor_restrict_unprivileged_userns=0, но ради удобства этого делать не стоит.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть k3sУстановка k3s: команда и её параметры
Каноническая установка — одна строка:
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=v1.33 sh -
Скрипт кладёт бинарник в /usr/local/bin/k3s, создаёт симлинки kubectl, crictl и ctr, пишет юнит k3s.service, генерирует kubeconfig /etc/rancher/k3s/k3s.yaml и запускает службу. На VPS 2 vCPU / 2 ГБ в Лондоне он отрабатывает за 40 секунд, ещё 25 секунд узел переходит в Ready.
Канал задан явно не случайно: по умолчанию берётся stable, который со временем уезжает вперёд, и через полгода второй узел приедет с другой версией. Точнее фиксирует INSTALL_K3S_VERSION=v1.33.5+k3s1; куда каналы смотрят сейчас, скажет curl -s https://update.k3s.io/v1-release/channels.
Флаги в командной строке — плохая идея, они теряются при переустановке. k3s читает /etc/rancher/k3s/config.yaml, и файл можно положить до установки:
sudo mkdir -p /etc/rancher/k3s
sudo tee /etc/rancher/k3s/config.yaml >/dev/null <<'EOF'
node-name: k3s-uk-1
write-kubeconfig-mode: "0640"
write-kubeconfig-group: "k3s"
tls-san:
- k3s.example.com
secrets-encryption: true
EOF
tls-san добавляет в сертификат API дополнительные имена — без него обращение по домену даёт x509: certificate is valid for 127.0.0.1, 10.0.0.5, not k3s.example.com. secrets-encryption шифрует секреты, которые иначе лежат почти открытым текстом. А write-kubeconfig-mode, который во всех мануалах ставят в 0644, делает файл с правами админа кластера читаемым любому локальному пользователю — аккуратнее группа и 0640.
Дальше скопируйте /etc/rancher/k3s/k3s.yaml в ~/.kube/config, смените владельца, поставьте chmod 600 и пропишите export KUBECONFIG=~/.kube/config в ~/.bashrc. Иначе kubectl get nodes ответит error loading config file ...: permission denied, а без переменной вовсе — The connection to the server localhost:8080 was refused.
Проверяем кластер и разбираем ошибки первых минут
Картину дают systemctl status k3s, kubectl get nodes -o wide и kubectl get pods -A. Здоровый узел выглядит так:
NAME STATUS ROLES AGE VERSION OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k3s-uk-1 Ready control-plane,master 72s v1.33.5+k3s1 Ubuntu 24.04.3 LTS 6.8.0-79-generic containerd://2.0.5-k3s2
В kube-system поднимаются coredns, local-path-provisioner, metrics-server, traefik, svclb-traefik-* и разовый helm-install-traefik. Цифры для сверки: на узле с 2 ГБ free -m показывал 748 МБ занятых с Traefik и 612 МБ при disable: traefik, а /var/lib/rancher/k3s весит около 1,5 ГБ.
CoreDNS в CrashLoopBackOff. В kubectl logs -n kube-system deploy/coredns строка [FATAL] plugin/loop: Loop (127.0.0.1:53 -> :53) detected for zone ".". Виноват systemd-resolved: в /etc/resolv.conf прописан стаб 127.0.0.53, и CoreDNS пересылает запросы сам себе. Обычно k3s это распознаёт, но при нестандартном resolv.conf добавьте в config.yaml строку resolv-conf: /run/systemd/resolve/resolv.conf.
Узел висит в NotReady. На серверах с несколькими интерфейсами Flannel нередко выбирает не тот: проверьте journalctl -u k3s -n 200 | grep -i flannel и задайте его явно — flannel-iface: ens3.
The connection to the server 127.0.0.1:6443 was refused сразу после установки — просто рано; дайте минуту и смотрите journalctl -u k3s -f. Остальные сбои разобраны в статьях частые ошибки k3s и k3s: под не запускается.
Фаервол ufw и сеть Flannel
На свежей Ubuntu 24.04 ufw установлен, но неактивен. Включите его без правил — отрежете и себя, и половину внутрикластерной сети.
| Порт | Протокол | Кому открывать | Зачем |
|---|---|---|---|
| 6443 | TCP | ваш IP и агент-узлы | Kubernetes API |
| 8472 | UDP | только другим узлам | Flannel VXLAN |
| 10250 | TCP | узлам кластера | kubelet: logs, exec, метрики |
| 2379–2380 | TCP | только серверным узлам | встроенный etcd в HA-режиме |
Минимальный набор для одиночного узла:
sudo ufw allow 22/tcp
sudo ufw allow from 203.0.113.7 to any port 6443 proto tcp
sudo ufw allow from 10.42.0.0/16 to any
sudo ufw allow from 10.43.0.0/16 to any
sudo ufw default deny incoming && sudo ufw enable
Две средние строки — самое важное и самое пропускаемое. 10.42.0.0/16 — сеть подов, 10.43.0.0/16 — сеть сервисов k3s. Без них любой под, обращающийся к API через kubernetes.default (а это всё, что использует ServiceAccount — от ingress-контроллера до cert-manager), получает dial tcp 10.43.0.1:443: i/o timeout. Выглядит как проблема приложения, а создал её ваш же фаервол.
Для многоузловой схемы важен ещё пункт: в /etc/default/ufw политика форварда по умолчанию DROP, и межузловой трафик подов умирает — приведите строку к DEFAULT_FORWARD_POLICY="ACCEPT" и выполните sudo ufw reload. Агент подключается токеном из /var/lib/rancher/k3s/server/node-token, из-за которого 6443 нельзя оставлять открытым в мир. И учтите: VXLAN не шифруется — для нод в разных ДЦ переключайте бэкенд на flannel-backend: wireguard-native.
На одиночном узле ufw можно и не включать вовсе, закрыв лишнее сетевым фильтром провайдера.
Образы, реестры и первое приложение
Проблема, которой нет в англоязычных мануалах: с российских адресов Docker Hub и registry.k8s.io работают нестабильно или не работают вовсе. Под уходит в ImagePullBackOff, а в kubectl describe pod видно:
Failed to pull image "nginx:1.29-alpine": failed to resolve reference: failed to do request:
Head "https://registry-1.docker.io/v2/library/nginx/manifests/1.29-alpine": dial tcp ...:443: i/o timeout
Лечится зеркалами — k3s читает /etc/rancher/k3s/registries.yaml:
sudo tee /etc/rancher/k3s/registries.yaml >/dev/null <<'EOF'
mirrors:
docker.io:
endpoint:
- "https://mirror.gcr.io"
EOF
sudo systemctl restart k3s
Грабля, на которую наступают почти все: соблазн отредактировать /var/lib/rancher/k3s/agent/etc/containerd/config.toml напрямую. k3s генерирует его заново при каждом старте из registries.yaml, так что правки исчезнут после рестарта — править нужно config.toml.tmpl рядом. Зеркало проверяется загрузкой sudo k3s ctr images pull docker.io/library/nginx:1.29-alpine. И скажу прямо: зеркала — костыль, их доступность меняется, а теги отстают; сервер в Лондоне или Париже снимает вопрос целиком.
Выкатываем первое приложение — три команды:
kubectl create deployment web --image=nginx:1.29-alpine --replicas=2
kubectl expose deployment web --port=80 --target-port=80
kubectl create ingress web --class=traefik --rule="app.example.com/*=web:80"
Проверка без DNS: curl -H "Host: app.example.com" http://<ip-сервера>/ — придёт страница nginx. Если под svclb-traefik-* завис в Pending с 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports, на хосте занят 80-й или 443-й порт: кем — покажет sudo ss -lntp | grep -E ':80|:443'. Освобождайте порты или отключайте ServiceLB через disable: servicelb.
Класс хранилища по умолчанию — local-path: PVC становится каталогом в /var/lib/rancher/k3s/storage/ и привязывает под к узлу, на другую ноду данные не поедут. Для кластера нужен Longhorn или NFS, и тут снова специфика Ubuntu: Longhorn требует open-iscsi и конфликтует с multipathd, который в 24.04 перехватывает его устройства (sudo systemctl disable --now multipathd).
Какой сервер под k3s взять в MAATRIX
Пустой узел k3s с Traefik занимает около 750 МБ RAM и 1,5 ГБ диска, а за несколько месяцев активных деплоев /var/lib/rancher/k3s вырастает до 8–15 ГБ: сборщик мусора containerd чистит образы только при заполнении диска на 85%.
Минимум: 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe. На 2 ГБ кластер поднимется, но под ваши поды останется чуть больше гигабайта, и первая же сборка образа упрётся в OOM. 4 ГБ — честный минимум для одного-двух небольших сервисов с базой.
Комфортно: 4 vCPU, 8 ГБ RAM, 120–160 ГБ NVMe. Помещается четыре-пять сервисов, PostgreSQL, мониторинг и запас на пересборку без выталкивания прода в своп.
HA-кластер: три серверных узла со встроенным etcd, по 2 vCPU и 4 ГБ. Требование тут не к памяти, а к диску: etcd чувствителен к задержкам fsync, на медленном хранилище вы получите etcdserver: request timed out и перевыборы лидера. Все VPS MAATRIX — KVM и NVMe, так что проверка systemd-detect-virt из первой секции пройдёт.
Локация. По умолчанию берите UK (Лондон): k3s постоянно ходит в реестры и Helm-репозитории, а из Лондона они работают без зеркал и registries.yaml. Пинг 8–15 мс до Амстердама и Франкфурта, 40–55 мс до Москвы — для админского доступа незаметно. Франция — по тем же причинам, если аудитория в континентальной Европе. Россию берите под 152-ФЗ, сразу закладывая зеркала. США — если сервисы кластера ходят в зарубежные ИИ-API и нужен чистый IP.
Заказ занимает несколько минут: выбираете локацию и конфигурацию, отмечаете приложение k3s — сервер приедет с развёрнутым кластером, останется забрать kubeconfig. Ручная настройка разобрана в материале как установить и настроить k3s на VPS, выбор оркестратора — в сравнении k3s против Docker Swarm, конфигурацию можно подобрать здесь. Оплата — картами российских банков, по СБП, криптой или токеном MAAT.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть k3sОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Можно ли поставить k3s на Ubuntu 24.04 внутри LXC?
Технически да, но только на своём гипервизоре с вложенностью, снятым профилем AppArmor и прокинутым /dev/kmsg. На типовом контейнерном VPS этих настроек не даст никто — проверьте systemd-detect-virt и берите KVM.
Чем опасен curl | sh и как поставить без него?
Тем, что вы выполняете от root скрипт, который не читали. Альтернатива: скачать install.sh и бинарник k3s отдельно, сверить сумму по sha256sum-amd64.txt, положить его в /usr/local/bin/k3s и запустить установщик с INSTALL_K3S_SKIP_DOWNLOAD=true.
Как удалить k3s начисто?
На серверном узле — sudo /usr/local/bin/k3s-uninstall.sh, на агенте — k3s-agent-uninstall.sh. Скрипт сносит службу, бинарник, /etc/rancher/k3s и весь /var/lib/rancher/k3s, включая storage с данными ваших PVC, — скопируйте их заранее.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.