- PVSM.RU - https://www.pvsm.ru -

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Впервые управлять коллекцией кластеров как единым объектом пробовали с помощью инструмента 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 [11] в блоге о Kubernetes и в официальном репозитории проекта kubefed [6].

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

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

Shipper [7] чем-то похож на 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 [12] или kapitan [13]?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Автор: nAbdullin

Источник [26]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/319310

Ссылки в тексте:

[1] Daniele Polencic: https://twitter.com/danielepolencic

[2] Learnk8s: https://learnk8s.io/

[3] свяжитесь с нами по электронной почте: http://hello@learnk8s.io

[4] Твиттере: @learnk8s: https://twitter.com/learnk8s

[5] Ищите их здесь: https://learnk8s.io/visualise-dependencies-kubernetes

[6] скоро выходит Kubefed v2: https://github.com/kubernetes-sigs/federation-v2

[7] Shipper: https://github.com/bookingcom/shipper

[8] проекте multi-cluster-scheduler: https://github.com/admiraltyio/multicluster-scheduler

[9] алгоритм raft: http://thesecretlivesofdata.com/raft/

[10] в официальной документации рекомендуется использовать SSD вместо обычных жестких дисков: https://coreos.com/etcd/docs/latest/faq.html#deployment

[11] официальной статьи о kubefed2: https://kubernetes.io/blog/2018/12/12/kubernetes-federation-evolution/

[12] kustomize: https://kubernetes.io/blog/2018/05/29/introducing-kustomize-template-free-configuration-customization-for-kubernetes/

[13] kapitan: https://github.com/deepmind/kapitan

[14] этом официальном пресс-релизе: https://medium.com/booking-com-infrastructure/introducing-shipper-daf9244e3882

[15] веб-hooks для модификации доступа: https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/

[16] странице официального репозитория: https://learnk8s.io/bite-sized/connecting-multiple-kubernetes-clusters/multi-cluster-scheduler

[17] интересный случай применения с Argo: https://admiralty.io/blog/running-argo-workflows-across-multiple-kubernetes-clusters/

[18] Submariner от Rancher: https://submariner.io/

[19] Unimatrix в сочетании Spinnaker, чтобы оркестировать деплой на нескольких кластерах: https://tech.target.com/infrastructure/2018/06/20/enter-unimatrix.html

[20] единую сеть в нескольких регионах: https://itnext.io/kubernetes-multi-cluster-networking-made-simple-c8f26827813

[21] Istio для соединения нескольких кластеров: https://istio.io/docs/setup/kubernetes/install/multicluster/

[22] функцию cluster mesh: https://cilium.io/blog/2019/03/12/clustermesh/

[23] Chris Nesbitt-Smith: https://github.com/chrisns

[24] Vincent De Smet: https://github.com/so0k

[25] swatmobile.io: https://swatmobile.io/

[26] Источник: https://habr.com/ru/post/454056/?utm_campaign=454056