Развёртывание Kubernetes на Debian 11 с CRI-O и Calico
Важно: все команды выполняйте от имени пользователя с привилегиями sudo или root.
О чём эта статья
Это подробный практический гайд по развертыванию рабочего Kubernetes-кластера (control-plane + 2 worker) на Debian 11. Подход ориентирован на стабильность и повторяемость: конфигурация сетей (CRI-O bridge + Calico) согласована, изначально открыты необходимые порты, включены kernel-модули, отключён swap и настроен firewall. Также в конце — чеклисты, отладка, рекомендации по безопасности и сценарии тестирования.
Основные понятия в одну строку
- Kubernetes: система оркестрации контейнеров для управления развёртываниями и масштабированием.
- CRI-O: контейнерная среда выполнения, реализующая CRI (Container Runtime Interface).
- Calico: плагин сети (CNI) для Kubernetes, обеспечивает маршрутизацию и сетевую политику.
Требования (кратко)
- Минимум три сервера Debian 11 (можно физические или виртуальные).
- Пользователь с sudo-правами на каждом сервере.
- Доступ по SSH между машинами (OpenSSH).
- Доступ к интернет-репозиториям для скачивания пакетов и образов.
Структура руководства
- Подготовка хостов: hostname, /etc/hosts.
- Настройка UFW: правила для control-plane, worker и Calico.
- Включение kernel-модулей и отключение swap.
- Установка и настройка CRI-O.
- Установка kubeadm, kubelet, kubectl.
- Инициализация control-plane и развёртывание Calico.
- Добавление worker-узлов.
- Деплой тестового nginx и проверка.
- Чеклисты, отладка, безопасность, тесты и шаблоны.
Схема тестового окружения
Пример хостов, использованных в руководстве:
| Hostname | IP Address | Роль |
|---|---|---|
| k8s-master | 192.168.5.10 | control-plane |
| k8s-worker1 | 192.168.5.115 | worker |
| k8s-worker2 | 192.168.5.116 | worker |
Сохраните эту таблицу как шаблон для вашей среды и замените IP/имена на реальные.
Подготовка систем
- Установите hostname на каждой машине:
sudo hostnamectl set-hostname k8s-masterДля воркеров:
# setup hostname k8s-worker1
sudo hostnamectl set-hostname k8s-worker1
# setup hostname k8s-worker2
sudo hostnamectl set-hostname k8s-worker2- Обновите /etc/hosts на всех серверах (используйте ваш редактор):
sudo nano /etc/hostsДобавьте (пример):
192.168.5.10 k8s-master
192.168.5.115 k8s-worker1
192.168.5.116 k8s-worker2Проверьте пингом:
ping k8s-master -c3
ping k8s-worker1 -c3
ping k8s-worker2 -c3
ALT: Схема трёх узлов и пример содержимого /etc/hosts
Настройка UFW (файрвол)
Kubernetes требует открытия ряда портов как для control-plane, так и для worker-узлов. Ниже сводная таблица и команды для UFW.
Пример правил для control-plane:
sudo ufw allow 6443/tcp # API server
sudo ufw allow 2379:2380/tcp # etcd
sudo ufw allow 10250/tcp # kubelet API
sudo ufw allow 10259/tcp # kube-scheduler
sudo ufw allow 10257/tcp # kube-controller-managerПример правил для worker-узлов:
sudo ufw allow 10250/tcp # kubelet
sudo ufw allow 30000:32767/tcp # NodePortПравила для Calico (в примере используется BGP и VXLAN):
sudo ufw allow 179/tcp # Calico BGP
sudo ufw allow 4789/udp # VXLAN (Calico/Flannel)
sudo ufw allow 4789/tcp # VXLAN (иногда требуется)
sudo ufw allow 2379/tcp # etcd (если используется внешний etcd)Установка UFW и базовая активация:
sudo apt install ufw
sudo ufw allow "OpenSSH"
sudo ufw enable
sudo ufw status
ALT: Установка пакета ufw и включение службы на Debian

ALT: Подтверждение включения UFW и активные правила
Проверка статуса UFW:
sudo ufw status verboseВажно: открывая порты, учитывайте дополнительные слои сетевой безопасности (облачные Security Groups, внешние firewalls). Если узлы находятся в защищённой сети, корректируйте правила соответствующим образом.

ALT: Список правил ufw на control-plane

