Блог-шпаргалка системного администратора
Кластер k8s
Кластер k8s

Кластер 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к/сек

← Назад к списку