← Kubernetes локально
9 мин · средне · Урок 8 из 8

За пределами ноутбука: k3s, MicroK8s, k0s, Talos

Кластер на своём сервере или VPS: что ставить, какие порты открывать и почему kubeadm стоит трогать только ради понимания control plane.

Кластер в контейнерах на ноутбуке хорош для быстрых проверок. Он не переживёт закрытие крышки, не отдаст сервис коллеге и не покажет, как ведут себя настоящие ноды на настоящей сети. Как только нужен постоянно живой кластер с внешним адресом, разговор переходит на серверы: домашнюю машину, старый мини-ПК или VPS за несколько долларов.

Ниже шесть вариантов, от самого простого до самого поучительного.

ВариантГде работаетВторая нодаЧто уже внутри
k3sтолько LinuxK3S_URL и K3S_TOKENTraefik, ServiceLB, local-path
MicroK8sLinux напрямую, macOS и Windows через VMmicrok8s add-node, HA с трёх нодаддоны одной командой
k0sтолько Linuxk0sctl по SSHStorageClass ставится отдельно
Talosсвоя ОС без SSH и shell--controlplanes, --workersуправление только через talosctl
vclusterповерх готового кластераноды берутся у хостасвой control plane в namespace
kubeadmтолько Linuxkubeadm joinCNI и StorageClass ставятся отдельно

k3s на своём сервере или VPS

Версия v1.36.4+k3s1 от 2026-08-27. Каналы stable и latest сейчас указывают на неё же. Работает только на Linux: x86_64, armhf, arm64.

Требования скромные: серверу нужны 2 CPU и 2 GB RAM, агенту хватает 1 CPU и 512 MB. Порты: TCP 6443 для API server, UDP 8472 для flannel VXLAN между нодами, TCP 10250 для kubelet. Hostname у всех нод должны быть уникальными, иначе ноды перезаписывают друг друга.

curl -sfL https://get.k3s.io | sh -
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.36.4+k3s1 sh -

cat /var/lib/rancher/k3s/server/node-token
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

Вторая нода подключается к первой по адресу API server и токену из файла выше:

curl -sfL https://get.k3s.io | K3S_URL=https://server:6443 K3S_TOKEN=$TOKEN sh -

Удаляется всё одним скриптом: /usr/local/bin/k3s-uninstall.sh.

Что k3s приносит с собой

ServiceLB, он же klipper-lb, отвечает за Service типа LoadBalancer. На каждый такой Service создаётся DaemonSet в namespace kube-system с подами вида svc-…. Эти поды биндят hostPort и садятся только на ноды, где нужный порт свободен. Отсюда типичная картина: второй LoadBalancer на том же порту просто не получает поды. Отключается флагом --disable=servicelb, и это обязательный шаг, если ставишь MetalLB.

Traefik v3 разворачивается автоматически и занимает 80 и 443. Чарт лежит в /var/lib/rancher/k3s/server/manifests/traefik.yaml, но править этот файл нельзя: настройки задают через ресурс HelmChartConfig. Полностью снимается через --disable=traefik. Gateway API включается значением providers.kubernetesGateway.enabled: true, поддерживается Gateway API v1.4.

StorageClass - local-path, дефолтный, данные складываются в /var/lib/rancher/k3s/storage.

С этим StorageClass связана неочевидная грабля. Манифесты из каталога server/manifests переприменяются при каждом старте k3s. Поэтому local-path сам возвращает себе статус дефолтного, даже если ты назначил дефолтным другой класс. Поставил Longhorn, сделал его default, перезагрузил сервер - и снова два кандидата или снова local-path по умолчанию.

Прочее по мелочи: firewalld и ufw придётся настраивать под порты выше. На Raspberry Pi в cmdline нужно дописать cgroup_memory=1 cgroup_enable=memory. На RHEL 10 требуется dnf install -y kernel-modules-extra.

MicroK8s

Дистрибутив от Canonical, ставится через snap. Текущий трек 1.36, в канале latest/stable лежит v1.36.2. Проект активен.

Первая же неприятность встречает в документации: страница getting-started отстала и показывает --channel=1.35. Канал стоит указывать явно.

sudo snap install microk8s --classic --channel=1.36
sudo usermod -a -G microk8s $USER
mkdir -p ~/.kube && chmod 0700 ~/.kube
su - $USER
microk8s status --wait-ready
microk8s kubectl get nodes

Управление жизненным циклом: microk8s stop, microk8s start, microk8s reset.

Linux ставится напрямую, а Windows и macOS - только через виртуальную машину (Multipass или WSL2). На Raspberry Pi работает.

Сильная сторона MicroK8s - аддоны одной командой:

microk8s enable dns hostpath-storage ingress metrics-server registry

Встроенный реестр образов поднимается на localhost:32000. Дополнительный набор аддонов включается через microk8s enable community.

Важное изменение: в 1.36 сняты с поддержки аддоны dashboard, minio и kwasm. Kubernetes Dashboard в MicroK8s больше нет, и это ломает практически все старые туториалы, которые начинались с microk8s enable dashboard.

