This article is more than one year old. Older articles may contain outdated content. Check that the information in the page has not become incorrect since its publication.

Установка кластера Kubernetes под управлением Cozystack: подробное руководство от Gohost и Ænix

Установка кластера Kubernetes под управлением Cozystack: подробное руководство от Gohost и Ænix

Эту статью написал Владислав Карабасов из казахстанской хостинг-компании gohost, поэтому повествование будет вестись от первого лица.

На момент моего перехода в gohost.kz компания уже 15 лет работала на рынке Казахстана, предоставляя клиентам стандартный набор услуг: VPS/VDC, IaaS, виртуальный хостинг и т. д. Однако у клиентов появлялись новые потребности, поэтому мне была поставлена задача развивать направление Kubernetes as a Service.

Так началось моё «знакомство 2.0» с *nix-системами (на этот раз с Talos Linux), а также с миром контейнеров (через Kubernetes). Работая над задачами запуска и развития этого нового направления, я наткнулся на Open Source-платформу Cozystack и познакомился с её разработчиками — Андреем Квапилом и Георгом Гаалом. Мы пообщались, и я решил развернуть кластер Kubernetes под управлением Cozystack, основанный на Talos Linux.

Вот что меня заинтересовало в Cozystack:

  • Платформа позволяет развёртывать кластеры Kubernetes внутри существующего кластера без использования виртуализации для запуска control plane Kubernetes, при этом рабочие узлы (workers) запускаются как виртуальные машины в существующем кластере Kubernetes. Это позволяет оптимально использовать ресурсы без ущерба для безопасности.
  • Talos Linux, на котором основана платформа, имеет очень высокий уровень безопасности.
  • Более того, создатели платформы — активные участники сообщества Kubernetes и вносят значительный вклад в Open Source, в том числе организовали сообщество для разработки собственного etcd-operator.

Как оказалось, gohost участвует в этом Open Source-проекте с самого первого дня, и прямо сейчас мы активно тестируем платформу и готовимся ввести её в промышленную эксплуатацию, то есть предоставлять нашим клиентам хостинга услуги на базе Cozystack.

Написать эту статью меня побудило несколько причин: я хотел систематизировать полученные знания, поделиться с сообществом своим опытом установки Cozystack на Talos Linux и рассказать о работе с различными инструментами экосистемы Kubernetes. Кроме того, наверняка найдутся читатели, которым этот материал пригодится в работе, — в общем, это моя скромная попытка что-то вернуть сообществу. Итак, начнём.

Топология кластера

Хотя Cozystack можно развернуть на «голом железе» (bare metal) буквально за несколько минут, платформу также можно запустить в любой виртуальной среде. Например, я начинал с развёртывания кластеров в Proxmox и KVM.

Однако в этой статье я расскажу о своём опыте установки на реальном оборудовании. Начнём с конфигурации — вот какое оборудование у меня было:

  1. VPS 2G/2CPU (хотя можно использовать и обычный домашний ПК) — 1 шт.
  2. Коммутаторы — 2 шт. (в режиме агрегации — этот режим повышает отказоустойчивость, пропускную способность и обеспечивает балансировку нагрузки, рис. 1) или 1 шт. (без агрегации, рис. 2).
  3. Серверы с локальным хранилищем на дисках NVMe (для контейнеров) и SSD (для операционной системы). Минимальное количество серверов в кластере для обеспечения отказоустойчивости — 3 шт.

Также можно использовать сетевое хранилище (NAS), например, с комбинацией DRBD + Linstor (мы используем такие NAS в нашей production-среде для VPS, но их настройка — тема для отдельной большой статьи, поэтому в данном случае мы ограничимся серверами).

Вот схема настройки оборудования для развёртывания Cozystack в моём случае (рис. 1). Конфигурацию коммутации я оставлю за рамками этой статьи.

Рис. 1. Топология с агрегацией портов

Рис. 2. Топология без агрегации портов

При организации топологии кластера необходимо обеспечить доступ в Интернет (SRV1, SRV2, SRV3). В моём случае доступ осуществляется через management-host. SRV1, SRV2 и SRV3 используют management-host в качестве шлюза по умолчанию. Кроме того, на management-host включена маршрутизация и настроены соответствующие правила iptables. При желании можно использовать и другой шлюз — management-host нужен только для первоначальной настройки кластера.

