В этой статье мы рассмотрим пошаговую настройку кластера Kubernetes на Ubuntu 24.04 с тремя узлами: один мастер (который также может запускать пользовательские поды) и два рабочих узла. Мы настроим PersistentVolume (PVC) с использованием локального хранилища и развернём сеть с помощью Calico.
Предварительные требования
- Три сервера или виртуальные машины с Ubuntu 24.04.
- У каждого узла должен быть статический IP-адрес.
- На всех узлах должен быть доступ к интернету.
- На всех узлах должны быть установлены SSH-ключи для удалённого доступа.
- Минимальные требования к ресурсам:
- Мастер-узел: 4 CPU, 8 GB RAM, 40 GB HDD.
- Рабочие узлы: 2 CPU, 4 GB RAM, 20 GB HDD.
Настройка узлов
Обновление системы и установка базовых пакетов
На всех узлах выполните:
# apt update && sudo apt upgrade -y
# apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
Настройка имён хостов
На каждом узле задайте уникальное имя:
# hostnamectl set-hostname master-node
# hostnamectl set-hostname worker-node-1
# hostnamectl set-hostname worker-node-2
Обновите файл /etc/hosts на всех узлах:
# nano /etc/hosts
Добавьте записи:
192.168.1.10 master-node
192.168.1.11 worker-node-1
192.168.1.12 worker-node-2
Замените IP-адреса на актуальные для вашей сети.
Установка Docker и Kubernetes
Установка Docker
На всех узлах выполните:
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt update
# apt install -y docker.io
# systemctl enable docker
# systemctl start docker
# usermod -aG docker $USER
Перезайдите в систему или выполните (если вы выполняете операции под непривелигированным пользователем):
# newgrp docker
Установка компонентов Kubernetes
На всех узлах выполните:
# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/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.32/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
# apt update
# apt install -y kubelet kubeadm kubectl
# apt-mark hold kubelet kubeadm kubectl
Инициализация мастер-узла
На мастер-узле выполните:
# kubeadm init --pod-network-cidr=192.168.74.0/16
После успешного выполнения команды вы увидите вывод с командами для настройки kubeconfig и добавления рабочих узлов. Сохраните эти команды.
Настройка kubeconfig на мастер-узле
# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config
Настройка сети Calico
Примените конфигурацию Calico:
# kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
Проверьте статус подов Calico:
# kubectl get pods -n kube-system
Все поды должны быть в состоянии Running.
Добавление рабочих узлов
На рабочих узлах выполните команду, полученную на шаге 3 (она будет выглядеть примерно так):
# kubeadm join 192.168.1.10:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Проверьте, что узлы присоединились:
# kubectl get nodes
Настройка локального хранилища для PVC
Создание каталога на мастер-узле
# mkdir -p /mnt/gluster-storage/
# chmod 777 /mnt/gluster-storage/
Создание StorageClass
Создайте файл local-storage-class.yaml:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Примените конфигурацию:
# kubectl apply -f local-storage-class.yaml
Создание PersistentVolume
Создайте файл local-pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local-1
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/gluster-storage
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- master-node
Примените конфигурацию:
# kubectl apply -f local-pv.yaml
Создание PersistentVolumeClaim и тестового пода
Создайте файл pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
Примените конфигурацию:
# kubectl apply -f pvc.yaml
Создайте файл test-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
- name: local-storage
mountPath: /usr/share/nginx/html
volumes:
- name: local-storage
persistentVolumeClaim:
claimName: pvc-local
Примените конфигурацию:
# kubectl apply -f test-pod.yaml
Проверьте статус:
# kubectl get pvc
# kubectl get pods
Проверка работоспособности кластера
Проверка узлов
# kubectl get nodes
Проверка подов
# kubectl get pods -A
Проверка PVC и PV
# kubectl get pvc
# kubectl get pv
Основные порты, которые нужно открыть если вы работаете во внешней сети
Если ваши узлы находятся в сети Internet то неплохо было бы их прикрыть. Я в моем случае я полностью ограничил внешний доступ к узлам и разрешил взаимодействие между узлами по ряду портов. Вам естественно потребуется для примеров правил указать еще и IP-адреса мастера и воркеров которые по этим адресам будут взаимодействовать.
На мастер-узле
# ufw allow 6443/tcp # API Server
# ufw allow 2379:2380/tcp # etcd server client API
# ufw allow 10250/tcp # Kubelet API
# ufw allow 10259/tcp # kube-scheduler
# ufw allow 10257/tcp # kube-controller-manager
На рабочих узлах
# ufw allow 10250/tcp # Kubelet API
# ufw allow 30000:32767/tcp # NodePort Services
Дополнительные порты для Calico
Для корректной работы Calico необходимо открыть следующие порты:
# ufw allow proto udp port 179 # BGP (для Calico)
# ufw allow proto tcp port 179 # BGP (для Calico)
# ufw allow proto ipv4-icmp # ICMP (для диагностики сети)
# ufw allow proto ipv6-icmp # ICMPv6 (для диагностики сети)
Универсальная настройка на всех узлах
Чтобы упростить процесс, можно применить следующий набор правил на всех узлах кластера:
# Разрешаем связь между узлами кластера (замените 192.168.1.0/24 на вашу подсеть)
# ufw allow from 192.168.1.0/24
# Разрешаем связь по протоколу ICMP (для диагностики)
# ufw allow proto icmp
# Открываем порты для Kubernetes API и компонентов
# ufw allow 6443/tcp # API Server
# ufw allow 2379:2380/tcp # etcd
# ufw allow 10250/tcp # Kubelet API
# ufw allow 10259/tcp # kube-scheduler
# ufw allow 10257/tcp # kube-controller-manager
# Порты для NodePort сервисов
# ufw allow 30000:32767/tcp
# Порты для Calico
# ufw allow proto udp port 179
# ufw allow proto tcp port 179
Включение и проверка UFW
- Включите UFW:
# ufw enable
- Проверьте статус и правила:
# ufw status verbose
- Проверьте доступность портов между узлами (с любого узла на любой другой):
# Проверка API Server
# telnet <другой-узел-ip> 6443
# Проверка Kubelet API
# telnet <другой-узел-ip> 10250
Установка Ingress Nginx в кластере Kubernetes
Добавление репозитория Helm
Сначала добавим репозиторий Helm для Nginx Ingress:
# helm repo add nginx-stable https://helm.nginx.com/stable
# helm repo update
Установка Ingress Nginx через Helm
Выполним установку Ingress Nginx с помощью Helm. Ниже — базовый вариант установки:
# helm install nginx-ingress nginx-stable/nginx-ingress \
--set controller.service.type=LoadBalancer
Если вы используете локальное хранилище или хотите настроить другие параметры, можно использовать кастомный файл значений (values.yaml). Например, для настройки NodePort:
# helm install nginx-ingress nginx-stable/nginx-ingress \
--set controller.service.type=NodePort
Проверка установки
После установки проверьте, что поды и сервисы Ingress Nginx запущены:
# kubectl get pods -n default -l app.kubernetes.io/name=nginx-ingress
# kubectl get services -n default -l app.kubernetes.io/name=nginx-ingress
Обратите внимание на пространство имён (namespace). По умолчанию Helm может устанавливать ресурсы в пространство имён default, но вы можете указать другое пространство имён с помощью флага --namespace <имя_пространства_имён> при установке.
Шаг 4. Создание Ingress-ресурса
Теперь создадим Ingress-ресурс, чтобы направить трафик к вашему приложению.
Создайте файл ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: your-service
port:
number: 80
Замените example.com на ваш домен, а your-service — на имя сервиса, к которому вы хотите направить трафик.
Примените конфигурацию:
# kubectl apply -f ingress.yaml
Проверка работы Ingress
Проверьте, что Ingress-ресурс создан и работает:
# kubectl get ingress
Вы должны увидеть созданный ресурс в списке.
Тестирование
Чтобы протестировать работу Ingress, можно использовать следующие методы:
- Если сервис имеет тип
LoadBalancer, получите внешний IP-адрес сервиса Ingress Nginx:
kubectl get services -n default -l app.kubernetes.io/name=nginx-ingress
Затем откройте браузер и введите этот IP-адрес.
- Если сервис имеет тип
NodePort, узнайте порт, назначенный сервису, и используйте IP-адрес любого узла кластера вместе с этим портом. - Для локального тестирования можно отредактировать файл
/etc/hostsна вашей машине, добавив запись вида:
<IP-адрес-узла> example.com
Затем откройте http://example.com в браузере.
Альтернативный способ: установка через манифесты (без Helm)
Если вы предпочитаете не использовать Helm, можно установить Ingress Nginx с помощью готовых манифестов:
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/cloud/deploy.yaml
Разрешаем запуск пользовательских pod-ов на Master-узле
# kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule-