ALT: Список правил ufw на worker-узле
Включение kernel-модулей и отключение SWAP
Kubernetes требует, чтобы модули overlay и br_netfilter были загружены и чтобы net.ipv4.ip_forward и правила bridge-nf были включены. Также kubelet требует отключённого swap.
Включение модулей в текущей сессии:
sudo modprobe overlay
sudo modprobe br_netfilterСделать постоянным при загрузке:
cat <Sysctl-параметры для проброса и обработки таблиц iptables:
cat <
ALT: Вывод команд modprobe и создание файла modules-load.d/k8s.conf
Отключение swap (временно и постоянно):
sudo sed -i '/ swap / s/^/#/' /etc/fstab
sudo swapoff -a
free -mПроверьте, что в выводе free -m значение swap равно 0.

ALT: Вывод команды free -m с нулевым SWAP
Установка CRI-O (контейнерная среда выполнения)
Мы используем CRI-O версии 1.24 для Debian 11. Если вы планируете другую версию Kubernetes, подберите соответствующую версию CRI-O совместимую с вашим kubeadm.
Установка зависимостей:
sudo apt install gnupg2 apt-transport-https -yЭкспорт переменных (пример):
export OS=Debian_11
export VERSION=1.24Добавление репозиториев:
echo "deb [signed-by=/usr/share/keyrings/libcontainers-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb [signed-by=/usr/share/keyrings/libcontainers-crio-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.listДобавление ключей GPG:
mkdir -p /usr/share/keyrings
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-archive-keyring.gpg
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-crio-archive-keyring.gpgОбновление индекса пакетов и установка CRI-O:
sudo apt update
sudo apt install cri-o cri-o-runc cri-tools -y
ALT: Вывод команд curl и gpg для добавления ключей репозитория CRI-O
После установки отредактируйте /etc/crio/crio.conf — в секции [crio.network] укажите пути к CNI:
# network_dir = "/etc/cni/net.d/"
network_dir = "/etc/cni/net.d/"
# plugin_dirs = ["/opt/cni/bin/"]
plugin_dirs = [
"/opt/cni/bin/",
]Измените файл моста CRI-O (/etc/cni/net.d/100-crio-bridge.conf), установите подсеть под Pods, например 10.42.0.0/24:
...
"ranges": [
[{ "subnet": "10.42.0.0/24" }],
[{ "subnet": "1100:200::/24" }]
]
...Перезапустите и включите службу:
sudo systemctl restart crio
sudo systemctl enable crio
sudo systemctl status crio
ALT: Статус службы crio после перезапуска
Совет: если вы используете containerd или Docker, соответствующим образом замените инструкции по установке и укажите их сокет в kubeadm init.
Установка Kubernetes (kubeadm, kubelet, kubectl)
Добавление официального репозитория Kubernetes и ключа:
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt updateУстановка пакетов:
sudo apt install kubelet kubeadm kubectl -yЗафиксируйте версии чтобы избежать автоматического обновления:
sudo apt-mark hold kubelet kubeadm kubectl
ALT: Добавление ключа и репозитория Kubernetes в систему
Инициализация control-plane
Проверьте наличие модуля br_netfilter:
lsmod | grep br_netfilterПредварительно подтяните образы kubeadm для экономии времени при init:
sudo kubeadm config images pull --cri-socket=unix:///var/run/crio/crio.sockСписок образов (crictl):
sudo crictl images
ALT: Вывод kubeadm config images pull и crictl images
Инициализация кластера (пример):
sudo kubeadm init --pod-network-cidr=10.42.0.0/24 \
--apiserver-advertise-address=192.168.5.10 \
--cri-socket=unix:///var/run/crio/crio.sockПояснения:
- –pod-network-cidr: подсеть для Pod-ов, должна совпадать с вашей конфигурацией CNI и CRI-O bridge.
- –apiserver-advertise-address: IP, на котором API server будет доступен внутри сети.
- –cri-socket: путь к сокету CRI, если используется не стандартный runtime.
После успешной инициализации вы получите инструкции по созданию kubeconfig для управления кластером с текущего пользователя:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configПроверьте состояние кластера:
kubectl cluster-info
kubectl get pods --all-namespaces
ALT: Вывод kubeadm init с ключевыми шагами и подсказками

