Введение

Pod запускает контейнеры, но сам по себе Pod — это не самый распространенный способ запуска приложений в Kubernetes. Deployment описывает желаемое состояние приложения и создает ReplicaSet, который, в свою очередь, создает и поддерживает работу Pods.

В этой лабораторной работе вы создадите свой первый Deployment, дождетесь его готовности, изучите созданные им Deployment, ReplicaSet и Pods, а затем увидите, как Deployment восстанавливает Pods после их удаления. Это станет фундаментом для дальнейших тем CKAD, таких как масштабирование, последовательные обновления (rolling updates), откат изменений (rollback) и предоставление доступа к приложениям.

Подготовка пространства имен для Deployment

На этом этапе вы подготовите чистое пространство имен (namespace) для практики с Deployment и сделаете его пространством имен по умолчанию для ваших команд.

Начните работу в /home/labex/project. В этой лабораторной работе вам не потребуется писать манифесты, но использование единой рабочей директории поможет поддерживать порядок в курсе.

mkdir -p /home/labex/project
cd /home/labex/project

Убедитесь, что API-сервер Kubernetes доступен. Если виртуальная машина только что запустилась и эта команда выдает ошибку, подождите несколько секунд и повторите попытку, пока узел не перейдет в состояние Ready.

kubectl get nodes --request-timeout=5s

Ожидаемый вывод:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Для того чтобы Pods перешли в состояние готовности, им необходим сетевой плагин кластера. Дождитесь запуска Pod'а Calico, прежде чем создавать рабочие нагрузки приложения.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Ожидаемый вывод:

pod/calico-node-... condition met

Создайте пространство имен с именем ckad-prep-deployments:

kubectl create namespace ckad-prep-deployments

Команда должна подтвердить создание:

namespace/ckad-prep-deployments created

Установите это пространство имен в качестве текущего контекста:

kubectl config set-context --current --namespace=ckad-prep-deployments

Проверьте текущее пространство имен:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Ожидаемый вывод:

ckad-prep-deployments

Создание Deployment

На этом этапе вы создадите Deployment с именем web-demo с двумя репликами.

Команда kubectl create deployment дает указание Kubernetes создать объект Deployment. Опция --image задает образ контейнера в шаблоне Pod'а, а --replicas=2 предписывает Deployment поддерживать работу двух соответствующих Pods.

kubectl create deployment web-demo --image=registry.k8s.io/pause:3.10.1 --replicas=2

Ожидаемый вывод:

deployment.apps/web-demo created

Дождитесь завершения развертывания (rollout) Deployment. Для нового Deployment статус развертывания означает, что Kubernetes создал ReplicaSet и запрошенные Pods стали доступны.

kubectl rollout status deployment/web-demo --timeout=90s

В процессе вывода могут появляться сообщения об ожидании, пока Pods становятся доступными. В конце должно быть:

deployment "web-demo" successfully rolled out

Теперь изучите сводную информацию о Deployment:

kubectl get deployment web-demo

Ожидаемый вывод:

NAME       READY   UP-TO-DATE   AVAILABLE   AGE
web-demo   2/2     2            2           ...

Изучение ReplicaSet и Pods

На этом этапе вы изучите объекты, созданные под управлением Deployment.

Deployment не запускает контейнеры напрямую. Он создает ReplicaSet, а ReplicaSet создает Pods. Селектор Deployment и метки (labels) в шаблоне Pod'а связывают эти объекты вместе.

Сначала изучите метку селектора и метку шаблона в Deployment. JSONPath выведет только нужные поля, что позволит сфокусироваться на важном.

kubectl get deployment web-demo -o 'jsonpath={.spec.selector.matchLabels.app}{" "}{.spec.template.metadata.labels.app}{"\n"}'

Ожидаемый вывод:

web-demo web-demo

Первое значение — это метка селектора Deployment. Второе значение — это метка, присвоенная Pods из шаблона. Они совпадают, поэтому Deployment может управлять этими Pods.

Выведите список ReplicaSet, созданных этим Deployment:

kubectl get replicasets -l app=web-demo

Ожидаемый вывод:

NAME                  DESIRED   CURRENT   READY   AGE
web-demo-...          2         2         2       ...

Теперь выведите список Pods, выбранных по той же метке:

kubectl get pods -l app=web-demo --show-labels

Ожидаемый вывод включает два работающих Pod'а:

NAME                        READY   STATUS    RESTARTS   AGE   LABELS
web-demo-...                1/1     Running   0          ...   app=web-demo,pod-template-hash=...
web-demo-...                1/1     Running   0          ...   app=web-demo,pod-template-hash=...

Наконец, отобразите тип владельца (owner kind) для каждого Pod'а. Каждый Pod принадлежит ReplicaSet, а не напрямую Deployment.

kubectl get pods -l app=web-demo -o 'custom-columns=NAME:.metadata.name,OWNER:.metadata.ownerReferences[0].kind,PHASE:.status.phase'

Ожидаемый вывод:

NAME                        OWNER        PHASE
web-demo-...                ReplicaSet   Running
web-demo-...                ReplicaSet   Running

Наблюдение за восстановлением желаемого состояния

На этом этапе вы удалите текущие Pods и увидите, как Deployment восстанавливает желаемое состояние.

В этом заключается ключевое различие между одиночным Pod'ом и Deployment. Если вы удалите обычные Pods, они исчезнут навсегда. Если вы удалите Pods, управляемые Deployment, Deployment заметит, что фактическое состояние больше не соответствует желаемому, и создаст новые экземпляры на замену.

Удалите Pods, выбранные по метке app=web-demo. Опция --wait=false позволяет вернуть управление сразу после отправки запроса на удаление, чтобы вы могли наблюдать за процессом восстановления, не дожидаясь исчезновения старых Pods.

kubectl delete pods -l app=web-demo --wait=false

Ожидаемый вывод:

pod "web-demo-..." deleted from ckad-prep-deployments namespace
pod "web-demo-..." deleted from ckad-prep-deployments namespace

Дождитесь, пока Deployment снова станет доступным:

kubectl wait --for=condition=Available deployment/web-demo --timeout=90s

Ожидаемый вывод:

deployment.apps/web-demo condition met

Снова выведите список Pods:

kubectl get pods -l app=web-demo

Ожидаемый вывод включает два работающих Pod'а. Их имена могут отличаться, так как ReplicaSet создал новые экземпляры.

NAME                        READY   STATUS    RESTARTS   AGE
web-demo-...                1/1     Running   0          ...
web-demo-...                1/1     Running   0          ...

Еще раз проверьте сводную информацию о Deployment:

kubectl get deployment web-demo

Ожидаемый вывод:

NAME       READY   UP-TO-DATE   AVAILABLE   AGE
web-demo   2/2     2            2           ...

Резюме

Вы создали Deployment, дождались его развертывания, изучили его селектор и метки шаблона Pod'а, нашли созданные им ReplicaSet и Pods, а также пронаблюдали восстановление желаемого состояния после удаления Pods. Эти знания подготовят вас к следующим лабораторным работам по Deployment, где вы будете изменять количество реплик, обновлять приложения и управлять поведением развертывания.