Разворачиваем кластер Kubernetes (kubeadm) на Ubuntu 22.04

Ubuntu / Containers Вчера, 23:44 sobir 23 0


Развернём полноценный Kubernetes (не k3s и не microk8s) через kubeadm на трёх серверах с Ubuntu 22.04 LTS. Версия Kubernetes — v1.33.13 (LTS), container runtime — containerd, CNI — Calico через Tigera Operator.

Требования


  • 3 сервера на Ubuntu 22.04 LTS: один под control-plane, два под worker.
  • Каждый сервер — минимум 2 vCPU и 2 GB RAM (официальный минимум kubeadm; на практике control-plane комфортнее от 4 GB).
  • Уникальные hostname, MAC-адрес и product_uuid на каждой ноде — стандартно для отдельных машин, но стоит проверить при клонировании VM.
  • Полная сетевая связность между всеми тремя нодами — напрямую или через VPN/туннель.
  • Root-доступ или sudo на каждой ноде.


Проверить product_uuid можно так:
cat /sys/class/dmi/id/product_uuid


Между нодами должны быть открыты порты:
  • 6443 — Kubernetes API server (control-plane).
  • 2379–2380 — etcd client/peer (control-plane).
  • 10250 — kubelet API (все ноды).
  • 10251, 10252 — scheduler и controller-manager (control-plane).
  • 30000–32767 — NodePort Services (worker-ноды).


1. Базовая подготовка ОС (на всех нодах)


Задаём имя хоста — на каждой ноде своё:
hostnamectl set-hostname master1


Ставим chrony и отключаем systemd-resolved в пользу статичного /etc/resolv.conf:
apt update
apt install chrony -y
systemctl disable --now systemd-resolved
rm -f /etc/resolv.conf
echo 'nameserver 1.1.1.1' > /etc/resolv.conf
echo 'nameserver 8.8.8.8' >> /etc/resolv.conf
nslookup ya.ru


Отключаем ufw, если firewall управляется на другом уровне инфраструктуры:
systemctl disable --now ufw


Обновляем систему и перезагружаемся:
apt update
apt upgrade -y
reboot


2. Отключаем swap (на всех нодах)


swapoff -a


Постоянно — правкой /etc/fstab: комментируем строку со swap.

Важно: если swap не отключить полностью (включая /etc/fstab), при kubeadm join kubelet может не пройти health-check за отведённые 4 минуты и уйти в CrashLoopBackOff с ошибкой unable to load bootstrap kubeconfig — этот случай разобран в разделе «Возможные проблемы» ниже. Проверяйте free -h перед следующим шагом.


3. Модули ядра и sysctl (на всех нодах)


cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

lsmod | egrep "overlay|br_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


4. Установка containerd (на всех нодах)


apt install containerd -y
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml > /dev/null
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd


Без SystemdCgroup = true kubelet и containerd используют разные cgroup driver — кластер не инициализируется.


5. Установка kubeadm, kubelet и kubectl (на всех нодах)


Старый репозиторий apt.kubernetes.io закрыт с 2023 года — используем pkgs.k8s.io:
apt install -y apt-transport-https ca-certificates curl gpg

KUB_VER=1.33
curl -fsSL https://pkgs.k8s.io/core:/stable:/v${KUB_VER}/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:/v${KUB_VER}/deb/ /" | \
  tee /etc/apt/sources.list.d/kubernetes.list

apt update
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl


6. Инициализация control-plane (только на control-plane)


kubeadm init \
  --control-plane-endpoint "<IP_CONTROL_PLANE>:6443" \
  --apiserver-advertise-address=<IP_CONTROL_PLANE> \
  --pod-network-cidr=10.244.0.0/16


--apiserver-advertise-address обязателен, если на ноде несколько сетевых интерфейсов — без него kubeadm может выбрать не тот. --control-plane-endpoint закладывает возможность перейти на HA (несколько control-plane нод) без пересоздания кластера.


Настраиваем kubectl:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config


Сохраняем команду kubeadm join из вывода — она понадобится для worker-нод. Токен живёт 24 часа, при необходимости перегенерируем:
kubeadm token create --print-join-command


7. Установка Calico через Tigera Operator (только на control-plane)


kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.4/manifests/tigera-operator.yaml
kubectl get pods -n tigera-operator


Скачиваем файл с настройками и правим CIDR — он должен совпадать с --pod-network-cidr:
wget https://raw.githubusercontent.com/projectcalico/calico/v3.31.4/manifests/custom-resources.yaml
vi custom-resources.yaml