Подготовка management-host

Сначала настроим management-host, который будет использоваться для развёртывания кластера Kubernetes под управлением Cozystack. Предполагая, что вы уже умеете настраивать хост с операционной системой, я опущу подробности — в моём случае я использовал Ubuntu 22.04.

Приступим к развёртыванию management-host. Для этого я предлагаю использовать мой bash-скрипт, который избавляет от рутины поиска и установки пакетов и автоматизирует настройку хоста. На момент написания статьи использовались следующие версии пакетов: talosctl v1.7.1 и kubectl v1.30.1.

#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # Без цвета

apt update
apt upgrade -y
apt -y install ntp bind9 curl jq nload

service ntp restart
#service ntp status
sed -i -r 's/listen-on-v6/listen-on/g'  /etc/bind/named.conf.options 
sed -i '/listen-on/a \\tallow-query { any; };'  /etc/bind/named.conf.options 
apt -y  install apt-transport-https ca-certificates curl software-properties-common
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-ce snapd make dialog nmap 
#systemctl status docker
#curl -sL https://talos.dev/install | sh

releases=$(curl -s https://api.github.com/repos/siderolabs/talos/releases | jq -r '.[].tag_name' | head -n 10)
echo -e "${YELLOW}Select version to download:${NC}"
select version in $releases; do
    if [[ -n "$version" ]]; then
        echo "You have selected a version $version"
        break
    else
        echo -e "${RED}Incorrect selection. Please try again. ${NC}"
    fi
done
url="https://github.com/siderolabs/talos/releases/download/$version/talosctl-linux-amd64"
wget $url -O talosctl
chmod +x talosctl
sudo mv talosctl /usr/local/bin/
#kubectl
releases=$(curl -s https://api.github.com/repos/kubernetes/kubernetes/releases | jq -r '.[].tag_name' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 10)
echo -e "${YELLOW}Select kubectl version to download:${NC}"
select version in $releases; do
    if [[ -n "$version" ]]; then
        echo  "You have selected a version $version"
        break
    else
        echo -e "${RED}Incorrect selection. Please try again. ${NC}"
    fi
done
url="https://storage.googleapis.com/kubernetes-release/release/$version/bin/linux/amd64/kubectl"
wget $url -O kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

curl -LO https://github.com/kvaps/kubectl-node-shell/raw/master/kubectl-node_shell
chmod +x ./kubectl-node_shell
sudo mv ./kubectl-node_shell /usr/local/bin/kubectl-node_shell

curl -LO https://github.com/aenix-io/talm/releases/download/v0.5.7/talm-linux-amd64
chmod +x ./talm-linux-amd64
sudo mv ./talm-linux-amd64 /usr/local/bin/talm

echo "Specify the directory name for the configuration files,"
echo -e "the directory will be located in the catalog ${GREEN}/opt/${NC}. By default: ${GREEN}/opt/cozystack${NC}"
echo -e "${YELLOW}"
read -p "Enter the directory name: " cozystack
echo -e "${NC}"
if [ -z "$cozystack" ]; then    
  cozystack="cozystack" 
fi
mkdir -p /opt/$cozystack
curl -LO https://github.com/aenix-io/talos-bootstrap/raw/master/talos-bootstrap
mv talos-bootstrap /opt/$cozystack
chmod +x /opt/$cozystack/talos-bootstrap
snap install  yq
echo -e "${YELLOW}Specify IP network for etcd and kubelet${NC}"
echo -e "Default: ${GREEN} 192.168.100.0/24 ${NC}"
read -p "IP network (network/mask): " IPEK 
if [ -z "$IPEK" ]; then    
  IPEK="192.168.100.0/24" 
fi
# Добавить FORWARD (RELATED,ESTABLISHED)
rule1="-d $IPEK -m state --state RELATED,ESTABLISHED -m comment --comment $cozystack -j ACCEPT"
if ! iptables-save | grep -q -- "-A FORWARD $rule1"; then
    iptables -I FORWARD -d $IPEK -m state --state RELATED,ESTABLISHED -m comment --comment $cozystack -j ACCEPT
fi
# Добавить FORWARD
rule2="-s $IPEK -m comment --comment $cozystack -j ACCEPT"
if ! iptables-save | grep -q -- "-A FORWARD $rule2"; then
    iptables -I FORWARD -s $IPEK -m comment --comment $cozystack -j ACCEPT
fi
# Добавить NAT
rule3="-s $IPEK -m comment --comment $cozystack -j MASQUERADE"
if ! iptables-save | grep -q -- "-A POSTROUTING $rule3"; then
    iptables -t nat -I POSTROUTING -s $IPEK -m comment --comment $cozystack -j MASQUERADE
fi
#sysctl -w net.ipv4.ip_forward=1
if ! grep -qF "$REQUIRED_SETTING" "$FILE"; then
  echo "net.ipv4.ip_forward = 1" | sudo tee -a "/etc/sysctl.conf" > /dev/null 
fi
sysctl -p
apt -y install iptables-persistent 

cat > /opt/$cozystack/patch.yaml <<EOT
machine:
  kubelet:
    nodeIP:
      validSubnets:
      - $IPEK
    extraConfig:
      maxPods: 512
  kernel:
    modules:
    - name: openvswitch
    - name: drbd
      parameters:
        - usermode_helper=disabled
    - name: zfs
    - name: spl
  install:
    image: ghcr.io/aenix-io/cozystack/talos:v1.7.1
  files:
  - content: |
      [plugins]
        [plugins."io.containerd.grpc.v1.cri"]
          device_ownership_from_security_context = true      
    path: /etc/cri/conf.d/20-customization.part
    op: create
cluster:
  network:
    cni:
      name: none
    dnsDomain: cozy.local
    podSubnets:
    - 10.244.0.0/16
    serviceSubnets:
    - 10.96.0.0/16
EOT

cat > /opt/$cozystack/patch-controlplane.yaml <<EOT
cluster:
  allowSchedulingOnControlPlanes: true
  controllerManager:
    extraArgs:
      bind-address: 0.0.0.0
  scheduler:
    extraArgs:
      bind-address: 0.0.0.0
  apiServer:
    certSANs:
    - 127.0.0.1
  proxy:
    disabled: true
  discovery:
    enabled: false
  etcd:
    advertisedSubnets:
    - $IPEK
EOT

echo -e "${YELLOW}========== Installed binary ===========${NC}"
echo "helm       in folder" $(which helm)
echo "yq         in folder" $(which yq)
echo "kubectl    in folder" $(which kubectl)
echo "docker     in folder" $(which  docker)
echo "talosctl   in folder" $(which  talosctl)
echo "dialog     in folder" $(which  dialog)
echo "nmap       in folder" $(which  nmap)
echo "talm       in folder" $(which  talm)
echo "node_shell       in folder" $(which  kubectl-node_shell)
echo -e "${YELLOW}========== services runing ===========${NC}"
echo "DNS Bind9"; systemctl is-active bind9 
echo "NTP"; systemctl is-active ntp
echo -e "${YELLOW}========== ADD Iptables Rule ===========${NC}"
iptables -S | grep $cozystack
iptables -t nat -S | grep $cozystack
echo -e "${RED}!!!  Please change the catalog to work with talos-bootstrap !!!${NC}"
echo -e "${GREEN}cd  /opt/$cozystack ${NC}"

Как работает скрипт: он скачивает и устанавливает различные инструменты, включая helm, yq, kubectl, docker, talosctl, dialog, nmap, make, kubectl-node-shell и talm (ещё одну удобную open-source-утилиту от разработчиков Cozystack для настройки Talos Linux — своего рода Helm для Talos). Затем он раскладывает их по нужным каталогам. Весь процесс автоматизирован и сопровождается понятными диалогами. Кроме того, скрипт настраивает службу времени NTP, DNS-службу bind9 и создаёт правила для доступа в интернет из кластера через management-host.

В результате выполнения скрипта в каталог /opt/your_name (по умолчанию /opt/cozystack) скачивается скрипт talos-bootstrap для развёртывания кластера, а также создаются необходимые конфигурационные файлы, такие как patch-controlplane.yaml и patch.yaml. В этих файлах указаны модули ядра, которые будут загружены, и образ, из которого будет выполнена установка.

В итоге содержимое каталога должно выглядеть так:

Рис. 3. Каталог /opt/cozystack

Management-host готов к дальнейшей работе.

Загрузка из системного образа Talos Linux

Операционная система, на которой основан Cozystack, — это Talos Linux. Существует несколько способов установки Cozystack:

  • PXE — для установки с помощью временных DHCP- и PXE-серверов, работающих в контейнерах Docker.
  • ISO — для установки с помощью ISO-образов.
  • Hetzner — для установки на серверах Hetzner.

Для установки мы будем использовать ISO-файл. Разработчики Cozystack собирают и тестируют готовые к использованию образы платформы со всем необходимым программным обеспечением. Всё ПО также проходит проверку на совместимость с платформой и дистрибутивом Talos Linux.

Первоначальная настройка системы

После загрузки из образа экран выглядит так. Теперь нужно настроить сетевые параметры — для этого нажмите F3 (при установке через PXE адресация на узлах настраивается автоматически).

Рис. 4. Экран Talos Linux после загрузки

Задаём сетевые адреса — можно указать несколько DNS- и Time-серверов (вводятся через пробел или запятую). Нажмите «Save».

Рис. 5. Экран настройки Talos Linux

Аналогично настройте остальные узлы. Я использовал собственную адресацию, поэтому некоторые IP-адреса на скриншотах будут размыты.

Запуск установки с помощью talos-bootstrap

Запустите файл ./talos-bootstrap без параметров, чтобы получить справочную информацию.

Рис. 6. talos-bootstrap (первый запуск)

После этого запустите ./talos-bootstrap install, и в первом диалоговом окне будет предложено имя кластера по умолчанию — оно совпадает с каталогом, где находится скрипт (по умолчанию имя будет cozystack, если вы не указали своё).

Рис. 7. talos-bootstrap (задание имени кластера)

Укажите сеть, в которой будут искаться узлы.

Рис. 8. talos-bootstrap (поиск узлов в указанной сети)

Скрипт автоматически найдёт узлы и отобразит их — как видим, все три наших узла найдены. В какой-то момент обнаружение узлов перестало работать на management-host под управлением AlmaLinux, но я не стал разбираться с этой проблемой и просто перешёл на Ubuntu.

Также узлы можно искать вручную с помощью команды: nmap -Pn -n -p 50000 your_ip_network -vv | awk ‘/Discovered open port/ {print $NF}’.(Выводит список IP-адресов.)

Рис. 9. talos-bootstrap (выбор узла для установки)

На этом этапе выберите опцию «ControlPlane» и нажмите OK (все 3 узла кластера настраиваются как Control Plane).

Рис. 10. talos-bootstrap (выбор роли узла)

Далее скрипт берёт все настройки с узлов (мы задали их при настройке сети в Talos Linux, рис. 5) и выводит их в консоль. Нам остаётся только подтвердить, что всё верно.

Рис. 11. talos-bootstrap (указание имени хоста)

Выбираем диск для установки системы — у меня это sda.

Рис. 12. talos-bootstrap (выбор диска для установки)

После этого появляется наш интерфейс с предварительно настроенным IP-адресом (в моём случае это eno4). Соглашаемся и нажимаем «OK».

Рис. 13. talos-bootstrap (выбор сетевого интерфейса)

Выберите наш шлюз, затем согласитесь.

Рис. 14. talos-bootstrap (шлюз будет использоваться для доступа в Интернет)

Появляется окно для ввода адресов DNS-серверов; их можно добавить через пробел. После этого нажмите «OK».

Рис. 15. talos-bootstrap (укажите DNS-серверы или согласитесь с предложенными)

В следующем окне нужно ввести floating IP. Этот механизм в Talos очень похож на работу VRRP, но вместо низкоуровневого сетевого протокола для проверки состояния он использует кластер etcd, развёрнутый на узлах Control Plane. Floating IP обеспечивает высокую доступность кластера в сети: он «плавает» между узлами, позволяя IP-адресу перемещаться без изменения конфигурации. Введите здесь любой свободный IP из адресного пространства нашей сети (можно использовать тот же, что и на схеме топологии, например, 192.168.100.10) — это будет IP-адрес кластера.

Рис. 16. talos-bootstrap (ввод floating IP)

После этого должно появиться окно с нашим IP. Снова согласитесь.

Рис. 17. talos-bootstrap (API для kubelet)

Далее скрипт отобразит настройки, которые применяются к master-узлу.

Рис. 18. talos-bootstrap (итоговая конфигурация для запуска установки)

Нажмите «OK» и дождитесь завершения установки. В процессе установки на нашем узле будут появляться похожие строки:

Рис. 19. talos-bootstrap (экран Talos Linux)

На management-host в другой консоли можно наблюдать рост потребления трафика (с помощью утилиты nload) — это означает, что образ загружается из сети.

Рис. 20. nload (монитор сетевой нагрузки)

После установки узел будет перезагружен, а индикатор выполнения покажет сначала 20%, затем 50%, затем 70%. Именно на 70% узел перезагрузится. Снова подождите — время ожидания зависит от скорости интернет-соединения: чем быстрее интернет, тем быстрее загрузка.

Рис. 21. talos-bootstrap (процесс установки)

После установки первого узла кластера нам предлагается установить etcd. Нажмите «Yes».

Рис. 22. talos-bootstrap (установка etcd)

Остальные узлы устанавливаются аналогичным образом, за исключением предпоследнего шага. Итак, приступим к установке остальных узлов.

Рис. 23. talos-bootstrap (установка завершена)

Теперь у нас есть первый узел нашего будущего кластера.

После установки в каталоге /opt/your_name появятся новые файлы — команда ls должна выдать следующий результат:

Рис. 24. Новые файлы в каталоге

В этом каталоге нужно выполнить ряд команд — они создадут в каталоге пользователя папки с конфигурационными файлами. Эти файлы необходимы для работы kubectl и talosctl.

mkdir $HOME/.kube/
mkdir $HOME/.talos/
cp -i kubeconfig $HOME/.kube/config
cp -i talosconfig $HOME/.talos/config

Если этого не сделать, конфигурационные файлы придётся загружать вручную: для talosctl используйте команду talosctl --talosconfig=config_file, а для kubectl нужно либо выполнить KUBECONFIG=config_file в консоли пользователя (это будет действовать только в текущей сессии), либо каждый раз указывать конфигурационный файл через kubectl --kubeconfig=config_file.

Далее выполните команду:

kubectl get node

И вы получите следующий вывод:

Рис. 25. Узлы в нашем кластере

После установки остальных узлов мы завершили первоначальную настройку кластера. На данный момент он содержит лишь несколько системных компонентов, а узлы находятся в состоянии NotReady, поскольку мы отключили установку CNI и kube-proxy в конфигурации Talos. Эти компоненты будут предоставлены и управляться Cozystack.

Установка Cozystack

Создайте каталог с именем manifests и поместите в него файл с именем cozystack-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
 name: cozystack
 namespace: cozy-system
data:
 bundle-name: "paas-full"
 ipv4-pod-cidr: "10.244.0.0/16"
 ipv4-pod-gateway: "10.244.0.1"
 ipv4-svc-cidr: "10.96.0.0/16"
 ipv4-join-cidr: "100.64.0.0/16"

Последовательно выполните следующие команды:

  1. kubectl create ns cozy-system создаёт в Kubernetes новое пространство имён с именем cozy-system. Пространства имён используются для организации ресурсов внутри кластера Kubernetes.
  2. kubectl apply -f cozystack-config.yaml применяет конфигурацию из указанного файла, описывая конфигурационные данные с именем cozystack в пространстве имён cozy-system. Этот файл определяет сети, которые будут использоваться в кластере.
  3. kubectl apply -f https://github.com/aenix-io/cozystack/raw/v0.7.0/manifests/cozystack-installer.yaml— эта команда применяет конфигурацию из указанного URL. В данном случае URL указывает на файл манифеста на GitHub для установки Cozystack.
kubectl create ns cozy-system 
kubectl apply -f cozystack-config.yaml 
kubectl apply -f https://github.com/aenix-io/cozystack/raw/v0.7.0/manifests/cozystack-installer.yaml

Выполните следующее:

whatch -n1 kubectl get hr -A

А теперь дождитесь, пока состояние READY не станет True во всех NAMESPACE.

Рис. 26. Процесс установки компонентов в кластере

Когда это произойдёт, можно продолжать.

Настройка дисковой подсистемы

Выполните следующие команды:

alias linstor='kubectl exec -n cozy-linstor deploy/linstor-controller -- linstor'
linstor node list

Мы должны получить следующий вывод:

+-------------------------------------------------------+

| Node | NodeType  | Addresses                 | State  |

|=======================================================|

| srv1 | SATELLITE | 192.168.100.11:3367 (SSL) | Online |

| srv2 | SATELLITE | 192.168.100.12:3367 (SSL) | Online |

| srv3 | SATELLITE | 192.168.100.13:3367 (SSL) | Online |

+-------------------------------------------------------+
linstor physical-storage list
+--------------------------------------------+

| Size         | Rotational | Nodes          |

|============================================|

| 107374182400 | True       | srv3[/dev/nvme1n1,/dev/nvme0n1 ] |

|              |            | srv1[/dev/nvme1n1,/dev/nvme0n1] |

|              |            | srv2[/dev/nvme1n1,/dev/nvme0n1] |

+--------------------------------------------+

Создайте пул хранения. В моём случае это диски /dev/nvme1n1 и /dev/nvme0n1, но у вас они могут быть другими:

linstor ps cdp zfs srv1 /dev/nvme1n1 /dev/nvme0n1 --pool-name data --storage-pool data
linstor ps cdp zfs srv2 /dev/nvme1n1 /dev/nvme0n1 --pool-name data --storage-pool data
linstor ps cdp zfs srv3 /dev/nvme1n1 /dev/nvme0n1 --pool-name data --storage-pool data

Введите команду:

linstor sp l

Посмотрим, что получилось:

Рис. 27. Список пулов хранения

Теперь создадим классы хранилища для постоянного хранения: базовое хранилище у нас уже настроено, но нужно сообщить Kubernetes, что в нём можно создавать тома. Это делается с помощью ресурса StorageClass. Итак, мы создадим два класса:

  • local — для локального хранилища.
  • replicated — для данных, требующих репликации.
kubectl create -f- <<EOT

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: local
 annotations:
   storageclass.kubernetes.io/is-default-class: "true"
provisioner: linstor.csi.linbit.com
parameters:
 linstor.csi.linbit.com/storagePool: "data"
 linstor.csi.linbit.com/layerList: "storage"
 linstor.csi.linbit.com/allowRemoteVolumeAccess: "false"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: replicated
provisioner: linstor.csi.linbit.com
parameters:
 linstor.csi.linbit.com/storagePool: "data"
 linstor.csi.linbit.com/autoPlace: "3"
 linstor.csi.linbit.com/layerList: "drbd storage"
 linstor.csi.linbit.com/allowRemoteVolumeAccess: "true"
 property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: suspend-io
 property.linstor.csi.linbit.com/DrbdOptions/Resource/on-no-data-accessible: suspend-io
 property.linstor.csi.linbit.com/DrbdOptions/Resource/on-suspended-primary-outdated: force-secondary
 property.linstor.csi.linbit.com/DrbdOptions/Net/rr-conflict: retry-connect
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOT

Введите команду:

kubectl create -f- <<EOT

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: local
 annotations:
   storageclass.kubernetes.io/is-default-class: "true"
provisioner: linstor.csi.linbit.com
parameters:
 linstor.csi.linbit.com/storagePool: "data"
 linstor.csi.linbit.com/layerList: "storage"
 linstor.csi.linbit.com/allowRemoteVolumeAccess: "false"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: replicated
provisioner: linstor.csi.linbit.com
parameters:
 linstor.csi.linbit.com/storagePool: "data"
 linstor.csi.linbit.com/autoPlace: "3"
 linstor.csi.linbit.com/layerList: "drbd storage"
 linstor.csi.linbit.com/allowRemoteVolumeAccess: "true"
 property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: suspend-io
 property.linstor.csi.linbit.com/DrbdOptions/Resource/on-no-data-accessible: suspend-io
 property.linstor.csi.linbit.com/DrbdOptions/Resource/on-suspended-primary-outdated: force-secondary
 property.linstor.csi.linbit.com/DrbdOptions/Net/rr-conflict: retry-connect
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOT

Введите команду:

kubectl get storageclasses

Посмотрим, что получилось:

Рис. 28. Список классов хранилища

Настройка сети

Задайте пул для выделения IP-адресов из подсети, которую мы указали ранее (см. рис. 1). Примечание: если у вас другое адресное пространство (например, 192.168.100.200/192.168.100.250), в конфигурацию потребуется внести изменения, поскольку здесь настройки применяются сразу, без создания файла. Впрочем, можно сохранить конфигурацию в файл и применить манифест командой kubectl apply -f path_to_file.

kubectl create -f- <<EOT
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
 name: cozystack
 namespace: cozy-metallb
spec:
 ipAddressPools:
 - cozystack
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
 name: cozystack
 namespace: cozy-metallb
spec:
 addresses:
 - 192.168.100.200-192.168.100.250
 autoAssign: true
 avoidBuggyIPs: false
EOT

Настройка доступа к веб-интерфейсу кластера

Получите токен:

kubectl get secret -n tenant-root tenant-root -o go-template='{{ printf "%s\n" (index .data "token" | base64decode) }}'

Примечание: выполнив эту команду на management-host, мы получим токен, который нужно использовать для доступа к веб-интерфейсу Cozystack с того же management-host. Для этого выполните на management-host следующую команду:

kubectl port-forward -n cozy-dashboard svc/dashboard 8000:80

Теперь перейдите по ссылке http://localhost:8000 и введите ранее сгенерированный токен.

Рис. 29. Окно авторизации

Нажмите на «tenant-root»:

Рис. 30. Выбор tenant-root

Нажмите «Upgrade», чтобы переразвернуть приложение с нужными нам параметрами:

Рис. 31. Переход к обновлению tenant-root

Если страница не обновится сразу, нажмите F5.

Рис. 32. Окно для внесения изменений в tenant-root

Введите свои значения; мы укажем kuber.gohost.kz в поле host, переведём переключатели из false в true и нажмём «DEPLOY».

Рис. 33. Добавление компонентов и обновление tenant-root

Вы будете перенаправлены на страницу, где можно увидеть настроенные значения:

Рис. 34. tenant-root обновлён

Теперь введите в консоли следующую команду, чтобы просмотреть список всех PersistentVolumeClaim (PVC) в указанном пространстве имён tenant-root в кластере:

kubectl get pvc -n tenant-root

Если ваш вывод похож на мой, значит всё в порядке:

Рис. 35. Список PVC

Вернувшись в веб-интерфейс на главную страницу, вы должны увидеть примерно следующее:

Рис. 36. Главная страница Cozystack

Проверка подов

Чтобы проверить поды, выполните стандартную команду:

kubectl get pod -n tenant-root

Вывод должен выглядеть примерно так:

Рис. 37. Список всех подов в пространстве имён tenant-root

Теперь выполните следующую команду:

kubectl get svc -n tenant-root root-ingress-controller

В выводе мы должны увидеть публичный IP-адрес ingress-контроллера:

NAME                      TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                   AGE
root-ingress-controller   LoadBalancer   10.96.58.227   192.168.100.200   80:30149/TCP,443:32152/TCP   7d8h

Мониторинг

После установки платформы Cozystack у нас есть предварительно настроенный мониторинг на базе Grafana. Мы настроили мониторинг во время обновления tenant-root (рис. 27–31). Давайте проверим настройки мониторинга.

Для начала выберите плитку «monitoring» на главной странице:

Рис. 38. Доступ к мониторингу

Нажмите кнопку «Upgrade». В поле host проверьте свои значения (например, grafana.kuber.gohost.kz). Учётные данные можно получить, просмотрев или скопировав password и user.

Рис. 38. Получение данных авторизации

Чтобы получить доступ к веб-интерфейсу, нужно добавить в файл /etc/hosts на management-host следующие данные.

192.168.100.200 gafana.kuber.gohost.kz

На этом хосте откройте веб-браузер и введите grafana.kuber.gohost.kz. Откроется интерфейс Grafana.

Рис. 39. Окно входа в систему мониторинга

В результате выполненных шагов мы получили следующее:

  1. Кластер из трёх узлов на базе Talos Linux.
  2. Хранилище, включающее LINSTOR с ZFS и DRBD «под капотом».
  3. Удобный интерфейс.
  4. Предварительно настроенный мониторинг.

В следующей статье этой серии мы разберём Kubernetes в Kubernetes, поймём, как в Cozystack работает Kubernetes as a Service, и рассмотрим каталог приложений, где приложения можно развернуть всего в несколько кликов. Мы назначим кластеру реальные IP-адреса и настроим его для доступа из публичной сети.

Вот и всё — мы успешно установили кластер Cozystack! Оставайтесь с нами, дальше будет ещё интереснее… 😊

Дополнительные ссылки