Multi-node устроен просто: microk8s add-node на первой ноде печатает готовую команду join для второй. При трёх и более нодах HA включается сама, отдельно настраивать её не нужно. Ноды тут - настоящие машины или виртуалки, не контейнеры.

По ресурсам минимум 540 MB RAM, рекомендуется 4 GB и 20 GB диска. StorageClass даёт аддон hostpath-storage, класс называется microk8s-hostpath; документация прямо предупреждает, что для продакшена он не годится.

k0s

Ещё один кластер одним бинарником. Версия v1.36.4+k0s.0 от 2026-08-31, вспомогательный k0sctl - v0.32.2 от 2026-07-28. Только Linux с systemd или OpenRC, архитектуры amd64, arm64 и armv7. Версии под macOS нет.

curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo sh
sudo k0s install controller --single --start
sudo k0s status
sudo k0s kubectl get nodes

Multi-node разворачивают через k0sctl по SSH: k0sctl init > k0sctl.yaml, правишь spec.hosts, потом k0sctl apply --config k0sctl.yaml и k0sctl kubeconfig > kubeconfig. То есть описываешь машины в одном файле, а раскатку k0sctl делает сам.

Кому подходит: тем, кому нужен настоящий кластер на VPS одним бинарником, без контейнерной обёртки и без сложности kubeadm. StorageClass надо ставить отдельно.

Talos Linux

Версия v1.13.9 от 2026-08-19. Это не пакет для установки в существующую систему, а целая операционная система под Kubernetes. Immutable: без SSH, без shell, без пакетного менеджера. Всё управление идёт через gRPC API и утилиту talosctl.

Попробовать можно локально, в контейнерах:

brew install siderolabs/tap/talosctl
talosctl cluster create docker
kubectl get nodes -o wide
talosctl cluster destroy

У docker-провайдера есть флаги --controlplanes, --workers, --cpus-controlplanes, --memory-controlplanes, --kubernetes-version, -p/--exposed-ports, --name и --cidr. Нужен Docker 18.03 и выше. На Linux перед запуском требуется sudo modprobe br_netfilter, без него падает Flannel.

Ограничение контейнерного режима: API upgrade и reset в нём не работают. То есть ровно те операции, ради которых Talos и берут в проде, локально в контейнерах не проверить.

Кому подходит: тем, кто изучает immutable-инфраструктуру и хочет кластер, который нельзя починить руками через ssh. Новичку в Kubernetes не подходит: отсутствие shell убирает привычные способы посмотреть, что происходит на ноде.

vcluster

Версия v0.36.1 от 2026-08-03. Это не способ поднять кластер с нуля. Нужен уже работающий хост-кластер (kind, k3d, k3s), внутри которого в отдельном namespace поднимается собственный API server и control plane, а ноды синхронизируются с хоста.

brew install loft-sh/tap/vcluster
vcluster create my-vcluster --namespace team-x
vcluster delete my-vcluster --namespace team-x

Кому подходит: мультитенантность, изолированные окружения под CI, раздача «своих кластеров» нескольким командам поверх одного физического. Одному человеку, который учится на ноутбуке, это лишний слой.

kubeadm

Официальный инструмент бутстрапа кластера, часть Kubernetes v1.37.0. Ставится только на Linux из deb или rpm. Требования: 2 GiB RAM на машину, 2 CPU на control plane, выключенный swap, уникальные hostname, MAC-адреса и product_uuid.

kubeadm init --pod-network-cidr=<CIDR>
mkdir -p $HOME/.kube && sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config && sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f <cni-manifest>
kubeadm join <host>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

Обрати внимание на третью строку. CNI в комплект не входит, сеть надо выбрать и поставить самому, и до этого момента ноды остаются NotReady, а поды не запускаются. Ровно на этом шаге спотыкается большинство тех, кто впервые запустил kubeadm init.

Зачем его вообще трогают. kubeadm не прячет состав control plane: ты своими руками видишь /etc/kubernetes/manifests, статические поды apiserver, controller-manager, scheduler и etcd, сертификаты, токены присоединения. k3s и MicroK8s всё это упаковывают в один процесс, и понимание, из чего состоит кластер, оттуда не появляется. Для подготовки к CKA это обязательный опыт.

Для быстрого локального старта это худший вариант в списке. Отдельная Linux-машина, ручное выключение swap, отдельная установка CNI, StorageClass тоже отдельно. Полчаса работы там, где kind справляется за тридцать секунд.

Что выбирать

Нужен постоянно живой кластер на VPS с публичным адресом и минимумом возни - k3s. Один curl, Traefik и StorageClass уже внутри.

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

Нужен кластер на VPS без контейнерной обёртки и хочется описать все машины одним файлом - k0s с k0sctl.

Изучаешь immutable-инфраструктуру и хочешь понять, как живут ноды без ssh - Talos.

Нужно раздать несколько изолированных кластеров поверх одного - vcluster.

Готовишься к CKA или хочешь понимать, из чего собран control plane - kubeadm, и только ради этого.

Коротко

Прошли материал до конца? Отметьте урок пройденным.