Технические характеристики кластера
Для примера я возьму кластер из двух master-нод, двух рабочих нод, а также дополнительного сервера с HAProxy, который будет распределять сетевую нагрузку.
На всех узлах кластера, включая балансировщик, я использую операционную систему Ubuntu 20.04.6 LTS Focal Fossa в редакции Server, версия ядра ОС — 5.4.0-152-generic.
Также задам следующие IP-адреса и имена хостов:
- 10.2.47.80 k8s-master1
- 10.2.47.81 k8s-master2
- 10.2.47.82 k8s-worker1
- 10.2.47.83 k8s-worker2
- 10.2.47.84 haproxy
Создание и установка кластера Kubernetes
Настройка операционной системы
Первый шаг — подготовка и настройка ОС. На всех четырех серверах, предназначенных для узлов кластера, выполняем одинаковые шаги.
1. Обновляем ОС и пакеты программ:
sudo apt update && sudo apt -y upgrade
2. Далее выключаем SWAP, так как Kubernetes не поддерживает работу с ним. Сделать это можно двумя способами:
- Выключить SWAP до следующей перезагрузки сервера по команде sudo swapoff -a. Тогда кластер не запустится при старте сервера.
- Выключить SWAP перманентно. Для этого нужно открыть файл /etc/fstab и добавить перед строкой со словом swap символ решетки #.
Затем нужно сохранить и закрыть файл, а после — выполнить перезагрузку сервера командой sudo reboot.
3. Для удобства выключаем firewall и убираем его из автозапуска. По умолчанию в ОС семейства Ubuntu используется утилита для конфигурирования межсетевого экрана под названием UFW:
sudo systemctl stop ufw && sudo systemctl disable ufw
Для кластера в production-среде нужно открыть порты, которые я указал в таблицах ниже.
4. Загружаем сетевые модули из ядра Linux:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
5. Активируем загруженные модули и применяем настройки:
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.ip_forward = 1
> net.bridge.bridge-nf-call-ip6tables = 1
> EOF
6. Перезапускаем параметры ядра:
sudo sysctl –system
Первый этап установки кластера Kubernetes завершен. Далее мы перейдем ко второму этапу, который заключается в установке CRI-O — движка для контейнеров.
Установка CRI-O
Так как поддержка Docker полностью прекращена в версии 1.24, а устанавливать мы будем версию Kubernetes под номером 1.27.3, то в качестве движка я выбрал CRI-O. Это легковесная исполняемая среда для контейнеров в Kubernetes. Чтобы установить CRI-O, повторите одинаковые шаги на всех нодах кластера Kubernetes. Кстати, я уже писал подробную статью об установке кластера Kubernetes с CRI-O в качестве Container Engine.
1. Создадим переменные, содержащие версию используемого дистрибутива Ubuntu и версию CRI-O 1.23:
OS=xUbuntu_20.04
VERSION=1.23
2. В официальных репозиториях Ubuntu нет пакетов CRI-O, поэтому воспользуемся репозиторием от разработчиков ОС openSUSE. Добавляем его в систему:
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
3. Добавляем репозиторий, содержащий пакеты CRI-O:
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
4. Скачиваем и добавляем ключ от репозитория:
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key add –
5. Устанавливаем CRI-O и необходимые пакеты:
sudo apt update && sudo apt install cri-o cri-o-runc cri-tools -y
6. Добавляем CRI-O в автозагрузку и запускаем:
sudo systemctl enable crio.service && sudo systemctl start crio.service
Установка пакетов Kubernetes
На третьем шаге установим Kubernetes, действия для всех четырех нод кластера будут одинаковыми.
1. Скачиваем и добавляем публичный ключ от официального репозитория Kubernetes:
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
2. Добавляем официальный репозиторий Kubernetes:
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
3. Обновляем список пакетов, устанавливаем утилиты kubelet, kubeadm, kubectl и помечаем эти пакеты, чтобы в будущем они не обновлялись:
sudo apt update && sudo apt -y install kubelet kubeadm kubectl && sudo apt-mark hold kubelet kubeadm kubectl
Блокировку можно снять командой sudo apt-mark unhold kubelet kubeadm kubectl.
4. Добавляем сервис kubelet в автозагрузку:
sudo systemctl enable kubelet
Установка и настройка HAProxy
Дальнейшие шаги выполняем только на сервере, предназначенном для HAProxy.
1. Обновляем список пакетов и устанавливаем HAProxy:
sudo apt update && sudo apt -y install haproxy
2. Дополняем блок defaults в конфигурационном файле haproxy.cfg:
frontend kubernetes
bind 10.2.47.84:6443
option tcplog
mode tcp
default_backend kubernetes-master-nodes
frontend http_front
mode http
bind 10.2.47.84:80
default_backend http_back
frontend https_front
mode http
bind 10.2.47.84:443
default_backend https_back
backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
server k8s-master1 10.2.47.80:6443 check fall 3 rise 2
server k8s-master2 10.2.47.81:6443 check fall 3 rise 2
backend http_back
mode http
server k8s-master1 10.2.47.80:32059 check fall 3 rise 2
server k8s-master2 10.2.47.81:32059 check fall 3 rise 2
backend https_back
mode http
server k8s-master1 10.2.47.80:32423 check fall 3 rise 2
server k8s-master2 10.2.47.81:32423 check fall 3 rise 2
Обратите внимание, что выделенные значения нужно заменить на ваши. В разделах frontend kubernetes, frontend http_front и frontend https_front в параметре bind нужно указать IP-адрес сервера, где установлен HAProxy. В разделах backend kubernetes-master-nodes, backend http_back и backend https_back в параметре server необходимо прописать все сервера, которые будут выступать в качестве master-нод кластера.
После этого сохраняем изменения в файле и выходим из него.
3. Перезапускаем HAProxy:
sudo systemctl restart haproxy
Развертывание кластера Kubernetes
После того как все необходимые настройки были выполнены, можно приступать к запуску кластера Kubernetes.
Подготовка и запуск master-нод Kubernetes
1. Переходим на первый сервер, который исполняет роль master-ноды. В моем примере это сервер с именем k8s-master1 и IP-адресом 10.2.47.80. Создаем конфигурационный файл с именем kubeadmcf.yaml и прописываем в нем:
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
certSANs:
- 10.2.47.84
controlPlaneEndpoint: 10.2.47.84:6443
Вместо 10.2.47.84 нужно указать адрес сервера, на котором установлен HAProxy.
2. Сохраняем файл и запускаем первую master-ноду, передав в качестве аргумента ранее созданный конфигурационный файл kubeadmcf.yaml:
sudo kubeadm init --config=kubeadmcf.yaml
3. После запуска ноды копируем файл kubeconfig, чтобы получить доступ к кластеру:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Обратите внимание на то, что в выводе отобразились две команды: одна для присоединения master-нод, а другая — для рабочих нод. Их нужно скопировать на будущее.
4. Устанавливаем CNI-плагин Weave Net, чтобы обеспечить сетевое взаимодействие между объектами pod в кластере:
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
5. Теперь необходимо присоединить вторую master-ноду. Для этого воспользуемся командой, которая отобразилась в выводе при запуске первой ноды:
sudo kubeadm join 10.2.47.84:6443 --token p9szn5.bkhfe5p6e6h5tori --discovery-token-ca-cert-hash sha256:ec7bf871568193dd51aad4b9858e31d695e58c6755603d4baf53346439a25991 --control-plane
6. Повторяем третий шаг: копируем файл kubeconfig и получаем доступ к кластеру.
7. Чтобы запустить обе ноды, поочередно выполняем на них команду:
kubectl get nodes
В нашем кластере появились две master-ноды.
Добавление рабочих нод
Финальный этап заключается в добавлении рабочих нод кластера. Для этого воспользуемся командой, которая отобразилась в выводе при запуске первой master-ноды, но уже используем команду для инициализации рабочих нод. Выполняем ее на первой рабочей ноде:
sudo kubeadm join 10.2.47.84:6443 --token ah81xj.q83e0ra6hny6kfpz --discovery-token-ca-cert-hash sha256:16f28205e1e69fd7a018340ffbabb98aed7a106d1dd2ed1e83ab129e02dfb84b
И на второй рабочей ноде:
sudo kubeadm join 10.2.47.84:6443 --token ah81xj.q83e0ra6hny6kfpz --discovery-token-ca-cert-hash sha256:16f28205e1e69fd7a018340ffbabb98aed7a106d1dd2ed1e83ab129e02dfb84b
Когда все ноды кластера запущены, можно отобразить их статус:
kubectl get nodes
На выходе мы получаем полностью рабочий, отказоустойчивый кластер Kubernetes из 4 нод. В качестве балансировщика нагрузки на ноды используется HAProxy, поэтому выход из строя одной master-ноды не скажется на работоспособности всего кластера.