Добре дошли в серия кратки ръководства за Kubernetes. Това е редовен стълб с най-интересните въпроси, които получаваме онлайн и на нашите обучения. Отговаря експерт по Kubernetes.
Днешният експерт е Даниел Поленчик (). Даниел работи като инструктор и разработчик на софтуер в .
Ако искате да получите отговор на въпроса си в следващия пост, или в .
Пропуснали ли сте предишните постове? .
Как да свържете Kubernetes клъстери в различни дата центрове?
Накратко: , а също така препоръчвам да прочетете за и .
Доста често инфраструктурата се репликира и разпределя в различни региони, особено в контролирани среди.
Ако един регион е недостъпен, трафикът се пренасочва към друг, за да се избегнат прекъсвания.
С Kubernetes може да се използва подобна стратегия и да се разпределят работните натоварвания в различни региони.
Може да имате един или няколко клъстера за екип, регион, среда или комбинация от тези елементи.
Вашите клъстери могат да са разположени в различни облаци и в локална среда.
Но как да планирате инфраструктурата за такова географско разпръсване?
Трябва ли да създадете един голям клъстер за няколко облачни среди по единна мрежа?
Или да създадете много малки клъстери и да намерите начин да ги контролирате и синхронизирате?
Един ръководен клъстер
Създаването на един клъстер по единна мрежа не е толкова просто.
Представете си, че имате авария, загубена свързаност между сегментите на клъстера.
Ако имате един майстор-сървър, половината от ресурсите няма да могат да получават нови команди, защото не могат да се свържат с майстора.
И при това имате стари таблици за маршрутизиране (kube-proxy не могат да заредят нови) и никакви допълнителни pod-ове (kubelet не може да прави заявки за актуализации).
При това, ако Kubernetes не вижда възел, той го помечава като загубен и разпределя липсващите pod-ове на съществуващите възли.
В резултат на това имате два пъти повече pod-ове.
Ако направите по един майстор-сървър за всеки регион, ще има проблеми с алгоритъма за постигане на консенсус в базата данни etcd. (бел. ред. — Всъщност, базата данни etcd не е задължително да бъде на майстор сървъри. Може да бъде стартирана на отделна група сървъри в един регион. Въпреки това, получавате точка на отказ на клъстера. Но е бързо.)
etcd използва , за да постигне съгласие относно стойността, преди да я запише на диск.
Тоест, повечето екземпляри трябва да постигнат консенсус, преди състоянието да може да бъде записано в etcd.
Ако закъснението между екземплярите на etcd рязко нараства, както е при три екземпляра на etcd в различни региони, отнема много време, за да се постигне съгласие и да се запише стойността на диск.
Това се отразява и на контролерите на Kubernetes.
Мениджърът на контролерите има нужда от повече време, за да научи за промяната и да запише отговор в базата данни.
А тъй като контролерите не са един, а няколко, възниква верижна реакция и целият клъстер започва да работи много бавно..
etcd е толкова чувствителен към закъснение, че .
В момента няма добри примери за голяма мрежа за един клъстер.
Основно, общността на разработчиците и групата SIG-cluster се опитват да разберат как да оркестрират клъстери, подобно на това как Kubernetes оркестрира контейнери.
Вариант 1: федерация на клъстери с kubefed
Официалният отговор от SIG-cluster е .
За първи път да управляват колекция от клъстери като един обект е било опитано с инструмента 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 от в блога за Kubernetes и в .
Вариант 2: комбиниране на клъстери в стил Booking.com
Разработчиците на Booking.com не се занимаваха с kubefed v2, но създадоха 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: 3Shipper е добро решение за управление на множество клъстери, но тясната му връзка с Helm само пречи.
Ами ако всички преминем от Helm на или ?
Научете повече за Shipper и неговата философия в .
Ако искате да се задълбочите в кода, .
Вариант 3: "магическото" обединение на клъстери
Kubefed v2 и Shipper работят с федерация на клъстери, предоставяйки на клъстерите нови ресурси чрез потребителски дефиниции на ресурси.
Но какво, ако не искате да преписвате всички доставки, StatefulSets, DaemonSets и т.н. за обединение?
Как да включите съществуващ клъстер във федерацията, без да променяте YAML?
, който се занимава с натоварвания за планиране в клъстери.
Но вместо да изобретявате нов начин за взаимодействие с клъстера и да обвивате ресурсите в потребителски дефиниции, multi-cluster-scheduler се интегрира в стандартния жизнен цикъл на Kubernetes и прихваща всички извиквания, които създават подове.
Всеки създаден под незабавно се заменя с празен.
multi-cluster-scheduler използва , за да прихване извикването и да създаде неактивен pod-празен.
Изходният pod преминава през още един цикъл на планиране, където след проучване на цялата федерация се взема решение за разполагане.
Накрая, pod се предоставя на целевия клъстер.
В резултат на това имате допълнителен pod, който не прави нищо, просто заема място.
Предимството е, че не е нужно да пишете нови ресурси за обединение на доставките.
Всеки ресурс, който създава pod, автоматично е готов за обединение.
Интересно, что у вас внезапно появляются поставки, распределенные по нескольким регионам, и вы этого не замечаете. Тем не менее, это довольно рискованно, поскольку всё зависит от магии.
Но если Shipper старается в основном смягчить последствия поставок, multi-cluster-scheduler решает более общие задачи и, возможно, лучше подходит для пакетных заданий.
У него нет продвинутого механизма поэтапных поставок.
Больше о multi-cluster-scheduler можно узнать на .
Если хотите увидеть multi-cluster-scheduler в действии, у Admiralty есть — рабочими процессами, событиями, CI и CD Kubernetes.
Другие инструменты и решения
Соединение нескольких кластеров и их управление — сложная задача, универсального решения не существует.
Если вы хотите подробнее изучить эту тему, вот несколько ресурсов:
- — инструмент, соединяющий оверлейные сети различных кластеров Kubernetes.
- Розничная сеть Target использует .
- Попробуйте использовать IPV6 и .
- Можно использовать service mesh, например, .
- Cilium, плагин интерфейса сети контейнеров, предлагает которая позволяет объединять несколько кластеров.
На сегодня всё.
Благодаря, че прочетохте до края!
Если вы знаете, как эффективнее соединить несколько кластеров, .
Мы добавим ваш способ к ссылкам.
Особая благодарность Крису Несбитту-Смитту () и Венсану де Смету () (инженеру по надежности в ) за то, что прочитали статью и поделились ценными данными о том, как работает федерация.
Източник: habr.com
