MAATRIX / Блог / k3s на Ubuntu 24.04: пошаговая установка

k3s на Ubuntu 24.04: пошаговая установка

k3s на Ubuntu 24.04: пошаговая установка

MAATRIX

Полноценный 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 установлен, но неактивен. Включите его без правил — отрежете и себя, и половину внутрикластерной сети.

ПортПротоколКому открыватьЗачем
6443TCPваш IP и агент-узлыKubernetes API
8472UDPтолько другим узламFlannel VXLAN
10250TCPузлам кластераkubelet: logs, exec, метрики
2379–2380TCPтолько серверным узламвстроенный 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 — десятки моделей в одном окне. Оплата картой РФ и по СБП.