В файле меняем cidr: 192.168.0.0/16 на cidr: 10.244.0.0/16 — дефолт Tigera-оператора не совпадает с CIDR, который задавали в kubeadm init.

Применяем:
kubectl create -f custom-resources.yaml
kubectl get pods -n calico-system


Дожидаемся, пока все поды перейдут в Running, а control-plane — в Ready:
kubectl get nodes


8. Присоединение worker-нод (на каждом worker)


Токен из вывода kubeadm init живёт 24 часа. Если истёк — генерируем новый на control-plane:
kubeadm token create --print-join-command


На каждом worker'е:
kubeadm join <IP_CONTROL_PLANE>:6443 --token <токен> \
    --discovery-token-ca-cert-hash sha256:<хэш>


9. Финальная проверка (на control-plane)


kubectl get nodes
kubectl get pods -n calico-system -o wide


Ожидаемый результат — все ноды в статусе Ready:
NAME      STATUS   ROLES           AGE   VERSION
master1   Ready    control-plane   30m   v1.33.13
worker1   Ready    <none>          16m   v1.33.13
worker2   Ready    <none>          6m    v1.33.13


Возможные проблемы


kubelet падает в CrashLoopBackOff после kubeadm join

Команда kubeadm join завершилась таймаутом:
[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is not healthy after 4m0.000639042s


Причина — не был отключён swap перед join. В логе journalctl -xeu kubelet видна конкретная ошибка:
E ... "command failed" err="failed to run Kubelet: unable to load bootstrap kubeconfig: stat /etc/kubernetes/bootstrap-kubelet.conf: no such file or directory"


Файл bootstrap-kubelet.conf не успел создаться до того, как join прервался по таймауту — нода осталась в промежуточном состоянии.

Решение:
free -h
swapoff -a
vi /etc/fstab   # комментируем строку со swap


Сбрасываем недоделанное состояние ноды:
kubeadm reset -f


Проверяем, что containerd жив:
systemctl status containerd


Получаем свежий токен на control-plane и повторяем join:
kubeadm join <IP_CONTROL_PLANE>:6443 --token <новый_токен> \
    --discovery-token-ca-cert-hash sha256:<хэш>


На этот раз kubelet проходит health-check за секунды, а не за 4 минуты:
[kubelet-check] The kubelet is healthy after 1.008980757s
This node has joined the cluster
Похожие новости
Установка и настройка Ansible в Ubuntu

Учимся использовать Ansible на сервере Ubuntu....

Подробнее
Запуск systemd в контейнере в CentOS 8 / RHEL 8

Запускаем systemd в контейнере Podman’а....

Подробнее
How to deploy ClickHouse Server with Docker Compose

Quickly start a ClickHouse database server in a Docker container....

Подробнее
Отслеживаем соединения контейнеров Docker

Отслеживаем состояние соединений в среде контейнеризации Docker....

Подробнее
Релиз Ubuntu 20.04.1 LTS

Компания Canonical представила первый корректирующий выпуск дистрибутива Ubuntu 20.04.1 LTS, в который...

Подробнее
Поднимаем прозрачный прокси Squid на Ubuntu 22.04

Рассмотрим настройку прозрачного проксирования в Squid без подмены сертификатов на базе ОС Ubuntu 22.04....

Подробнее
Комментарии (0)
Новые комментарии
sobir8 ноября 2024 12:42

Цитата: FidoNet Цитата: sobir Цитата: FidoNet Спасибо за статью. Остальные

img
К комментарию
FidoNet7 ноября 2024 03:26

Цитата: sobir Цитата: FidoNet Спасибо за статью. Остальные статьи что находил

img
К комментарию
sobir27 октября 2024 19:02

Цитата: FidoNet Цитата: sobir Цитата: FidoNet Можт быть дело в

img
К комментарию
FidoNet25 октября 2024 22:04

Цитата: sobir Цитата: FidoNet Можт быть дело в dnsmasq.service? Ошибка Failed

img
К комментарию
sobir25 октября 2024 16:48

Цитата: FidoNet Цитата: sobir Цитата: FidoNet Спасибо за статью. Остальные

img
К комментарию
FidoNet20 октября 2024 12:12

Можт быть дело в dnsmasq.service? Ошибка Failed to set DNS configuration: Unit

img
К комментарию
Все комментарии
Какой дистрибутив Linux вы часто используете?
Календарь
«    Сентябрь 2026    »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
282930 
Подпишись на канал