Как соединить кластеры Kubernetes в разных дата-центрах

в 8:30, , рубрики: clusters, devops, k8s, kubefed, multiple clusters, shipper, Блог компании Southbridge, Серверное администрирование, системное администрирование

Как соединить кластеры Kubernetes в разных дата-центрах - 1
Добро пожаловать в серию кратких руководств по Kubernetes. Это регулярная колонка с самыми интересными вопросами, которые мы получаем онлайн и на наших тренингах. Отвечает эксперт по Kubernetes.

Сегодняшний эксперт — Даниэль Поленчик (Daniele Polencic). Даниэль работает инструктором и разработчиком ПО в Learnk8s.

Если вы хотите получить ответ на свой вопрос в следующем посте, свяжитесь с нами по электронной почте или в Твиттере: @learnk8s.

Пропустили предыдущие посты? Ищите их здесь.

Как соединить кластеры Kubernetes в разных дата-центрах?

Кратко: скоро выходит Kubefed v2, а еще советую почитать о Shipper и проекте multi-cluster-scheduler.

Довольно часто инфраструктура реплицируется и распределяется по разным регионам, особенно в контролируемых средах.

Если один регион недоступен, трафик перенаправляется в другой, чтобы избежать перебоев.

С Kubernetes можно использовать схожую стратегию и распределять рабочие нагрузки по разным регионам.

У вас может быть один или несколько кластеров на команду, регион, среду или на комбинацию этих элементов.

Ваши кластеры могут размещаться в различных облаках и в локальной среде.

Но как спланировать инфраструктуру для такого географического разброса?
Нужно создать один большой кластер на несколько облачных сред по единой сети?
Или завести много маленьких кластеров и найти способ контролировать и синхронизировать их?

Один руководящий кластер

Создать один кластер по единой сети не так-то просто.

Представьте себе разделение сети.

Если у вас одна мастер-сервер, половина ресурсов не смогут получать новые команды, потому что им не удастся связаться с мастером.

И при этим у вас старые таблицы маршрутизации (kube-proxy не может загрузить новые) и никаких дополнительных pod’ов (kubelet не может запрашивать обновления).

Что еще хуже, если Kubernetes не видит узел, он помечает ее как потерянную и распределяет отсутствующие pod’ы по существующим нодам.

В итоге pod’ов у вас в два раза больше.

Если вы сделаете по одному мастер-серверу на каждый регион, будут проблемы с алгоритмом достижения консенсуса в базе данных etcd.

etcd использует алгоритм raft, чтобы согласовать значение, прежде чем записать его на диск.
То есть большинство экземпляров должны достичь консенсуса, прежде чем состояние можно будет записать в etcd.

Если задержка между экземплярами etcd резко вырастает, как в случае с тремя экземплярами etcd в разных регионах, требуется много времени, чтобы согласовать значение и записать его на диск.
Это отражается и на контроллерах Kubernetes.

Менеджеру контроллеров нужно больше времени, чтобы узнать об изменении и записать ответ в базу данных.

А раз контроллер не один, а несколько, получается цепная реакция, и весь кластер начинает работать очень медленно.

etcd настолько чувствителен к задержке, что в официальной документации рекомендуется использовать SSD вместо обычных жестких дисков.

Сейчас не существует хороших примеров большой сети для одного кластера.

В основном, сообщество разработчиков и группа SIG-cluster пытаются понять, как оркестрировать кластеры так же, как Kubernetes оркестрирует контейнеры.

Вариант 1: федерация кластеров с kubefed

Официальный ответ от SIG-cluster — kubefed2, новая версия исходного клиента и оператора kube federation.

Впервые управлять коллекцией кластеров как единым объектом пробовали с помощью инструмента kube federation.

Начало было хорошим, но в итоге kube federation так и не стал популярным, потому что поддерживал не все ресурсы.

Он поддерживал объединенные поставки и сервисы, но, к примеру, не StatefulSets.
А еще конфигурация федерации передавалась в виде аннотаций и не отличалась гибкостью.

Представьте себе, как можно описать разделение реплик для каждого кластера в федерации с помощью одних аннотаций.

Получился полный беспорядок.

SIG-cluster проделали большую работу после kubefed v1 и решили подойти к проблеме с другой стороны.

Вместо аннотаций они решили выпустить контроллер, который устанавливается на кластерах. Его можно настраивать с помощью пользовательских определений ресурсов (Custom Resource Definition, CRD).

Для каждого ресурса, который будет входить в федерацию, у вас есть пользовательское определение CRD из трех разделов:

  • стандартное определение ресурса, например деплой;
  • раздел placement, где вы определяете, как ресурс будет распределяться в федерации;
  • раздел override, где для конкретного ресурса можно переопределить вес и параметры из placement.

Вот пример объединенной поставки с разделами placement и override.

apiVersion: types.federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
  name: test-deployment
  namespace: test-namespace
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - image: nginx
              name: nginx
  placement:
    clusterNames:
      - cluster2
      - cluster1
  overrides:
    - clusterName: cluster2
      clusterOverrides:
        - path: spec.replicas
          value: 5

Как видите, поставка распределена по двум кластерам: cluster1 и cluster2.

