Как стать автором
Обновить
Флант
DevOps-as-a-Service, Kubernetes, обслуживание 24×7

Гибридный Kubernetes-кластер из bare metal и динамически подключаемых облачных виртуальных машин

Уровень сложностиСложный
Время на прочтение5 мин
Количество просмотров4.4K

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

Мы решили сделать гибридный кластер Kubernetes на базе существующего bare-metal-кластера, чтобы:

  • на лету заказывать узлы у облачного провайдера, когда в основном кластере заканчиваются ресурсы;

  • разворачивать на этих узлах нужные окружения для тестов;

  • сворачивать окружения после выхода изменений в production и отключать узлы.

Для этого мы воспользовались модулем cloud-provider-openstack, который входит в состав Kubernetes-платформы Deckhouse. Расскажу, как это работает.

☝️ В статье рассматривается вариант развертывания гибридного кластера в Selectel и OpenStack-облаке, которое предоставляет провайдер. Но сам подход универсален, его можно применять, к примеру, и на собственной инфраструктуре.

Настройка сетевой связности

У нас был bare-metal-кластер Kubernetes, расположенный в Selectel. Узлы в нем находились в разных зонах: SPB-3 и SPB-5. Также некоторые приложения использовали managed PostgreSQL, расположенный в облачной зоне ru-3. Чтобы была возможность дозаказывать узлы в OpenStack-облаке Selectel, нам пришлось настроить сетевое взаимодействие между уже существующими сетями и облачными.

Так выглядит L3VPN-роутер от Selectel, который позволяет связать bare-metal-узлы в зонах SPB-3 (network_SPB-3) и SPB-5 (network_SPB-5) с PostgreSQL (network_ru-3):

Четвёртую сеть — k8s_l3vpn — добавили инженеры Selectel, чтобы связать виртуальные машины (ВМ) в облаке с остальными сетями.

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

Одна из сетей дает ВМ доступ во внешнюю сеть:

Через вторую L3VPN-роутер связывает облачные ВМ с остальными сетями:

Две этих сети объединены отдельным облачным роутером, который подключен к внешней сети:

Затем мы попросили настроить маршрутизацию таким образом, чтобы ВМ, которые заказываются в сети k8s_l3vpn (192.168.200.0/24), получали маршруты вида:

            -   to: 0.0.0.0/0
                via: 192.168.200.1
            -   to: 10.13.1.0/24
                via: 192.168.200.252
            -   to: 192.168.204.0/24
                via: 192.168.200.252
            -   to: 192.168.205.0/24
                via: 192.168.200.252

В результате получилась такая схема: 

  • доступ во внешнюю сеть k8s-external-access реализован через основной шлюз 192.168.200.1;

  • доступ к «серым» подсетям организован через шлюз 192.168.200.252.

На этом подготовительные работы были закончены.

Подготовка и настройка модуля cloud-provider-openstack в Deckhouse

Мы создали сервисного пользователя с доступом к проекту, в котором заказываются ВМ.

Сделать это можно в личном кабинете Selectel: Профиль и настройки → Управление пользователями → Добавить пользователя → Сервисный пользователь. Там нужно указать имя, пароль и выдать права администратора необходимого проекта:

Затем мы создали keypair, чтобы при необходимости подключаться к ВМ по ключу:

openstack keypair create --public-key ~/.ssh/id-rsa.pub --type ssh deckhouse

Также можно загрузить свой образ, с которым будет бутстрапиться новая ВМ с помощью openstack image create.

Чтобы настроить OpenStack CLI под созданного пользователя, скачали скрипт в разделе Облачная платформаДоступ, выбрав там нужного пользователя:

И выполнили:

source rc.sh

