
Процесът на актуализация за вашия Kubernetes клъстер
В някакъв момент при използването на Kubernetes клъстер може да възникне нужда от актуализиране на работещите възли. То може да включва актуализации на пакети, актуализиране на ядрото или внедряване на нови образи на виртуални машини. В терминологията на Kubernetes, това се нарича .
Тази публикация е част от цикъл от 4 публикации:
- Тази публикация.
- Коректно завършване на pod-ове в Kubernetes клъстер
- Отлагане на завършването на pod при неговото изтриване
- Как да избегнем престой в работата на Kubernetes клъстера с помощта на PodDisruptionBudgets
(прим. прев. преводите на останалите статии от цикъла очаквайте в близко бъдеще)
В тази статия ще опишем всички инструменти, които Kubernetes предоставя за постигане на нулево време на престой за работещите в клъстера възли.
Определение на проблема
Първоначално ще използваме наивен подход, за да определяме проблеми и да оценяваме потенциалните рискове от този подход, натрупвайки знания за разрешаване на всеки от проблемите, с които ще се сблъскаме през целия цикъл. В крайна сметка ще получим конфигурация, в която се използват lifecycle hooks, readiness probes и Pod disruption budgets, за да постигнем нашето нулево време на престой.
За да започнем нашия път, нека вземем конкретен пример. Да предположим, че имаме Kubernetes клъстер от две възли, в който работи приложение с два pod-а, находящи се зад Service:

Нека започнем с два pod-а с Nginx и Service, стартирани на нашите два възли в Kubernetes клъстера.
Искаме да актуализираме версията на ядрото на двата работещи възли в нашия клъстер. Как ще го направим? Просто решение би било да заредим нови възли с актуализирана конфигурация и след това да изключим старите възли, докато в същото време стартираме новите. Въпреки че това ще сработи, ще има някои проблеми с такъв подход:
- Когато изключите старите възли, стартираните на тях pod-ове също ще бъдат изключени. Какво ако pod-овете трябва да бъдат освободени за коректно изключване? Виртуализационната система, която използвате, може да не изчака завършването на процеса на освобождаване.
- Какво ако изключите всички възли едновременно? Ще получите значителен престой, докато pod-овете преминат на новите възли.
Нужен начин для правилна миграция на pod-ове от старите възли и в същото време трябва да сме сигурни, че никой от нашите работни процеси не е стартиран, докато внасяме промени в възлите. Или когато правим пълна подмяна на клъстера, както е описано в примера (т.е. заменяме имиджи на VM), искаме да пренесем работещите приложения от старите възли на новите. В двата случая искаме да предотвратим планирането на нови pod-ове на старите възли, след което да изселим всички работещи pod-ове от тях. За да постигнем тези цели, можем да използваме командата kubectl drain.
Преразпределение на всички pod-ове от възела
Операцията drain позволява преразпределяне на всички pod-ове от възела. По време на изпълнението на drain, възелът е маркиран като unschedulable (флаг NoSchedule). Това предотвратява появата на нови pod-ове на него. След това drain започва да изселва pod-овете от възела, завършвайки работа с контейнерите, които в момента работят на възела, като изпраща сигнал TERM на контейнерите в pod-а.
Въпреки че kubectl drain превъзходно ще се справи с изселването на pod-ове, но има още два фактора, които могат да причинят провал при изпълнението на операцията drain:
- Вашето приложение трябва да може правилно да завършва при подаване на
TERMсигнал. Когато pod-овете се изселват, Kubernetes изпраща сигналTERMна контейнерите и изчаква тяхното спиране за зададеното време, след което, ако не са се спрели, ги прекратява принудително. Във всички случаи, ако вашият контейнер не възприеме сигнала правилно, все пак можете да затворите pod-овете неправилно, ако в момента работят (например, протича транзакция в БД). - Вие губите всички pod-ове, в които се съдържа вашето приложение. То може да не бъде достъпно в момента на стартиране на новите контейнери на новите възли или, ако вашите pod-ове са разположени без контролери, те може да не се рестартират изобщо.
Избягване на престой
За да минимизираме времето на престой от доброволно прекъсване, например от операцията drain на възела, Kubernetes предоставя следните опции за управление на провалите:
В останалата част от цикъла ще използваме тези функции на Kubernetes, за да смекчим последиците от преместването на pod-овете. За да бъде по-лесно да проследим основната идея, ще използваме нашия пример по-горе с следната конфигурация на ресурсите:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
targetPort: 80
port: 80Тази конфигурация е минимален пример Deployment, който управлява подовете nginx в клъстера. Освен това, конфигурацията описва ресурс Service, който може да се използва за достъп до подовете nginx в клъстера.
През целия цикъл ще разширяваме итеративно тази конфигурация, така че накрая да включва всички възможности, предоставяни от Kubernetes за минимизиране на времето на престой.
За да получите напълно внедрена и тествана версия на актуализациите за клъстера Kubernetes с нулево време на престой на AWS и други ресурси, посетете .
Също така прочетете други статии в нашия блог:
Източник: habr.com
