- PVSM.RU - https://www.pvsm.ru -
Добро пожаловать в серию кратких руководств по Kubernetes. Это регулярная колонка с самыми интересными вопросами, которые мы получаем онлайн и на наших тренингах. Отвечает эксперт по Kubernetes.
Сегодняшний эксперт — Даниэль Поленчик (Daniele Polencic [1]). Даниэль работает инструктором и разработчиком ПО в Learnk8s [2].
Если вы хотите получить ответ на свой вопрос в следующем посте, свяжитесь с нами по электронной почте [3] или в Твиттере: @learnk8s [4].
Пропустили предыдущие посты? Ищите их здесь [5].
Кратко: скоро выходит 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 оркестрирует контейнеры.
Официальный ответ от 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].
Разработчики 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].
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
Нажмите здесь для печати.