ALT: Сообщение об успешной инициализации control-plane
Развёртывание Calico CNI с кастомной подсетью
Скачайте manifest Calico и отредактируйте его, чтобы указать ту же подсеть, что и в CRI-O bridge и в kubeadm init.
curl https://docs.projectcalico.org/manifests/calico.yaml -O
nano calico.yamlНайдите переменную CALICO_IPV4POOL_CIDR и замените её на 10.42.0.0/24:
- name: CALICO_IPV4POOL_CIDR
value: "10.42.0.0/24"Примените manifest (обратите внимание на имя файла — в инструкции ниже был calico.yml, используйте фактическое имя calico.yaml):
sudo kubectl apply -f calico.yamlПроверьте Pods Calico:
kubectl get pods --all-namespaces -o wide | grep calico
ALT: Применение manifest Calico и создание Pods

ALT: Вывод kubectl get pods –all-namespaces с Calico
Добавление worker-узлов
На каждом worker-узле выполните команду kubeadm join, которую вы получили в выводе kubeadm init. Пример команды (ваши токен и sha256 будут отличаться):
kubeadm join 192.168.5.10:6443 --token dbgk8h.nwzqqp1v5aqif5fy \
--discovery-token-ca-cert-hash sha256:7a543a545585358b143ce3e8633a8d673b6f628c5abc995939a58606c6dd219cПосле успешного join вернитесь на control-plane и проверьте узлы:
kubectl get nodes -o wide
kubectl get pods --all-namespaces
ALT: Вывод успешного join воркера в кластер

ALT: Присоединение второго воркера

ALT: Список pod-ов на всех namespaces и информация о узлах
Деплой тестового Nginx (проверка работоспособности)
Создадим простой Deployment и сервис NodePort:
kubectl create deployment nginx --image=nginx:alpine --replicas=2
kubectl create service nodeport nginx --tcp=80:80
kubectl get pods
kubectl get svcПосмотрите порт NodePort в выводе kubectl get svc (в диапазоне 30000-32767). Пример теста:
curl k8s-worker1:31277
curl k8s-worker2:31277Вы должны увидеть HTML-ответ от Nginx. Скриншоты примеров:

ALT: Созданный Deployment nginx и сервис NodePort

ALT: Ответ index.html от nginx на worker1

