1.8к
2
1
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Устанавливаем отказоустойчивый кластер Kubernetes

Время чтения 9 минут
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
1.8к
2
1
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Отказоустойчивость — это способность информационной системы продолжать работу во время отказов или технических сбоев без потери данных. Один из способов достижения отказоустойчивости заключается в горизонтальном масштабировании — при помощи добавления дополнительных серверов. Меня зовут Александр Бархатов, и в этой статье я покажу, как поднять отказоустойчивый кластер Kubernetes с отдельным сервером для балансировки трафика.

Устанавливаем отказоустойчивый кластер Kubernetes

Технические характеристики кластера

Для примера я возьму кластер из двух master-нод, двух рабочих нод, а также дополнительного сервера с HAProxy, который будет распределять сетевую нагрузку.

Технические характеристики кластера Kubernetes

На всех узлах кластера, включая балансировщик, я использую операционную систему 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

При отсутствии DNS можно прописать эти IP адреса и их доменные имена в файле hosts (/etc/hosts) на всех используемых серверах

Создание и установка кластера 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-ноды не скажется на работоспособности всего кластера.

Комментарии1
Алексей
7 месяцев назад
Кластер с 2 мастерами не является отказоустойчивым, для кворума в etcd необходимо (n/2)+1 нод. Где n количество нод. Тоесть минимум 3 для отказоустойчивости
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники