Kubernetes кластер на базе Talos в OpenStack

от автора

Хабр, привет! Я Максим, технический директор в облаке Амвера и в этой статье я хотел бы поделиться опытом развертывания кластера kubernetes, который под капотом использует OpenStack. В этой статья я хочу пошагово рассказать про путь развертывания, подсветив те места, которые вызвали у меня затруднения.

Про Amvera Cloud

Amvera  это облако для простого деплоя приложений через git push. Встроенный CI/CD, бэкапы и мониторинг позволяют развернуть проект тремя командами в IDE и не думать о настойке инфраструктуры. Amvera проще, чем использование VPS или Kubernetes-кластера. Все проекты мы запускаем в Kubernetes. Данная статья о том, как мы разворачивали кластер для нашей международной зоны доступности в Варшаве.

Подготовка образа

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

Команда разработчиков Talos позаботилась о том, что их ОС может развертываться на разных платформах и подготовила специальный конструктор образа. Чтобы получить образ для OpenStack выполним следующие шаги:

  1. Hardware Type — выбираем «Cloud Server»

  2. Choose Talos Linux Version — версия ОС. На момент развертывания кластера автором, последняя версия была 1.8.3. Всегда лучше выбирать последнюю стабильную версию.

  3. Cloud — тут выбираем, в каком облаке будем разворачивать. В моём случае это OpenStack.

  4. Machine Architecture — архитектура процессора, на котором будет разворачивается кластер (или конкретный узел).

  5. System Extensions — это самый интересный пункт. Базовый Talos не содержит в себе многих привычных модулей ядра, они должны быть добавлены через расширения. Так, если планируется использовать Longhorn, нужно добавить «iscsi-tools» и «util-linux-tools». Нужно заранее подумать о том, что потребуется разворачивать на нодах с данным образом и не забыть включить нужные расширения, иначе можно столкнуться с ошибками при запуске подов.

  6. Customization — можно указать дополнительные параметры запуска ядра, но я оставляю это поле пустым.

  7. Schematic Ready — мы добрались до страницы, с которой можно загрузить образ, который будет содержать все указанные на этапе 5 расширения. Мой облачный провайдер поддерживает загрузку только raw образов, поэтому я скачивал «Disk Image».

  8. Как только образ загрузится, грузим его в OpenStack.

Создание ВМ для администрирования

Из соображений безопасности и удобства конфигурации будущих узлов с Talos, создадим виртуальную машину, с которой будем настраивать кластер. Я выбрал ВМ с установленной на нее ОС Ubuntu 24.04. ВМ должна быть подключена к той-же сети, в которой ранее создавались порты и иметь внешний IP для доступа по SSH.

Нам потребуется установить две CLI — одну для работы с Openstack, другую для работы с Talos. Для этого выполним простые действия:

apt update  # Opensatck CLI apt install python3-openstackclient apt install python3-octaviaclient  # Talos CLI curl -sL https://talos.dev/install | sh

Так-же потребуется поставить kubectl.

Создание k8s кластера

Процесс создания узлов с Talos в OpenStack довольно подробно рассмотрено в их документации. Важно отметить, что ваш облачный провайдер должен поддерживать создание сетевого LoadBalancer. В нашем случае ребята из ProCloud, которых мы выбрали для базы иностранной зоны доступности, выдали ранний доступ к этой фиче, которая в скором времени будет доступна всем желающим. Для доступа к консоли OpenStack вам так-же необходимо запросить права доступа у вашего провайдера.

Как могут выглядеть креды доступа в OpenStack
export OS_AUTH_URL=https://some.url export OS_PROJECT_NAME="my-project" export OS_USER_DOMAIN_ID="default" export OS_PROJECT_DOMAIN_ID="default" export OS_USERNAME="username" export OS_PASSWORD="password" export OS_REGION_NAME="region" export OS_INTERFACE=public export OS_IDENTITY_API_VERSION=3 export OS_VOLUME_API_VERSION=3.63 export OS_COMPUTE_API_VERSION=2.87

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

  1. Создание балансировщика для control plane узлов.

    # Создание балансировщика В proCloud  # Использование в vip-subnet-id IPv6 это особенность провайдера. При возможности лучше использовать сразу IPv4 без additional-vip openstack loadbalancer create --vip-subnet-id IPv6 --additional-vip subnet-id=IPv4-2 --flavor amph-failover-standard --name talos-control-plane    # Создание listener openstack loadbalancer listener create --name talos-control-plane-listener --protocol TCP --protocol-port 6443 talos-control-plane    # Pool and health monitoring openstack loadbalancer pool create --name talos-control-plane-pool --lb-algorithm ROUND_ROBIN --listener talos-control-plane-listener --protocol TCP openstack loadbalancer healthmonitor create --delay 5 --max-retries 4 --timeout 10 --type TCP talos-control-plane-pool 

  2. Создание сети, подсети и портов.

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

    openstack port create --network talos-k8s talos-control-plane-1 openstack port create --network talos-k8s talos-control-plane-2 openstack port create --network talos-k8s talos-control-plane-3

    В исходном руководстве ещё для каждой ноды создается отдельный floating ip, но на мой взгляд это избыточно, так как чтобы «ходить» на отдельные ноды достаточно локальной сети и балансировщика.

  3. Смотрим, какие IP адреса присвоились портам на шаге 2 и создаем на основе них member(ов) у балансировщика.

    # Создание members для каждого порта с IP. openstack loadbalancer member create --subnet-id shared-subnet --address <PRIVATE IP OF talos-control-plane-1 PORT> --protocol-port 6443 talos-control-plane-pool openstack loadbalancer member create --subnet-id shared-subnet --address <PRIVATE IP OF talos-control-plane-2 PORT> --protocol-port 6443 talos-control-plane-pool openstack loadbalancer member create --subnet-id shared-subnet --address <PRIVATE IP OF talos-control-plane-3 PORT> --protocol-port 6443 talos-control-plane-pool

Создание и конфигурация ВМ с TalosOS

  1. Создадим ВМ с загрузочным образом Talos, который мы подготовили и присоединив заранее созданный порт. У нас в Амвере большое количество пользователей, хостящих свои боты, сайты и API. Кластер должен быть рассчитан на десятки тысяч подов, поэтому для control plane я выбрал ВМ с 4 vCPU, 8GB RAM и 64GB самого быстрого SSD. Выбор размера ВМ в основном обуславливается требованиями etcd.

  2. После запуска ВМ, можно открыть предоставляемую хостингом VNC консоль и убедиться, что узел запустился и перешел в maintenance mode.

  3. Выполним команду talosctl gen config talos-k8s-openstack-tutorial https://${LB_PUBLIC_IP}:6443 чтобы получить шаблон файла конфигурации. Важно, чтобы переменная LB_PUBLIC_IP содержала внешний адрес вашего созданного балансировщика.

  4. По итогу будет создано три файла: controlplane.yaml, talosconfig, worker.yaml.

  5. Отредактируем конфигурацию controlplane, установив необходимые параметры (в зависимости от используемых плагинов могут потребоваться дополнительные изменения):

    cluster:   clusterName: amvera   externalCloudProvider:     enabled: true
  6. Применим конфиг через talosctl apply-config --insecure -n 192.168.0.10 --file ./controlplane.yaml, где после -n стоит IP адрес узла во внутренней сети (тот, который был выдан порту, что мы присоединили к ВМ).

  7. Создадим ещё две ВМ и применим к ним тот-же самый конфиг.

  8. Теперь отредактируем файл worker.yaml

    cluster:   clusterName: amvera   externalCloudProvider:     enabled: true  # Для узлов, где будет запущен longhorn machine:   kubelet:     extraMounts:       - destination: /var/lib/longhorn         type: bind         source: /var/lib/longhorn         options:           - bind           - rshared           - rw   disks:       - device: /dev/sdb         partitions:           - mountpoint: /var/lib/longhorn
  9. Создадим ВМ (порт в openstack уже можно создать вместе с ней динамически) и применяем к ней конфиг talosctl apply-config --insecure -n 192.168.0.15 --file ./worker.yaml

Развертывание etcd

  1. Добавим узлы в файл конфигурации для talosctl

    talosctl --talosconfig talosconfig config endpoint <control plane 1 IP>  talosctl --talosconfig talosconfig config node <control plane 1 IP> 
  2. Развернем etcd:

    talosctl --talosconfig talosconfig bootstrap
  3. Через какое-то время все узлы будут запущены и KUBELET должен перейти в статус Healthy.

  4. Остается получить конфиг для доступа в кластер через talosctl --talosconfig talosconfig kubeconfig .

  5. Теперь, скопируем наш kubeconfig в .kube/config и проверим, что наши узлы кластера видны и запущены через kubectl get nodes

Установка Cloud Provider OpenStack

Для того, чтобы наш кластер kubernetes мог ходить в OpenStack и создавать там диски или балансировщики, необходимо поставить Cloud Provider OpenStack. Там есть совершенно разные плагины, лично меня интересовал только OpenStack Cloud Controller Manager для создания балансировщиков и Cinder CSI Plugin, чтобы при создании PV, диски сами создавались в OpenStack и монтировались к нужному узлу.

Для работоспособности необходимо создать файл cloud-config с конфигурацией и кредами от OpenStack

[Global] auth-url=OS_AUTH_URL username=OS_USERNAME password=OS_PASSWORD tenant-name=OS_PROJECT_NAME domain-name=default project-domain-name=OS_PROJECT_DOMAIN_ID user-domain-name=OS_USER_DOMAIN_ID region=OS_REGION_NAME  [LoadBalancer] lb-version=v2 subnet-id=<subnet_id> # ID подсети, из которой балансировщик будет выделять IP  floating-network-id=<floating_network_id> # ID сети в которой существует вышеуказанная подсеть  flavor-id=<flavor_id> # ID тарифа балансировщика member-subnet-id=<member_subnet_id> # ID сети, в которой будут создаваться member. В моем случае это подсеть сети talos-k8s. create-monitor=true monitor-delay=5s monitor-timeout=3s monitor-max-retries=3  [BlockStorage] trust-device-path=false ignore-volume-az=true

OpenStack Cloud Controller Manager

Чтобы поставить этот модуль достаточно выполнить команды из документации.

  1. Создать секрет из файла cloud-config описанного выше.

    kubectl create secret -n kube-system generic cloud-config --from-file=cloud.conf
  2. Пометить namespace для необходимых прав доступа, создать RBAC ресурсы и openstack-cloud-controller-manager daemonset.

    kubectl label namespace kube-system pod-security.kubernetes.io/enforce=privileged kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/master/manifests/controller-manager/cloud-controller-manager-roles.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/master/manifests/controller-manager/cloud-controller-manager-role-bindings.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/master/manifests/controller-manager/openstack-cloud-controller-manager-ds.yaml
  3. Теперь если попробовать создать в кубере Service с типом LoadBalancer, то он должен через как-то время создать балансировщик в OpenStack и автоматически его настроить и подключить.

Если основная сеть для балансировщика у вашего провайдера это IPv6, то IPv4 балансировщики в кубере через стандартный controller manager создавать не получится.

Чтобы обойти эту проблему, я создал fork основного репозитория, где добавил возможность указывать параметр additional-vip subnet-id.

В таком случае в cloud-config для параметра subnet-id указывается IPv6 подсеть, и в новый параметр additional-vips-subnet-id указывается уже IPv4 посдеть.

Сinder csi plugin

Установка производится так-же через применение манифестов, которые можно найти в репозитории в manifests/cinder-csi-plugin

 kubectl -f manifests/cinder-csi-plugin/ apply

Можно теперь создать StorageClass:

--- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:   name: ssd-lite provisioner: cinder.csi.openstack.org allowVolumeExpansion: true parameters:   type: SSD_Lite # Тип диска у провайдера   availability: WAW-1 # Регион провайдера

Теперь, при создании PV и PVC заданного класса они будут автоматически создаваться в OpenStack и монтироваться к той ноде, на которой запущен Pod. Стоит отметить, что количество дисков, которые могут быть примонтированы к одной ВМ ограничено и точные ограничения стоит уточнять у Вашего провайдера.

Заключение

В данной статье я рассмотрел процесс создания и настройки кластера кубернетис, который теперь будет использоваться в облаке Амвера в зарубежном регионе. Были рассмотрены основные моменты конфигурации с которыми могут столкнуться начинающие администраторы. Так-же важно было подсветить возможность использования Cloud Provider OpenStack плагина.


ссылка на оригинал статьи https://habr.com/ru/articles/867094/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *