kubernetes. Deployments - теория. часть3

Thank you for reading this post, don't forget to subscribe!

Кон­трол­лер раз­вер­ты­ва­ния (Deployment controller) предо­став­ля­ет воз­мож­ность декла­ра­тив­но­го обнов­ле­ния для объ­ек­тов типа поды (Pods) и набо­ры реплик (ReplicaSets).

Доста­точ­но опи­сать жела­е­мое состо­я­ние [подов/реплик] в объ­ек­те Deployment, после чего кон­трол­лер раз­вер­ты­ва­ния изме­нит теку­щее состо­я­ние объ­ек­тов на жела­е­мое в кон­тро­ли­ру­е­мом режи­ме. Сто­ит отме­тить, что при мани­пу­ля­ци­ях с раз­вер­ты­ва­ни­я­ми (Deployments) нам не нуж­но бес­по­ко­ить­ся об управ­ле­нии набо­ра­ми реплик (ReplicaSets) - все необ­хо­ди­мое будет выпол­не­но непо­сред­ствен­но кон­трол­ле­ром развертывания.

Как и для всех дру­гих API-объ­ек­тов Kubernetes, для опре­де­ле­ния Deployment в yaml-фай­ле нуж­ны поля apiVersionkind и metadata. Кро­ме того, в Deployment так­же долж­на при­сут­ство­вать сек­ция .spec.

Как мы уже гово­ри­ли, в сек­ции .spec обя­за­тель­но долж­на при­сут­ство­вать вло­жен­ная сек­ция .spec.template - шаб­лон пода (Pod). Он име­ет точ­но такой же фор­мат, как опи­са­ние пода (Pod) без сек­ций apiVersion и kind. Кро­ме обя­за­тель­ных полей, в сек­ции .spec.template при опи­са­нии Deployment нуж­но ука­зы­вать соот­вет­ству­ю­щие мет­ки (.spec.template.metadata.labels) и поли­ти­ку пере­за­пус­ка (един­ствен­ным допу­сти­мым зна­че­ни­ем для .spec.template.spec.restartPolicy явля­ет­ся Always, кото­рое соот­вет­ству­ет зна­че­нию по умолчанию).

В поле .spec.replicas ука­зы­ва­ем, сколь­ко экзем­пля­ров подов долж­но быть запу­ще­но одно­вре­мен­но - если это­го не сде­лать, то будет запу­щен толь­ко один экзем­пляр пода - .spec.replicas по умол­ча­нию рав­но единице.

Мож­но ука­зать .spec.selector - это необя­за­тель­ное поле, кото­рое опре­де­ля­ет селек­тор меток для подов, пред­на­зна­чен­ных для это­го раз­вер­ты­ва­ния. В таком слу­чае, .spec.selector дол­жен соот­вет­ство­вать зна­че­нию .spec.template.metadata.labels или будет откло­нен API Kubernetes.

В поле .spec.strategy необ­хо­ди­мо опре­де­лить стра­те­гию обнов­ле­ния ста­рых подов (Pods) новы­ми. Допу­сти­мые зна­че­ния для дан­но­го поля - Recreate или RollingUpdate (зна­че­ние по умолчанию).

Если выбрать стра­те­гию Recreate (.spec.strategy.type==Recreate), то перед стар­том новых подов будут уда­ле­ны все старые.

При стра­те­гии обнов­ле­ния RollingUpdate поды будут обнов­лять­ся плав­но, по оче­ре­ди (допол­ни­тель­но кон­тро­ли­ро­вать этот про­цесс мож­но с помо­щью пара­мет­ров maxUnavailable и maxSurge).

Пара­метр .spec.strategy.rollingUpdate.maxUnavailable - необя­за­тель­ное поле, ука­зы­ва­ю­щее мак­си­маль­ное коли­че­ство подов, кото­рые могут быть недо­ступ­ны в про­цес­се обнов­ле­ния. Зна­че­ние может быть абсо­лют­ным чис­лом (напри­мер, 5) или про­цен­том от жела­е­мо­го коли­че­ства подов (Pods) (напри­мер, 10%). Абсо­лют­ное чис­ло рас­счи­ты­ва­ет­ся из про­цен­та путем округ­ле­ния. Зна­че­ние это­го пара­мет­ра не может быть уста­нов­ле­но в 0 и по умол­ча­нию рав­но 25%.

