Привет! Я Владислав Карабасов, работаю в казахстанской хостинговой компании gohost. Сюда я перешел из университета, которому отдал без малого 20 лет, в том числе был руководителем Центра информационных технологий и телекоммуникаций.

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

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

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

  • Платформа позволяет разворачивать кластера Kubernetes внутри уже существующего кластера без использования виртуализации для запуска Kubernetes control-plane, в то же время запуская воркеры как виртуалки в существующем Kubernetes-кластере. Это позволяет добиться оптимальной утилизации ресурсов, не проигрывая в безопасности.

  • Talos Linux, на котором основана платформа, имеет очень высокий уровень безопасности. 

  • Кроме того, создатели платформы — активные участники русскоязычного сообщества Kubernetes и вносят значительный вклад в Open Source, в том числе организовав сообщество по разработке собственного etcd-operator.

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

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

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

Хотя Cozystack за несколько минут разворачивается прямо на железе, платформу можно развернуть и в любой виртуальной среде — я, например, начинал с развертывания кластеров в Proxmox и KVM.

Но в статье буду рассказывать об опыте установки на реальное железо. Начнем с сетапа — у меня было следующее оборудование:

  1. VPS 2G/2CPU (хотя можно использовать и обычный домашний ПК) — 1 шт.

  2. Коммутатор — 2 шт. (в режиме агрегирования -  данный режим позволяет повысить отказоустойчивость, пропускную способность и осуществлять балансировку.Рис 1.) или 1 шт. (без агрегирования Рис 2.).

  3. Серверы с  локальным хранилищем на NVMe-дисках (для контейнеров) и SSD-диски (для операционной системы). Минимальное количество серверов в кластере, которое обеспечивает отказоустойчивость — 3 шт.

Можно использовать и сетевую СХД, например, на связке DRBD + Linstor (такие СХД мы используем у себя в продакшене под VPS, однако их конфигурирование — тема для отдельной большой статьи, поэтому в данном случае ограничимся серверами).

Вот так выглядела схема оборудования для развертывания Cozystack в моем случае Рис 1. Настройку коммутации оставлю за скобками. 

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

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

Подготовка management-хоста 

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

Перейдем непосредственно к развертыванию management-хоста. Для этого я предлагаю воспользоваться моим 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' # No Color

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}Выберите версию для скачивания:${NC}"
select version in $releases; do
    if [[ -n "$version" ]]; then
        echo "Вы выбрали версию $version"
        break
    else
        echo -e "${RED}Неверный выбор. Пожалуйста, попробуйте еще раз. ${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}Выберите версию kubectl для скачивания:${NC}"
select version in $releases; do
    if [[ -n "$version" ]]; then
        echo  "Вы выбрали версию $version"
        break
    else
        echo -e "${RED}Неверный выбор. Пожалуйста, попробуйте еще раз. ${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 "Укажите название директории для конфигурационных файлов,"
echo -e "директория будет располагаться в каталоге ${GREEN}/opt/${NC}. По умолчанию: ${GREEN}/opt/cozystack${NC}"
echo -e "${YELLOW}"
read -p "Введите название директории: " 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}Укажите IP-сеть для  etcd и kubelet${NC}"
echo -e "По умолчанию: ${GREEN} 192.168.100.0/24 ${NC}"
read -p "IP-сеть (network/mask): " IPEK 
if [ -z "$IPEK" ]; then    
  IPEK="192.168.100.0/24" 
fi
#ADD 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
# ADD 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
# ADD 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-утилита от разработчиков Cozy Stack для конфигурирования Talos Linux — своего рода Helm для Talos), а потом устанавливает их и раскладывает по каталогам. Весь процесс автоматизирован и сопровождается осмысленными диалогами. Кроме того, на хосте поднимаются служба времени NTP, служба доменных имен bind9 и создаются правила для организации доступа из кластера в интернет через management-хост. 

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

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

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

Ура! Management-хост готов для дальнейшей работы. 

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

Операционная система, на которой базируется Cozystack, — это Talos Linux.

Существует несколько способов установки Cozystack:

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

ISO — для установки с использованием ISO-образов.

Hetzner — для установки на серверы Hetzner.

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

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

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

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

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

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

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

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

Запускаем файл ./talos-bootstrap без всяких параметров и получаем справку.

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

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

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

Задаем сеть в которой будет происходить поиск нод.

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

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

Ноды можно поискать и вручную с помощью команды:

nmap -Pn -n -p 50000 ваша_ip_сеть  -vv|awk '/Discovered open port/ {print $NF}'

Команда выводит список IP.

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

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

Рис. 10. talos-bootstrap (выбираем роль ноды ControlPlane)
Рис. 10. talos-bootstrap (выбираем роль ноды ControlPlane)

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

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

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

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

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

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

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

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

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

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

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

Рис. 16. talos-bootstrap (прописываем плавающий IP)
Рис. 16. talos-bootstrap (прописываем плавающий IP)

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

Рис. 17. talos-bootstrap (API - куда ходят kublet)
Рис. 17. talos-bootstrap (API - куда ходят kublet)

Далее скрипт выведет настройки, которые применяются к мастер-ноде.

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

Нажимаем OK и ждем когда закончится установка. На нашей ноде появятся в процессе установки похожие строки:

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

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

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

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

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

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

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

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

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

Ура! У нас есть первая нода будущего кластера.

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

Рис. 24. Новые файлы в директории
Рис. 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. Ноды в кластере
Рис. 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 создает новый namespace в 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

Запускаем:

 watch -n1 kubectl get hr -A 

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

Рис. 26. Наблюдаем за установкой компонентов в кластер
Рис. 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]  |

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

Создаем storage pool. У меня это диски /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. Список пулов хранения
Рис. 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 get storageclasses

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

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

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

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

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

Настройка доступа к Web UI кластера 

Получаем токен:

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

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

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

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

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

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

Рис. 30. Выбираем tenant-root
Рис. 30. Выбираем tenant-root

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

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

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

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

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

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

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

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

Теперь вводим в консоли команду, для просмотра списка всех PersistentVolumeClaim (PVC) в указанном пространстве имен tenant-root в кластере.

kubectl get pvc -n tenant-root

Если ваш вывод аналогичен моему, значит, все хорошо:

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

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

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

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

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

kubectl get pod -n tenant-root

Примерно таким должен быть ее вывод:

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

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

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

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

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.  Доступ к мониторингу
Рис. 38.  Доступ к мониторингу

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

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

Теперь необходимо получить доступ к веб-интерфейсу — для этого мы на management-хосте прописываем в файл /etc/hosts следующие данные.

192.168.100.200 grafana.kuber.gohost.kz 

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

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

В результате проделанных манипуляций мы получили следующее:

  1. Кластер из трех нод на базе ОС Talos Linux.

  2. Хранилище, где под капотом уже есть LINSTOR с ZFS и DRBD.

  3. Удобный пользовательский интерфейс.

  4. Предварительно настроенный мониторинг.

В следующей статье цикла мы рассмотрим Kubernetes in Kubernetes, разберемся, как в Cozystack функционирует Kubernetes as a Service, а также изучим каталог приложений, которые разворачиваются буквально в пару кликов мышки. Зададим реальные IP кластеру и выпустим его в публичную сеть. 

Ну вот мы и установили кластер Cozystack:)) Продолжение следует…

P.S.

Дополнительные материалы

Комментарии (9)


  1. Artarik
    08.08.2024 10:01

    Почему козистек, а не декхаус, например? В описании особенностей козистек во втором пункте есть повторение из первого пункта


    1. NavL
      08.08.2024 10:01

      Скорее всего потому что deckhouse денег просит,а cozystack open source


      1. Artarik
        08.08.2024 10:01

        Community version бесплатная.


        1. karabass_off Автор
          08.08.2024 10:01
          +1

          Распростроняется бесплатно.


    1. karabass_off Автор
      08.08.2024 10:01
      +2

      Мы выбрали CozyStack по нескольким причинам. Мы подключились к проекту на старте, что дало нам возможность активно участвовать в его развитии. У нас был положительный опыт работы с решениями от участников из команды разработки CozyStack, что укрепило наше доверие к проекту.

      Проект "Deckhouse" не рассматривали.

      Исправил, спасибо!


      1. Artarik
        08.08.2024 10:01

        А, я не обратил внимание, что статья от AEnix :)

        Будет продолжение с примером разворачивания в существующем кластере не на базе Талос?


        1. karabass_off Автор
          08.08.2024 10:01

          Talos OS — это фундамент всего кластера, на котором развёрнут Kubernetes, и без него никуда. В дальнейшем, в существующем кластере создаётся отдельный tenant для каждого арендатора, при этом арендатор не имеет доступа к управляющему кластеру.


    1. kvaps
      08.08.2024 10:01
      +3

      Несмотря на схожесть, это немного разные продукты решающие совсем разные задачи.

      Cozystack - это платформа для предоставления managed-сервисов.
      Deckhouse - это дистрибутив Kubernetes преднастроенный для использования.

      Насколько мне известно на данный момент Deckhouse не умеет запускать полнофункциональные кластера Kubernetes по кнопке, как и предоставлять остальные managed-сервисы в мультитенантной среде.


  1. SlavikF
    08.08.2024 10:01

    CozyStack как-то похоже на Harvester от SUSE. У них тоже идёт в комплекте Grafana, Prometheus, Longhorn. Тоже можно деплоить кластер в кластере.

    Или я неправ про аналогию?

    Хранилище, где под капотом уже есть LINSTOR с ZFS

    Как-то не понял, как получилось скрестить ZFS (низкоуровневая файловая система, в кластер не умеет) и LINSTOR (кластерная файловая система). Хотя на сайте у LINSTOR тоже написано, что эта возможность у них есть из коробки, но интересно почитать, как это работает.