Установка кластера
Есть два пути: простой (k3s — одна команда, рекомендуем новичкам) и классический (kubeadm — всё собирается вручную, для тех, кто хочет разобраться глубже). Начните с k3s, а к kubeadm вернитесь позже, когда захотите понять, что у кластера внутри.
Путь 1: k3s — рекомендуется новичку
k3s — облегчённый, но полностью сертифицированный дистрибутив Kubernetes от Rancher. Он упакован в один бинарный файл и уже содержит всё, что в ванильном k8s приходится ставить отдельно: контейнерный рантайм (containerd), сетевой плагин (flannel), Ingress-контроллер (Traefik), provisioner локальных дисков и простой балансировщик (ServiceLB). Официальный сайт проекта — k3s.io.
Шаг 1. Установите k3s на серверный узел
Зайдите по SSH на будущий control-plane и выполните официальный установочный скрипт:
curl -sfL https://get.k3s.io | sh -
Скрипт скачает бинарник k3s, создаст systemd-сервис и запустит его. Всё. Через 30–60 секунд у вас работающий кластер из одного узла, который совмещает роли control-plane и worker.
Проверим статус службы:
sudo systemctl status k3s
# должно быть: active (running)
Шаг 2. Настройте kubectl для своего пользователя
k3s ставит kubectl вместе с собой, а конфиг доступа к кластеру кладёт в /etc/rancher/k3s/k3s.yaml. Скопируем его в домашний каталог, чтобы работать без sudo:
# создать каталог и скопировать конфиг
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
# проверить доступ
kubectl get nodes
Ожидаемый вывод:
NAME STATUS ROLES AGE VERSION
k8s-node1 Ready control-plane,master 2m v1.31.x+k3s1
~/.bashrc строку export KUBECONFIG=~/.kube/config. Стандартное расположение ~/.kube/config и так работает, но явная переменная не помешает.
Шаг 3. Осмотритесь в кластере
# все системные поды
kubectl get pods -A
# общая информация
kubectl cluster-info
В выводе get pods -A вы увидите системные компоненты: CoreDNS (DNS внутри кластера), Traefik (Ingress), metrics-server, local-path-provisioner (диски) и svclb (балансировщик). Всё это поставилось само — в ванильном Kubernetes каждый компонент устанавливался бы отдельной инструкцией.
Что именно сделал установочный скрипт
Полезно понимать, что произошло за эти полминуты:
- скачан бинарник
k3sв/usr/local/bin/— в нём упакован весь Kubernetes; - создан systemd-сервис
k3s.serviceи добавлен в автозагрузку; - сгенерированы TLS-сертификаты и конфиг в
/etc/rancher/k3s/; - подняты: API-сервер, etcd (для одноузловой установки — поверх встроенной SQLite-обёртки kine либо честный etcd), планировщик, контроллеры;
- развёрнуты системные манифесты из
/var/lib/rancher/k3s/server/manifests/: CoreDNS, Traefik, local-path-provisioner, ServiceLB.
Установка конкретной версии и обновление
По умолчанию скрипт ставит последнюю стабильную версию. Для воспроизводимости (и чтобы все узлы были одинаковыми) версию лучше фиксировать:
# список релизов: https://github.com/k3s-io/k3s/releases
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.31.4+k3s1 sh -
Обновление k3s позже — это повторный запуск того же скрипта с более новой версией (или через систему автоматических обновлений system-upgrade-controller). Перед обновлением обязательно сделайте снапшот etcd — см. страницу «Советы».
Добавление рабочих узлов в k3s
Если у вас несколько машин, подключить их к кластеру проще простого.
Шаг 4. Возьмите токен на сервере
На control-plane узле прочитайте файл с токеном — это «пропуск» для новых узлов:
sudo cat /var/lib/rancher/k3s/server/node-token
# длинная строка вида K10abc...::server:xyz...
Шаг 5. Установите агент на новой машине
На каждой новой машине (предварительно пройдя на ней инструкцию «Подготовка») выполните тот же скрипт, но с двумя переменными: адресом сервера и токеном:
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.50:6443 \
K3S_TOKEN="K10abc...::server:xyz..." sh -
Здесь 192.168.1.50 — IP вашего control-plane узла, а токен — строка из предыдущего шага. Через полминуты на сервере проверьте:
kubectl get nodes
# теперь узлов два: server (control-plane) и новый agent
INSTALL_K3S_VERSION=v1.31.4+k3s1 — поставить конкретную версию; INSTALL_K3S_EXEC="--disable traefik" — установить без встроенного Ingress (если хотите nginx-ingress, см. «Сеть»); --disable servicelb — без встроенного балансировщика (если планируете MetalLB).
Варианты базы состояния в k3s
По умолчанию одиночный сервер k3s использует встроенный etcd — именно его снапшоты описаны на странице «Советы». Старые версии по умолчанию ставили SQLite, а внешнюю базу (MySQL/PostgreSQL) можно подключить параметром --datastore-endpoint. Для дома правильный выбор — встроенный etcd по умолчанию: он проще в бэкапах и является «родным» для Kubernetes.
Перенос kubectl на рабочий компьютер
Управлять кластером удобнее со своего основного компьютера, а не по SSH:
- Установите kubectl на рабочую машину (Windows:
winget install Kubernetes.kubectl; Linux/macOS — пакет или бинарник с kubernetes.io). - Скопируйте конфиг с сервера:
scp ivan@192.168.1.50:~/.kube/config ~/.kube/config(путь в Windows:C:\Users\Имя\.kube\config). - Отредактируйте файл: замените в строке
server:адрес127.0.0.1на IP сервера (https://192.168.1.50:6443).
Теперь kubectl get nodes работает прямо с вашего компьютера — а кластер защищён сертификатами, так что посторонний без этого файла конфига не подключится.
Путь 2: kubeadm — классическая установка
Этот раздел — для тех, кто хочет глубже понять устройство Kubernetes или готовится к сертификациям. Здесь мы вручную поставим контейнерный рантайм, компоненты k8s из официального репозитория и инициализируем кластер. Подробности архитектуры — в документации kubernetes.io.
Шаг 1. Установите containerd
Контейнерный рантайм — программа, которая непосредственно запускает контейнеры. Ставим containerd из репозитория Docker:
# ключи и репозиторий Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install -y containerd.io
Теперь важный момент: containerd нужно настроить на использование systemd в качестве cgroup-драйвера — иначе kubelet и рантайм будут конфликтовать:
# сгенерировать конфиг по умолчанию
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
# включить SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
Шаг 2. Установите kubeadm, kubelet и kubectl
Эти пакеты берутся из официального репозитория Kubernetes:
# ключ репозитория k8s (пример для ветки v1.31)
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /" | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
# зафиксировать версии, чтобы apt не обновил их неожиданно
sudo apt-mark hold kubelet kubeadm kubectl
Шаг 3. Инициализируйте control-plane
Команда kubeadm init поднимает управляющий узел. Единственный обязательный параметр для новичка — подсеть подов (её должен знать сетевой плагин; 10.244.0.0/16 — стандартная для flannel):
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Команда работает 2–5 минут: генерирует сертификаты, запускает etcd, apiserver, scheduler и controller-manager как статические поды. В конце она выведет два важных блока:
- как настроить kubectl для обычного пользователя;
- готовую команду
kubeadm join ...для добавления рабочих узлов — сохраните её.
Настроим kubectl, как советует вывод:
mkdir -p ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
Шаг 4. Установите сетевой плагин (CNI)
В отличие от k3s, ванильный кластер после init ещё не умеет в сеть — узел будет в статусе NotReady. Ставим flannel:
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Через минуту узел должен перейти в Ready:
kubectl get nodes -w
# -w — следить за изменениями; выход по Ctrl+C
Шаг 5. Разрешите приложения на control-plane (для одноузлового кластера)
По умолчанию kubeadm «запрещает» планировщику размещать обычные поды на управляющем узле (это называется taint). Если у вас всего одна машина, снимите ограничение:
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
В многоузловом кластере этого делать не нужно: пусть control-plane занимается управлением, а приложения работают на рабочих узлах.
Добавление узлов в kubeadm
Шаг 6. Подключите рабочий узел
На новой машине повторите шаги 1–2 (containerd + пакеты), а затем выполните команду join, которую вывел kubeadm init:
sudo kubeadm join 192.168.1.50:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:0123456789abcdef...
Если вывод init не сохранился, на control-plane можно сгенерировать команду заново:
kubeadm token create --print-join-command
Полезные параметры kubeadm init
| Параметр | Зачем |
|---|---|
--pod-network-cidr=10.244.0.0/16 | Подсеть подов; обязательна для flannel (он ждёт именно её по умолчанию) |
--kubernetes-version=v1.31.4 | Зафиксировать версию кластера вместо последней доступной |
--apiserver-advertise-address=192.168.1.50 | Адрес, на котором apiserver слушает (важно при нескольких интерфейсах) |
--control-plane-endpoint=k8s-api.home.lan | Стабильное имя точки входа API — пригодится при росте до нескольких control-plane |
--upload-certs | Загрузить сертификаты в кластер — нужно для добавления ещё control-plane узлов |
Полный список параметров и примеры конфигурационного файла kubeadm (KubeadmConfiguration) — в официальной документации kubernetes.io. Для домашнего старта достаточно одного --pod-network-cidr.
Если kubeadm init завис или упал
Типовые точки отказа и их причины:
- завис на
[wait-control-plane]— почти всегда медленный диск (etcd не успевает писать) или не хватает памяти. Смотритеsudo crictl ps -aи журналы компонентов: статические поды лежат в/etc/kubernetes/manifests/, их логи — черезsudo crictl logs; - ошибка
swap— вернитесь к инструкции «Подготовка», swap не отключён; - ошибка про cgroup driver — забыт
SystemdCgroup = trueв конфиге containerd (шаг 1 этого раздела); - порт 6443 занят — на машине уже что-то установлено (возможно, остатки k3s: сначала выполните
k3s-uninstall.sh).
Полный сброс неудачной инициализации:
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes /var/lib/etcd ~/.kube
sudo systemctl restart containerd
# после этого можно повторять kubeadm init
Проверка кластера
Независимо от пути установки финальная проверка одинакова.
Шаг 7. Убедитесь, что узлы Ready
kubectl get nodes -o wide
Что смотреть в выводе:
STATUS: Ready— узел здоров и принимает работу;ROLES— control-plane (управляющий) или <none> (рабочий);INTERNAL-IP— должны быть ваши статические адреса из локальной сети;VERSION— версия Kubernetes.
Шаг 8. Запустите тестовый под
# быстрый тест: запустить nginx
kubectl run test-nginx --image=nginx
# посмотреть, что под появился и работает
kubectl get pods -o wide
# удалить тестовый под
kubectl delete pod test-nginx
Если под перешёл в статус Running — поздравляем, у вас работающий домашний Kubernetes-кластер.
Шаг 9. Поставьте автодополнение kubectl (приятная мелочь)
# автодополнение по Tab для bash
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
source ~/.bashrc
# теперь можно писать просто: k get pods
Как понять, что вывод get nodes здоровый
Разберём пример вывода подробно — к нему вы будете возвращаться каждый день:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE CONTAINER-RUNTIME
k8s-node1 Ready control-plane,master 3d v1.31.4+k3s1 192.168.1.50 Debian GNU/Linux 12 containerd://2.0.x
k8s-node2 Ready <none> 2d v1.31.4+k3s1 192.168.1.51 Debian GNU/Linux 12 containerd://2.0.x
STATUS: Readyу всех узлов — главный индикатор здоровья. Всё остальное (NotReady, SchedulingDisabled) требует разбора на странице «Советы».ROLES: у k3s-сервера две роли (он и управляет, и работает), у агентов —<none>, что означает «просто рабочий».VERSIONдолжен совпадать на всех узлах — если нет, обновите отстающий узел (см. «Советы»).INTERNAL-IP— ваши статические адреса из инструкции «Подготовка». Если здесь вдруг адрес из другой подсети или 127.0.0.1 — проверяйте hostname и /etc/hosts.
/usr/local/bin/k3s-uninstall.sh на сервере и /usr/local/bin/k3s-agent-uninstall.sh на агентах. Они аккуратно сносят кластер и все его данные.