Thank you for reading this post, don't forget to subscribe!
Контроллер развертывания (Deployment controller) предоставляет возможность декларативного обновления для объектов типа поды (Pods
) и наборы реплик (ReplicaSets
).
Достаточно описать желаемое состояние [подов/реплик] в объекте Deployment
, после чего контроллер развертывания изменит текущее состояние объектов на желаемое в контролируемом режиме. Стоит отметить, что при манипуляциях с развертываниями (Deployments
) нам не нужно беспокоиться об управлении наборами реплик (ReplicaSets
) - все необходимое будет выполнено непосредственно контроллером развертывания.
Как и для всех других API-объектов Kubernetes
, для определения Deployment
в yaml-файле нужны поля apiVersion
, kind
и 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
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 |
В этом примере:
- создается развертывание (
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
с помощью команды:
1 2 |
kubectl create <span class="hljs-_">-f</span> nginx-deployment.yaml --record |
Примечание. Параметр --record
нам весьма пригодится для хранения истории изменений развертывания.
Если сразу же запустить команду kubectl get deployments
, то скорее всего результат будет следующим:
1 2 3 |
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 0 0 0 1s |
Когда вы с помощью данной команды хотите получить состояние развертываний (Deployments
) в кластере, вам доступны следующие поля:
NAME
- список имен развертываний в кластере;DESIRED
- отображает желаемое количество экземпляров пода (определяется при создании развертывания);CURRENT
- отображает количество экземпляров пода в настоящее время;UP-TO-DATE
- отображает количество экземпляров пода, которые были обновлены для достижения желаемого состояния;AVAILABLE
- отображает количество экземпляров пода, которые доступны пользователям;AGE
- отображает время с момента запуска развертывания.
Чтобы увидеть текущий статус (прогресс) развертывания, можно использовать команду kubectl rollout status deployment/nginx-deployment
. Вывод будет примерно таким:
1 2 3 |
Waiting <span class="hljs-keyword">for</span> rollout to finish: 2 out of 3 new replicas have been updated… deployment <span class="hljs-string">"nginx-deployment"</span> successfully rolled out |
Через несколько секунд (нужно ведь подождать, пока скачается docker-образ) еще раз проверяем состояние развертываний в кластере с помощью kubectl get deployments
:
1 2 3 |
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 18s |
Как видим, данное развертывание создало три экземпляра пода (как мы и писали в желаемом состоянии) - “под капотом” был также создан набор реплик (ReplicaSet
) - убедиться в этом можно с помощью команды kubectl get rs
:
1 2 3 |
NAME DESIRED CURRENT READY AGE nginx-deployment-2035384211 3 3 3 18s |
Имя набора реплик формируется автоматически и выглядит как [DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]
, hash-значение генерируется при создании развертывания. Узнать какие метки были автоматически добавлены каждому поду можно командой kubectl get pods --show-labels
, вывод может выглядеть так:
1 2 3 4 5 |
NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 |
Для обновления развертывания (например, изменения версии docker-образа на 1.9.1) можно воспользоваться такой командой:
1 2 3 |
kubectl <span class="hljs-built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.9.1 deployment <span class="hljs-string">"nginx-deployment"</span> image updated |
или изменить сам манифест развертывания (меняем значение .spec.template.spec.containers[0].image
):
1 2 3 |
kubectl edit deployment/nginx-deployment deployment <span class="hljs-string">"nginx-deployment"</span> edited |
или (предпочтительный вариант) - изменить файл с манифестом развертывания и применить изменения:
1 2 3 4 5 |
nano nginx-deployment.yaml <span class="hljs-comment"># вносим нужные правки и сохраняем файл</span> kubectl apply <span class="hljs-_">-f</span> nginx-deployment.yaml deployment <span class="hljs-string">"nginx-deployment"</span> configured |
Как и раньше, наблюдаем за процессом обновления и получаем интересующую нас информацию командами kubectl rollout status deployment/nginx-deployment
, kubectl get deployments
и kubectl get rs
(ниже приведен только результат последней команды):
1 2 3 4 |
NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 6s nginx-deployment-2035384211 0 0 0 36s |
Как видим, новый (ориентируемся по времени) набор реплик (ReplicaSet
) находится в желаемом состоянии, в то время как в старом наборе количество экземпляров пода равно нулю.
Детальное описание развертывания получаем командой kubectl describe deployments
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 30 Nov 2017 10:56:25 +0000 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=2 Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate M<span class="hljs-keyword">in</span>ReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.9.1 Port: 80/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m deployment-controller Scaled up replica <span class="hljs-built_in">set</span> nginx-deployment-2035384211 to 3 Normal ScalingReplicaSet 24s deployment-controller Scaled up replica <span class="hljs-built_in">set</span> nginx-deployment-1564180365 to 1 Normal ScalingReplicaSet 22s deployment-controller Scaled down replica <span class="hljs-built_in">set</span> nginx-deployment-2035384211 to 2 Normal ScalingReplicaSet 22s deployment-controller Scaled up replica <span class="hljs-built_in">set</span> nginx-deployment-1564180365 to 2 Normal ScalingReplicaSet 19s deployment-controller Scaled down replica <span class="hljs-built_in">set</span> nginx-deployment-2035384211 to 1 Normal ScalingReplicaSet 19s deployment-controller Scaled up replica <span class="hljs-built_in">set</span> nginx-deployment-1564180365 to 3 Normal ScalingReplicaSet 14s deployment-controller Scaled down replica <span class="hljs-built_in">set</span> nginx-deployment-2035384211 to 0 |
Рассмотрим пример отката (возвращения к предыдущему состоянию) развертывания (Deployment
). Допустим, при обновлении мы ошиблись и указали неверную версию docker-образа - nginx:1.91
вместо nginx:1.9.1
:
1 2 3 |
kubectl <span class="hljs-built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.91 deployment <span class="hljs-string">"nginx-deployment"</span> image updated |
Обновление застопорится (ожидаемо, ведь такого docker-образа нет):
1 2 3 |
kubectl rollout status deployments nginx-deployment Waiting <span class="hljs-keyword">for</span> rollout to finish: 2 out of 3 new replicas have been updated… |
Состояние набора реплик будет выглядеть примерно так:
1 2 3 4 5 6 |
kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 2 2 0 25s nginx-deployment-2035384211 0 0 0 36s nginx-deployment-3066724191 2 2 2 6s |
Состояние подов будет таким:
1 2 3 4 5 6 7 |
kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-70iae 1/1 Running 0 25s nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s |
Примечание. Дополнительную информацию о состоянии развертывания можно также получить используя kubectl describe deployment
, но уже и так ясно - необходим откат.
Для возврата на предыдущую (работоспособную) версию развертывания необходимо сначала проверить историю изменений (узнать номер ревизии):
1 2 3 4 5 6 7 |
kubectl rollout <span class="hljs-built_in">history</span> deployment/nginx-deployment deployments <span class="hljs-string">"nginx-deployment"</span> REVISION CHANGE-CAUSE 1 kubectl create <span class="hljs-_">-f</span> docs/user-guide/nginx-deployment.yaml --record 2 kubectl <span class="hljs-built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.9.1 3 kubectl <span class="hljs-built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.91 |
Благодаря параметру --record
мы можем увидеть изменения, которые применяли в каждой из ревизий. Узнать больше подробностей о конкретной ревизии развертывания можно указав ее номер, например так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
kubectl rollout <span class="hljs-built_in">history</span> deployment/nginx-deployment --revision=2 deployments <span class="hljs-string">"nginx-deployment"</span> revision 2 Labels: app=nginx pod-template-hash=1159050644 Annotations: kubernetes.io/change-cause=kubectl <span class="hljs-built_in">set</span> image deployment/nginx-deployment nginx=nginx:1.9.1 Containers: nginx: Image: nginx:1.9.1 Port: 80/TCP QoS Tier: cpu: BestEffort memory: BestEffort Environment Variables: <none> No volumes. |
Для отката на предыдущую ревизию достаточно выполнить такую команду:
1 2 3 |
kubectl rollout undo deployment/nginx-deployment deployment <span class="hljs-string">"nginx-deployment"</span> rolled back |
Для отката на конкретную ревизию необходимо указать ее номер в параметре --to-revision
:
1 2 3 |
kubectl rollout undo deployment/nginx-deployment --to-revision=2 deployment <span class="hljs-string">"nginx-deployment"</span> rolled back |
Для масштабирования (увеличения/уменьшения количества подов) можно использовать команду:
1 2 3 |
kubectl scale deployment nginx-deployment --replicas=10 deployment <span class="hljs-string">"nginx-deployment"</span> scaled |
хотя все же лучше вносить изменения в файл с манифестом развертывания (Deployment
) и применять их командой kubectl apply
.
К развертываниям также применимо горизонтальное масштабирование подов (HPA) - если такое включено в вашем кластере Kubernetes
- и применить его можно так:
1 2 3 |
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80 deployment <span class="hljs-string">"nginx-deployment"</span> autoscaled |
На этом все, еще больше информации можно найти в официальной документации по Kubernetes