Для работы с OpenStack мы воспользовались модулем Deckhouse cloud-provider-openstack. Вот его конфигурация:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: cloud-provider-openstack
spec:
  enabled: true
  settings:
    connection:
      authURL: <OS_AUTH_URL из rc.sh>
      domainName: <OS_PROJECT_DOMAIN_NAME из rc.sh>
      password: <пароль сервисного пользователя>
      region: <OS_REGION_NAME из rc.sh>
      tenantID: <OS_TENANT_ID из rc.sh>
      username: <имя сервисного пользователя>
    instances:
      sshKeyPairName: deckhouse # Имя keypair, созданного ранее.
    internalNetworkNames:
    - k8s_l3vpn # Имя сети, которая подключена к роутеру L3VPN и в которой будут находиться ВМ.
    podNetworkMode: DirectRouting
    zones:
    - ru-3a
  version: 1

Со всеми доступными параметрами модуля можно ознакомиться в разделе документации «OpenStack: настройки».

Сначала создали flavor с нужными параметрами:

openstack flavor create c4m8d50 --ram 8192 --disk 50 --vcpus 4 --private

Затем InstanceClass:

apiVersion: deckhouse.io/v1
kind: OpenStackInstanceClass
metadata:
  name: cloud-worker
spec:
  flavorName: c4m8d50
  imageName: ubuntu-22-04-cloud-amd64 # Берем существующий (openstack image list) или загруженный на шаге ранее.
  mainNetwork: k8s_l3vpn

И, наконец, NodeGroup:

apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
  name: cloud-worker
spec:
  chaos:
    mode: Disabled
  cloudInstances:
    classReference:
      kind: OpenStackInstanceClass 
      name: cloud-worker # Указываем имя InstanceClass, созданного ранее.
    maxPerZone: 10 # Максимальное кол-во узлов в зоне.
    minPerZone: 1 # Минимальное кол-во узлов в зоне.
    zones:
    - ru-3a
  disruptions:
    approvalMode: Automatic
  nodeTemplate:
    labels:
      node-role/cloud-worker: ""
    taints:
    - effect: NoExecute
      key: dedicated
      value: cloud-worker
  nodeType: CloudEphemeral

Работа с ВМ

Через 2–3 минуты после создания NodeGroup узлы начинают заказываться с учетом параметра minPerZone и добавляться в кластер. За процессом можно следить в панели Selectel:

И в кластере:

~ $ kubectl get no -owide | grep cloud
cloud-worker-af1ba977-7d4d4-lltnf   Ready    cloud-worker               28d      v1.23.15   192.168.200.68    <none>        Ubuntu 22.04.1 LTS   5.15.0-57-generic   docker://20.10.14

Смотрим на узлы с точки зрения cloud instance manager'a:

~ $ kubectl -n d8-cloud-instance-manager get machine
NAME                                STATUS    AGE
cloud-worker-af1ba977-7d4d4-lltnf   Running   5d3h

Если при создании возникают ошибки, связанные с недостаточностью прав или некорректным подключением к API, их можно наблюдать в логах контроллера:

~ $ kubectl -n d8-cloud-instance-manager logs -l app=machine-controller-manager -c controller

Когда временные окружения сворачиваются и ресурсы в кластере освобождаются, Cluster Autoscaler удаляет облачные ВМ.

Если требуется удалить ненужную ВМ вручную, нужно выполнить два шага.

  1. Получаем список машин:

 kubectl ‑n d8-cloud‑instance‑manager get machine NAME STATUS AGE cloud‑worker‑af1ba977–7d4d4-lltnf Running 25d
  1. Удаляем ненужную:

 kubectl -n d8-cloud-instance-manager delete machine cloud-worker-af1ba977-7d4d4-lltnf

Заключение

С помощью модуля cloud-provider-openstack, который входит в состав платформы Deckhouse, мы превратили обычный bare-metal-кластер в гибридный. В нем можно создавать различные группы узлов под специфические цели с непостоянной нагрузкой и масштабировать узлы в зависимости от потребностей.

Хотя в статье рассматривается вариант развертывания гибридного кластера в Selectel, связку «Deckhouse + модуль cloud-provider-openstack» можно использовать где угодно, в том числе и на собственной инфраструктуре.

P.S.

Читайте также в нашем блоге:

Теги:
Хабы:
Всего голосов 33: ↑33 и ↓0+33
Комментарии0

Публикации

Информация

Сайт
flant.ru
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия
Представитель
Александр Лукьянов