Пара­метр .spec.strategy.rollingUpdate.maxSurge - необя­за­тель­ное поле, ука­зы­ва­ю­щее мак­си­маль­ное коли­че­ство подов (Pods), кото­рое может быть созда­но сверх жела­е­мо­го коли­че­ства подов (Pods), опи­сан­но­го в раз­вер­ты­ва­нии. Зна­че­ние может быть абсо­лют­ным чис­лом (напри­мер, 5) или про­цен­том от жела­е­мо­го коли­че­ства подов (напри­мер, 10%). Зна­че­ние это­го пара­мет­ра не может быть уста­нов­ле­но в 0 и по умол­ча­нию рав­но 25%.

Ниже пред­став­лен при­мер раз­вер­ты­ва­ния (Deployment):

В этом примере:

  • созда­ет­ся раз­вер­ты­ва­ние (Deployment) с име­нем nginx-deployment (имя ука­за­но в поле metadata: name);
  • раз­вер­ты­ва­ние созда­ет три экзем­пля­ра пода (коли­че­ство ука­за­но в поле replicas);
  • в поле селек­то­ра ука­за­но, как раз­вер­ты­ва­ние (Deployment) обна­ру­жит, каки­ми пода­ми (Pods) нуж­но управ­лять. В этом при­ме­ре про­сто выби­ра­ем одну мет­ку, опре­де­лен­ную в шаб­лоне Pod‘а (app: nginx);
  • опи­са­ние шаб­ло­на Pod‘а в поле template: spec “тре­бу­ет” запу­стить docker-кон­тей­нер nginx, из обра­за nginx вер­сии 1.7.9 (образ будет взят с Docker Hub). Дан­но­му поду будет при­сво­е­на мет­ка app: nginx;
  • раз­вер­ты­ва­ние откры­ва­ет 80-й порт кон­тей­не­ра, так что кон­тей­нер может отправ­лять и при­ни­мать трафик.

Сохра­ним дан­ный мани­фест в файл nginx-deployment.yaml и запу­стим его в кла­сте­ре Kubernetes с помо­щью команды:

При­ме­ча­ние. Пара­метр --record нам весь­ма при­го­дит­ся для хра­не­ния исто­рии изме­не­ний развертывания.

Если сра­зу же запу­стить коман­ду kubectl get deployments, то ско­рее все­го резуль­тат будет следующим:

Когда вы с помо­щью дан­ной коман­ды хоти­те полу­чить состо­я­ние раз­вер­ты­ва­ний (Deployments) в кла­сте­ре, вам доступ­ны сле­ду­ю­щие поля:

  • NAME - спи­сок имен раз­вер­ты­ва­ний в кластере;
  • DESIRED - отоб­ра­жа­ет жела­е­мое коли­че­ство экзем­пля­ров пода (опре­де­ля­ет­ся при созда­нии развертывания);
  • CURRENT - отоб­ра­жа­ет коли­че­ство экзем­пля­ров пода в насто­я­щее время;
  • UP-TO-DATE - отоб­ра­жа­ет коли­че­ство экзем­пля­ров пода, кото­рые были обнов­ле­ны для дости­же­ния жела­е­мо­го состояния;
  • AVAILABLE - отоб­ра­жа­ет коли­че­ство экзем­пля­ров пода, кото­рые доступ­ны пользователям;
  • AGE - отоб­ра­жа­ет вре­мя с момен­та запус­ка развертывания.

Что­бы уви­деть теку­щий ста­тус (про­гресс) раз­вер­ты­ва­ния, мож­но исполь­зо­вать коман­ду kubectl rollout status deployment/nginx-deployment. Вывод будет при­мер­но таким:

Через несколь­ко секунд (нуж­но ведь подо­ждать, пока ска­ча­ет­ся docker-образ) еще раз про­ве­ря­ем состо­я­ние раз­вер­ты­ва­ний в кла­сте­ре с помо­щью kubectl get deployments:

Как видим, дан­ное раз­вер­ты­ва­ние созда­ло три экзем­пля­ра пода (как мы и писа­ли в жела­е­мом состо­я­нии) - “под капо­том” был так­же создан набор реплик (ReplicaSet) - убе­дить­ся в этом мож­но с помо­щью коман­ды kubectl get rs:

Имя набо­ра реплик фор­ми­ру­ет­ся авто­ма­ти­че­ски и выгля­дит как [DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE], hash-зна­че­ние гене­ри­ру­ет­ся при созда­нии раз­вер­ты­ва­ния. Узнать какие мет­ки были авто­ма­ти­че­ски добав­ле­ны каж­до­му поду мож­но коман­дой kubectl get pods --show-labels, вывод может выгля­деть так:

Для обнов­ле­ния раз­вер­ты­ва­ния (напри­мер, изме­не­ния вер­сии docker-обра­за на 1.9.1) мож­но вос­поль­зо­вать­ся такой командой:

или изме­нить сам мани­фест раз­вер­ты­ва­ния (меня­ем зна­че­ние .spec.template.spec.containers[0].image):

или (пред­по­чти­тель­ный вари­ант) - изме­нить файл с мани­фе­стом раз­вер­ты­ва­ния и при­ме­нить изменения:

Как и рань­ше, наблю­да­ем за про­цес­сом обнов­ле­ния и полу­ча­ем инте­ре­су­ю­щую нас инфор­ма­цию коман­да­ми kubectl rollout status deployment/nginx-deploymentkubectl get deployments и kubectl get rs (ниже при­ве­ден толь­ко резуль­тат послед­ней команды):

Как видим, новый (ори­ен­ти­ру­ем­ся по вре­ме­ни) набор реплик (ReplicaSet) нахо­дит­ся в жела­е­мом состо­я­нии, в то вре­мя как в ста­ром набо­ре коли­че­ство экзем­пля­ров пода рав­но нулю.

Деталь­ное опи­са­ние раз­вер­ты­ва­ния полу­ча­ем коман­дой kubectl describe deployments:

Рас­смот­рим при­мер отка­та (воз­вра­ще­ния к преды­ду­ще­му состо­я­нию) раз­вер­ты­ва­ния (Deployment). Допу­стим, при обнов­ле­нии мы ошиб­лись и ука­за­ли невер­ную вер­сию docker-обра­за - nginx:1.91 вме­сто nginx:1.9.1:

Обнов­ле­ние засто­по­рит­ся (ожи­да­е­мо, ведь тако­го docker-обра­за нет):

Состо­я­ние набо­ра реплик будет выгля­деть при­мер­но так:

Состо­я­ние подов будет таким:

При­ме­ча­ние. Допол­ни­тель­ную инфор­ма­цию о состо­я­нии раз­вер­ты­ва­ния мож­но так­же полу­чить исполь­зуя kubectl describe deployment, но уже и так ясно - необ­хо­дим откат.

Для воз­вра­та на преды­ду­щую (рабо­то­спо­соб­ную) вер­сию раз­вер­ты­ва­ния необ­хо­ди­мо сна­ча­ла про­ве­рить исто­рию изме­не­ний (узнать номер ревизии):

Бла­го­да­ря пара­мет­ру --record мы можем уви­деть изме­не­ния, кото­рые при­ме­ня­ли в каж­дой из реви­зий. Узнать боль­ше подроб­но­стей о кон­крет­ной реви­зии раз­вер­ты­ва­ния мож­но ука­зав ее номер, напри­мер так:

Для отка­та на преды­ду­щую реви­зию доста­точ­но выпол­нить такую команду:

Для отка­та на кон­крет­ную реви­зию необ­хо­ди­мо ука­зать ее номер в пара­мет­ре --to-revision:

Для мас­шта­би­ро­ва­ния (увеличения/уменьшения коли­че­ства подов) мож­но исполь­зо­вать команду:

хотя все же луч­ше вно­сить изме­не­ния в файл с мани­фе­стом раз­вер­ты­ва­ния (Deployment) и при­ме­нять их коман­дой kubectl apply.

К раз­вер­ты­ва­ни­ям так­же при­ме­ни­мо гори­зон­таль­ное мас­шта­би­ро­ва­ние подов (HPA) - если такое вклю­че­но в вашем кла­сте­ре Kubernetes - и при­ме­нить его мож­но так:

На этом все, еще боль­ше инфор­ма­ции мож­но най­ти в офи­ци­аль­ной доку­мен­та­ции по Kubernetes