Установка кластера

Есть два пути: простой (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
Совет Чтобы конфиг подхватывался на каждом новом входе по SSH, добавьте в конец файла ~/.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 каждый компонент устанавливался бы отдельной инструкцией.

Что именно сделал установочный скрипт

Полезно понимать, что произошло за эти полминуты:

Установка конкретной версии и обновление

По умолчанию скрипт ставит последнюю стабильную версию. Для воспроизводимости (и чтобы все узлы были одинаковыми) версию лучше фиксировать:

# список релизов: 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
Полезные опции установки k3s Скрипт принимает параметры через переменные окружения. Примеры: 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:

  1. Установите kubectl на рабочую машину (Windows: winget install Kubernetes.kubectl; Linux/macOS — пакет или бинарник с kubernetes.io).
  2. Скопируйте конфиг с сервера: scp ivan@192.168.1.50:~/.kube/config ~/.kube/config (путь в Windows: C:\Users\Имя\.kube\config).
  3. Отредактируйте файл: замените в строке 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
Внимание Перед этим шагом убедитесь, что swap отключён и модули ядра загружены — иначе kubelet не стартует. Всё это было на странице «Подготовка».

Шаг 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, как советует вывод:

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 завис или упал

Типовые точки отказа и их причины:

Полный сброс неудачной инициализации:

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

Что смотреть в выводе:

Шаг 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
Удаление k3s (если захотите начать заново) В комплекте с k3s идут скрипты удаления: /usr/local/bin/k3s-uninstall.sh на сервере и /usr/local/bin/k3s-agent-uninstall.sh на агентах. Они аккуратно сносят кластер и все его данные.