Первый кластер поставляет три реплики, а у второго указано значение 5.

Если вам нужно больше контроля над количеством реплик, kubefed2 предоставляет новый объект ReplicaSchedulingPreference, где реплики можно распределять по весу:

apiVersion: scheduling.federation.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
  name: test-deployment
  namespace: test-ns
spec:
  targetKind: FederatedDeployment
  totalReplicas: 9
  clusters:
    A:
      weight: 1
    B:
      weight: 2

Структура CRD и API еще не совсем готовы, и в официальном репозитории проекта ведется активная работа.

Следите за kubefed2, но помните, что для рабочей среды он пока не годится.

Узнайте больше о kubefed2 из официальной статьи о kubefed2 в блоге о Kubernetes и в официальном репозитории проекта kubefed.

Вариант 2: объединение кластеров в стиле Booking.com

Разработчики Booking.com не занимались kubefed v2, зато придумали Shipper — оператор для поставки на нескольких кластерах, в нескольких регионах и в нескольких облаках.

Shipper чем-то похож на kubefed2.

Оба инструмента позволяют настраивать стратегию развертывания на нескольких кластерах (какие кластеры используются и сколько у них реплик).

Но задача Shipper — снизить риск ошибок при поставке.

В Shipper можно определить ряд шагов, которые описывают разделение реплик между предыдущим и текущим деплоем и объем входящего трафика.

Когда вы отправляете ресурс в кластер, контроллер Shipper пошагово развертывает это изменение по всем объединенным кластерам.

А еще Shipper очень ограничен.

Например, он принимает Helm-чарты как входные данные и не поддерживает vanilla ресурсы.
В общих чертах, Shipper работает следующим образом.

Вместо стандартной поставки нужно создать ресурс приложения, включающий Helm-чарт:

apiVersion: shipper.booking.com/v1alpha1
kind: Application
metadata:
  name: super-server
spec:
  revisionHistoryLimit: 3
  template:
    chart:
      name: nginx
      repoUrl: https://storage.googleapis.com/shipper-demo
      version: 0.0.1
    clusterRequirements:
      regions:
        - name: local
    strategy:
      steps:
        - capacity:
            contender: 1
            incumbent: 100
          name: staging
          traffic:
            contender: 0
            incumbent: 100
        - capacity:
            contender: 100
            incumbent: 0
          name: full on
          traffic:
            contender: 100
            incumbent: 0
    values:
      replicaCount: 3

Shipper неплохой вариант для управления несколькими кластерами, но его тесная связь с Helm только мешает.

А вдруг мы все перейдем с Helm на kustomize или kapitan?

Узнайте больше о Shipper и его философии в этом официальном пресс-релизе.

Если хотите покопаться в коде, отправляйтесь в официальный репозиторий проекта.

Вариант 3: "магическое" объединение кластеров

Kubefed v2 и Shipper работают с федерацией кластеров, предоставляя кластерам новые ресурсы через пользовательское определение ресурсов.

Но вдруг вы не хотите переписывать все поставки, StatefulSets, DaemonSets и т. д. для объединения?

Как включить существующий кластер в федерацию, не меняя YAML?

multi-cluster-scheduler — это проект Admirality, который занимается рабочими нагрузками планирования в кластерах.

Но вместо того, чтобы придумывать новый способ взаимодействия с кластером и оборачивать ресурсы в пользовательские определения, multi-cluster-scheduler внедряется в стандартный жизненный цикл Kubernetes и перехватывает все вызовы, которые создают поды.

Каждый создаваемый под сразу заменяется на пустышку.

multi-cluster-scheduler использует веб-hooks для модификации доступа, чтобы перехватить вызов и создать бездействующий pod-пустышку.

Исходный pod проходит через еще один цикл планирования, где после опроса всей федерации принимается решение о размещении.

Наконец, pod поставляется в целевой кластер.

В итоге у вас лишний pod, который ничего не делает, просто занимает место.

Преимущество в том, что вам не пришлось писать новые ресурсы для объединения поставок.

Каждый ресурс, создающий pod, автоматически готов для объединения.

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

Но если Shipper старается, в основном, смягчить последствия поставок, multi-cluster-scheduler выполняет более общие задачи и, возможно, лучше подходит для пакетных заданий.

У него нет продвинутого механизма постепенных поставок.

Больше о multi-cluster-scheduler можно узнать на странице официального репозитория.

Если хотите прочитать о multi-cluster-scheduler в действии, у Admiralty есть интересный случай применения с Argo — рабочими процессами, событиями, CI и CD Kubernetes.

Другие инструменты и решения

Соединение нескольких кластеров и управление ими — сложная задача, универсального решения не существует.

Если вы хотите подробнее изучить эту тему, вот вам несколько ресурсов:

Вот и все на сегодня

Спасибо, что дочитали до конца!

Если вы знаете, как эффективнее соединить несколько кластеров, расскажите нам.

Мы добавим ваш способ к ссылкам.

Особая благодарность Крису Несбитту-Смиту (Chris Nesbitt-Smith) и Венсану де Сме (Vincent De Smet) (инженеру по надежности в swatmobile.io) за то, что прочитали статью и поделились полезной информацией о том, как работает федерация.

Автор: nAbdullin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js