Print this page

Kubernetes Cluster на Ubuntu 22.04

16 August 2024
Rate this item
(0 votes)

В данной статье мы установим Kubernetes-кластер, состоящий из трех нод (узлов), включающий в себя одну мастер-ноду (master) и две рабочие ноды (worker).

Предварительные требования

Для установки кластера Kubernetes необходимо следующее:

  • Три сервера или три виртуальные машины с установленной операционной системой Ubuntu 22.04.
  • На каждом сервере должно быть минимум 2 Гб оперативной памяти и минимум 2 ядра процессора. Если не учесть данное требование, то инициализировать кластер не получится.

Настройка операционной системы

Перед установкой и инициализацией кластера необходимо подготовить и настроить некоторые параметры на уровне операционной системы. Команды, которые будут использоваться в данном разделе, необходимо выполнять на всех трех серверах и от имени пользователя root.

1) Обновляем списки репозиториев, производим обновление всех пакетов в ОС, а также устанавливаем необходимые пакеты:

apt update && apt -y upgrade && apt -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common

2) Далее необходимо выключить механизм SWAP. Для начала проверим, используется ли SWAP у нас в системе. Для этого можно воспользоваться командой "free -h". SWAP не используется, если в значении SWAP (строка с именем Swap) указаны нулевые значения. Также можно воспользоваться командой swapon -s, которая выводит подробную информацию об используемых разделах SWAP в системе. Если в ответ команда ничего не вернула, это говорит о том, что SWAP выключен и не используется. Если же SWAP включен, то его необходимо выключить. В дистрибутивах Linux SWAP можно отключить 2 способами:

  • Первый способ — отключить SWAP на время работы сервера, в терминале достаточно выполнить команду "swapoff -a". Это означает, что SWAP будет выключен только до первой перезагрузки/выключения сервера. Данный способ не рекомендуется использовать в связи с тем, что после перезагрузки/включения сервера, узлы Kubernetes не смогут запуститься.
  • Второй способ — полное (перманентное) отключение SWAP. В таком случае SWAP будет полностью выключен и не будет использоваться и после перезагрузки сервера. Для полного выключения SWAP необходимо открыть на редактирование файл fstab при помощи любого текстового редактора, например, "nano /etc/fstab". Найти строку, содержащую значение swap.img, и закомментировать ее, прописав символ решетки (#), сохранить файл и перезапустить сервер.

3) Следующим шагом необходимо загрузить дополнительные сетевые модули из ядра операционной системы. Делается это в два этапа. На первом этапе создаем конфигурационный файл с именем k8s.conf и прописываем в нем те сетевые модули, которые нам необходимы: overlay и br_netfilter. Команда будет следующей:

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

4) На втором этапе загружаем ранее указанные модули из ядра операционной системы при помощи команд modprobe overlay && modprobe br_netfilter

5) Проверяем, что сетевые модули были успешно загружены и активированы, для этого выполним команду lsmod | egrep "br_netfilter|overlay". Если напротив значений overlay и br_netfilter во втором столбце присутствует цифра 0, то модули успешно активированы.

6) Так как большинство сетевых плагинов (CNI) в Kubernetes используют встроенный в ядро Linux firewall под названием Iptables, а также маршрутизируют трафик через сетевой мост (bridge), нам необходимо активировать соответствующие сетевые параметры, которые отвечают за маршрутизацию трафика через сетевой мост. Для этого выполняем команду:

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

7) Перезапускаем параметры ядра sysctl --system

8) При использовании брандмауэра UFW (Uncomplicated Firewall) или любого другого firewall (например, Iptables) необходимо открыть следующие порты: 6443, 2379, 2380, 10250, 10259, 10257.
Также UFW можно полностью выключить и убрать из автозагрузки: systemctl stop ufw && systemctl disable ufw

На этом настройка операционной системы завершена. В следующих разделах мы перейдем к установке контейнерного движка CRI-O и установке Kubernetes.

Настройка операционной системы

Так как Kubernetes самостоятельно не запускает контейнеры, то ему необходим сторонний инструмент для таких задач — контейнерный движок. Движок для контейнеров (он же Container Runtime) предназначен для работы с контейнерами, включая инициализацию контейнеров, их запуск, остановку и т.д. Мы будем устанавливать CRI-O — легковесный движок, который поддерживает полноценную работу с контейнерами и прост в использовании. Как и в предыдущем разделе, все команды, используемые ниже, необходимо выполнять на всех трех серверах.
1) Для начала задаем переменные, которые пригодятся нам для того, чтобы скачать необходимую версию Crio для определенной версии ОС. В переменной OS задаем имя и версию используемого дистрибутива, а в переменной CRIO_VERSION версию CRIO, которую будем скачивать:

export OS=xUbuntu_22.04
export CRIO_VERSION=1.25

2) Пакет crio присутствует в официальных репозиториях от дистрибутива openSUSE. Добавляем данные репозитории в систему:

echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /"| tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$CRIO_VERSION/$OS/ /"| tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION.list

3) Импортируем GPG-ключи от репозиториев:

curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$CRIO_VERSION/$OS/Release.key | apt-key add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -

4) Обновляем списки репозиториев и устанавливаем CRIO, а также дополнительные утилиты apt update && apt -y install cri-o cri-o-runc cri-tools

5) Запускаем crio и добавляем его в автозагрузку systemctl start crio && systemctl enable crio

6) Проверяем статус crio systemctl status crio. Если в статусе отображается Active (running), то crio успешно запущен и работает. На этом установка CRI-O успешно завершена.

Установка Kubernetes

Переходим к установке Kubernetes. Подключение репозитория и установку пакетов Kubernetes необходимо выполнять сразу на всех трех серверах.
1) Добавляем GPG-ключ от репозитория Kubernetes: curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

2) Далее подключаем официальный репозиторий Kubernetes: echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list

3) Обновляем списки репозиториев, устанавливаем пакеты kubelet, kubeadm, kubectl, а также делаем для них операцию hold — таким образом при появлении новых версий для данных компонентов они не будут обновляться: apt update && apt -y install kubelet kubeadm kubectl && apt-mark hold kubelet kubeadm kubectl

4) Команду по инициализации мастер-ноды выполняем только на одном сервере который предназначен именно для мастер-ноды. Инициализируем мастер-ноду а также выделяем подсеть, адреса которой будут назначаться подам в кластере: kubeadm init --pod-network-cidr=10.244.0.0/16.

Подсеть 10.244.0.0/16 используется для работы flannel — специального плагина, который создает виртуальную сеть разработанную для работы с контейнерами. flannel мы установим после того как создадим кластер. Процесс инициализации мастер-ноды может занимать от 5 минут и больше, в зависимости от скорости используемого интернет-соединения. Сначала скачиваются образы необходимых компонентов Kubernetes, такие как kube-apiserver, kube-controller-manager, kube-scheduler, kube-proxy, etcd, coredns; далее происходит первичная настройка включающая в себя создание сертификатов безопасности, создание конфигурационных файлов и запуск подов.
5) После того как процесс инициализации мастер-ноды будет завершен (в терминале отобразится надпись «Your Kubernetes control-plane has initialized successfully!»), необходимо выполнить шаги, перечисленные в конце вывода, а именно:

  • Создать в домашней директории скрытую папку с именем kube;
  • Скопировать конфигурационный файл, содержащий данные для подключения к кластеру в ранее созданный каталог в домашней директории;
  • Назначить пользователя и группу на созданную директорию.

Сами команды перечислены ниже. Также данные команды всегда отображаются в конце вывода команды при успешной инициализации мастер-ноды:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

6) Обратите внимание на самую последнюю строку в выводе команды (kubeadm join) — там будет сгенерирована команда, предназначенная для присоединения рабочих нод. Эту команду выполняем на оставшихся двух серверах. Команду kubeadm join необходимо выполнить от имени root-пользователя или от пользователя с правами sudo.

7) После того как оставшиеся узлы были успешно присоединены, возвращаемся на мастер-ноду и выводим список всех нод кластера при помощи команды: kubectl get nodes
8) Также выведем список всех подов в кластере, используя команду: kubectl get po -A

9) Так как ранее мы задали подсеть, но не установили сетевой плагин flannel, самое время это сделать. Для установки flannel выполняем команду: kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

10) Проверяем статус запущенных подов: kubectl get po -n kube-flannel. Поды успешно запущены. Количество реплик flannel соответствует числу нод в кластере.

11) Далее проверим работоспособность кластера путем запуска веб-сервера Nginx. Для этого создаем файл nginx_deployment.yaml: nano nginx_deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.16.1
        ports:
        - containerPort: 80

Обратите внимание что в языке разметки YAML необходимо соблюдать отступы строк, иначе файл станет невалидным. Сохраняем изменения и выходим из файла.

12) Создаем наш deployment (в котором описаны настройки нашего приложения) при помощи команды: kubectl apply -f nginx_deployment.yaml

13) Проверяем статус созданного deployment: kubectl get po -n default. Так как мы ранее задали две реплики приложения (параметр replicas: 2), то у нас запущено два пода с приложением.

14) Далее необходимо проверить, может ли Nginx отвечать на запросы. Для начала необходимо получить IP-адрес пода. Для этого воспользуемся командой kubectl describe, передав в качестве параметра имя одного из запущенных подов: kubectl describe pod nginx-deployment-848dd6cfb5-rn5bv IP-адрес всегда отображается в параметре IP. 

15) При помощи утилиты curl отправим запрос на IP-адрес пода: curl -i 10.244.1.2 Как можно увидеть, Nginx успешно (код 200) отправил ответ на наш запрос.