Кластер k8s
Предлагаю не душнить с описанием того, что такое kubernetes. Раз ты сюда пришёл, значит уже знаешь что это и скорее всего docker'a тебе стало мало
Данное пособие ни в коем случае не претендует на 100% мануал how to. Данное пособие, как и все статьи на этом сайте - это шпаргалка "как делал я и у меня это получилось"
Поехали.
Для организации не просто minikube, а реального кластера k8s и возможной реализации его в боевых условиях, были использованы виртуальные машины, обладающие следующими характеристиками:
CPU - 2 Core
RAM - 4 Gb
HDD - 20 Gb
NET - 10.0.0.0/24
Хостнеймы:
k8s-master, k8s-wn01, k8s-wn02
Перед выполнением работ необходимо отключить swap в /etc/fstab
Все действия выполняются от привилегированного пользователя root
Следующую последовательность необходимо выполнить на всех нодах
cat << EOF | tee /etc/hosts
127.0.0.1 localhost
10.0.0.10 k8s-master
10.0.0.11 k8s-wn01
10.0.0.12 k8s-wn02
EOF
Добавляем необходимые модули ядра в автозапуск
cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
И загружаем их
modprobe overlay && modprobe br_netfilter
Подправим возможность контроля обработки трафика через bridge в netfilter
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
Применим изменения
sysctl --system
Установим среду выполнения контейнеров, но...
...но, по состоянию на 19 октября 2026, в репах дебиана, версия containerd = 1.7 Версия кубера на это ругается, что мол надо обновиться, а то в будущих релизах они это поддерживать не будут, поэтому установим свежий бинарник с гитхаба. Смотрим -> тут <- номер версии и подставляем в переменную ниже
export CONTAINERD_VERSION="2.4.2"
apt install wget
wget https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz
tar -C /usr/local -xzf containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz
Установив ручками бинарник, юнита для управления не будет. Стянем его тоже с гитхаба
wget -O /etc/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
Сгенерируем необходимый конфиг
mkdir /etc/containerd
containerd config default | tee /etc/containerd/config.toml
И стартуем демона
systemctl daemon-reload
systemctl enable --now containerd
Для стабильной работы движка необходимо включить SystemdCgroup. Давайте выебнемся и сделаем это sed’ом
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
Отлично!
Следующим этапом нам необходимо затащить в систему runc - инструмент, который непосредственно создает и запускает контейнеры на узле Kubernetes. Смотрим актуальную версию на -> гитхабе <- и подставляем номер в строку ниже
export RUNC_VERSION="1.6.0-rc.1"
wget https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.amd64
install -m 755 runc.amd64 /usr/local/sbin/runc
Ну и для принятия изменений рестартуем движок
systemctl restart containerd
Переходим к устанавке кубера и необходимых компонентов, предварительно выяснив актуальную версию
apt install -y apt-transport-https ca-certificates curl gpg
Добавим ключ цифровой подписи. Обратите внимание, я взял версию из Release history и подставил к версии в команде ниже. На момент написания статьи, она была самой актуальной.
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.37/deb/Release.key | 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.37/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
Обновляем кэш пакетов
apt update
ну и ставим заветное
apt install -y kubelet kubeadm kubectl
Для понимания
kubelet - контролирует работу подов и управляет ими
kubeadm - управление кластером kubernetes
kubectl - утилита для ввода команд
Установка завершена! Для просмотра версии скомандуем
kubectl version --client --output=yaml
Инициализация кластера
Следующую последовательность действий необходимо выполнить ТОЛЬКО на мастере
kubeadm init --pod-network-cidr=10.244.0.0/16
На какое-то время покажется, что сервер подвис. Надо будет подождать, пока не побегут букафффки и в конце появится Your Kubernetes control-plane has initialized successfully!
Выгрузим переменную KUBECONFIG в /etc/kubernetes/admin.conf
Не забываем про безопасность! Ибо запускать комнады управления кубером могут только пидарасы! Мы же ровные пацанчики, поэтому делаем следующее
mkdir /home/<ваш пользователь>/.kube
cp -i /etc/kubernetes/admin.conf /home/swapon/.kube/config
chown <ваш пользователь>:<ваш пользователь> /home/swapon/.kube/config
Выходим из рута
exit
Смотрим, что у нас вообще получилось
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 8m29s v1.37.1
Отлично! Судя по столбику ROLES считаем, что мастер развёрнут, но статус NotReady свидетельствует тому, что нам, для полноты картины минимального окружения, нехватает инструмента для настройки сетевых интерфейсов - CNI. У большинства на устах - это Calico, так давайте не будем выёбываться с другими и установим его
И -> снова выясним <- какая версия на сегодняшний день актуальная, подставим необходимы цифры в строку ниже и скомандуем
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.33.0/manifests/calico.yaml
Спустя пару минут можно убедиться
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 11m v1.37.1
что статус сменился на Ready и на данном этапе у нас полностью настроенный мастер. Переходим к нодам. Сгенерируем токен для присоединения нод
kubeadm token create --print-join-command
Должна появиться строчка типа
kubeadm join 10.0.0.10:6443 --token dlp1w2.jxvny6z5wivmygiz --discovery-token-ca-cert-hash sha256:831135df3cb9cf8813f66f05c319d7cb3559fed0769c539cb47c32a11b0b28b9
Вводим её на всех вводимых в кластер нодах
Снова побегут букафффки по экрану и в самом конце мы должны будем увидеть строку
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
Буквально сразу, на мастере, по знакомой нам уже команде kubectl get nodes увидим, что список пополнился
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 33m v1.37.1
k8s-wn01 NotReady <none> 22s v1.37.1
k8s-wn02 NotReady <none> 11s v1.37.1
Ждём пару минут, чтоб статус всех нод перешёл в Ready
Для просмотра более детальной информации, можно добавить ключ -o с параметром wide
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master Ready control-plane 35m v1.37.1 10.0.0.10 <none> Debian GNU/Linux 13 (trixie) 6.12.113+deb13-amd64 (amd64) containerd://2.4.2
k8s-wn01 Ready <none> 2m2s v1.37.1 10.0.0.11 <none> Debian GNU/Linux 13 (trixie) 6.12.113+deb13-amd64 (amd64) containerd://2.4.2
k8s-wn02 Ready <none> 111s v1.37.1 10.0.0.12 <none> Debian GNU/Linux 13 (trixie) 6.12.113+deb13-amd64 (amd64) containerd://2.4.2
Ну всё! Мы кросссафффчЕГИ…! Замоторили кластер кубера. Можно смело добавлять строчку в своё резюме на хэдхантере - невъебенный девопс и ждать оффера с 300к/сек