ALT: Ответ index.html от nginx на worker2
Проверки и приёмка
Критерии приёмки:
- kube-apiserver, kube-controller-manager, kube-scheduler, etcd Running на control-plane.
- kubelet Running на всех узлах.
- Pods Calico Running.
- Наличие всех узлов в kubectl get nodes и статус Ready.
- Возможность доступа к тестовому nginx через NodePort с каждого worker-узла.
Полезные команды для диагностики:
kubectl get nodes
kubectl get pods -A
kubectl describe pod -n
journalctl -u kubelet -f
sudo crictl ps -a
sudo crictl logs Частые проблемы и исправления
- kubelet не запускается после включения swap: убедитесь, что swap отключён в /etc/fstab и в сессии sudo swapoff -a.
- Неправильные CNI-конфигурации: проверьте, совпадают ли pod-network-cidr, CRI-O bridge subnet и CALICO_IPV4POOL_CIDR.
- Неверные правила UFW: временно отключите UFW на время отладки и проверьте соединения (sudo ufw disable), затем уточните правила.
- Проблемы с CRI-O: проверьте /var/log/syslog и systemctl status crio, убедитесь, что plugin_dirs и network_dir указаны правильно.
- kubeadm join выдаёт ошибки токена: создайте новый токен на control-plane (kubeadm token create) и используйте команду kubeadm token create –print-join-command для генерации рабочей команды.
Безопасность и рекомендации для продакшена
- Защитите API-сервер: ограничьте доступ по IP и рассмотрите использование TLS-балансера или LB с WAF.
- Обновления: тестируйте обновления Kubernetes и CRI-O в контрольной среде перед применением в продакшене.
- Секреты: используйте механизмы шифрования Secret в etcd и RBAC для ограничения доступа.
- Audit логирование: включите Audit для API-сервера и собирайте логи централизованно.
- Политики сети: используйте Calico Network Policies для ограничения трафика между Pod-ами.
Миграция и альтернативы
Альтернативные контейнерные рантаймы: containerd, Docker (через cri-dockerd), Mirantis. Если вы хотите сменить runtime, план действий: 1) Drain узла, 2) Установить новый runtime, 3) Обновить сокет в kubelet/kubeadm, 4) Перезапустить kubelet и проверить состояние.
Если вы разворачиваете кластер в облаке, рассмотрите managed-решения (GKE, EKS, AKS) или гибридный подход с control-plane управляемым провайдером.
Роли и чеклисты (кто что делает)
Администратор инфраструктуры:
- Подготовить сеть и VLAN, обеспечить доступ между узлами.
- Настроить DNS/hosts.
- Проверить firewall/security groups.
DevOps-инженер:
- Установить CRI-O и Kubernetes пакеты.
- Инициализировать control-plane и настроить kubeconfig.
- Деплой Calico и тестовых приложений.
SRE/операции:
- Настроить мониторинг (Prometheus), логирование (ELK/EFK), алертинг.
- Создать процедуры восстановления/бекупа etcd.
Мини-методология для повторяемой установки
- Импортируйте шаблон hosts и конфигурацию UFW.
- Автоматизируйте установку пакетов (ansible/playbook).
- Версионируйте manifest-ы CNI/Network в git.
- Выполняйте проверку health-checks (kube-probes, node readiness).
Decision flowchart (Mermaid)
flowchart TD
A[Начало: подготовка хостов] --> B{Все хосты готовы?}
B -- Да --> C[Настройка UFW]
B -- Нет --> Z[Исправить Hosts/SSH]
C --> D[Включить модули ядра и отключить swap]
D --> E[Установить CRI-O]
E --> F[Установить kubeadm/kubelet/kubectl]
F --> G[Инициализировать control-plane]
G --> H{Инициалиация успешна?}
H -- Да --> I[Деплой Calico]
H -- Нет --> Y[Диагностика kubeadm/journalctl]
I --> J[Добавить worker-узлы]
J --> K[Деплой тестового приложения]
K --> L[Верификация и мониторинг]Тестовые сценарии и приёмка
- После инициализации: kubectl get nodes — все узлы имеют статус Ready.
- После установки Calico: kubectl get pods -n kube-system — calico pods Running.
- Тест сетевого взаимодействия: curl NodeIP:NodePort возвращает HTML от nginx.
- Проверка отказоустойчивости: удалить один pod nginx, убедиться, что ReplicaSet создаёт новый pod.
- Проверка масштабирования: kubectl scale deployment nginx –replicas=5 и проверка 5 Running pods.
Шаблоны и примеры
Шаблон /etc/hosts (пример):
# /etc/hosts
127.0.0.1 localhost
192.168.5.10 k8s-master
192.168.5.115 k8s-worker1
192.168.5.116 k8s-worker2Шаблон правил UFW (скрипт):
# ufw-setup.sh (пример)
sudo apt install ufw -y
sudo ufw allow "OpenSSH"
# control plane rules
sudo ufw allow 6443/tcp
sudo ufw allow 2379:2380/tcp
sudo ufw allow 10250/tcp
sudo ufw allow 10259/tcp
sudo ufw allow 10257/tcp
# calico
sudo ufw allow 179/tcp
sudo ufw allow 4789/udp
sudo ufw allow 4789/tcp
sudo ufw allow 2379/tcp
sudo ufw enableКороткая галерея нетипичных случаев
- Если ваша сеть уже использует 10.42.0.0/24, выберите другую подсеть для Pod-ов (например 10.244.0.0/16) и согласуйте её везде.
- При использовании внешнего etcd — откройте соответствующие порты и укажите параметры etcd в kubeadm config.
- Если узлы в разных подсетях — используйте туннелирование или корректную маршрутизацию для Pod-to-Pod трафика.
1-строчный глоссарий
- API server: основной компонент Kubernetes, принимающий запросы REST.
- kubelet: агент на каждом узле, управляющий Pod-ами.
- kubeadm: утилита для инициализации и администрирования базового кластера Kubernetes.
- CNI: Container Network Interface — стандарт для сетевых плагинов.
Итог
Вы развернули рабочий Kubernetes-кластер на Debian 11 с CRI-O и Calico, прошли все ключевые этапы: подготовка хостов, firewall, kernel-параметры, установка runtime и Kubernetes, и проверили работу через Nginx. Дальше рекомендуем автоматизировать повторяемые шаги с помощью Ansible/terraform и добавить мониторинг/логи.
Важно: поддерживайте политики бекапа etcd и тестируйте обновления в staging перед production.
Если нужно, могу подготовить Ansible playbook для автоматизации всех шагов, или сокращённую инструкцию для развёртывания в облаке.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента