Урок 03 · Kubernetes на практике
Pod и Deployment
Что-то не запустилось или осталось непонятным? Задайте вопрос в комментариях к разбору этого урока в канале — разберёмся вместе.
У вас уже есть образ hello-fastapi:0.1 из урока 1 и живой кластер из урока 2. Пора соединить их вместе — но не командой docker run, а декларативно, как это делает Kubernetes. Для этого понадобятся два новых объекта: Pod, самая маленькая единица запуска, и Deployment, который этими Pod'ами управляет и не даёт им бесследно исчезать.
Pod — не то же самое, что контейнер
Pod — минимальная единица, которую вообще можно запустить в Kubernetes. Формально он может объединять несколько контейнеров с общей сетью и диском, но на практике в 90% случаев внутри Pod'а — один контейнер. Тогда зачем вообще эта обёртка, если можно было просто запускать контейнеры?
- Pod эфемерен по своей природе. Kubernetes не «чинит» упавший Pod — он его выбрасывает и создаёт новый, с новым именем и новым IP. Это осознанный контракт, а не баг.
- Голый Pod, созданный вручную, никто не пересоздаст. Уроните узел, на котором он жил, — и Pod просто исчезнет вместе с ним. Никто не заметит и не восстановит.
- Именно поэтому Pod'ы почти никогда не создают напрямую — их создаёт объект уровнем выше, который следит, чтобы нужное количество Pod'ов существовало всегда.
Deployment и ReplicaSet: кто на самом деле следит за Pod'ами
Deployment — это декларация желаемого состояния: «я хочу, чтобы работало N копий вот такого контейнера». Сам Deployment Pod'ами не занимается — он создаёт под собой ReplicaSet, а уже ReplicaSet непрерывно сверяет факт с желаемым числом и досоздаёт Pod'ы, если их стало меньше.
Deployment добавляет поверх ReplicaSet ещё одну важную вещь — управляемые обновления: когда вы меняете образ в манифесте, Deployment создаёт новый ReplicaSet и постепенно переключает трафик на него, не роняя сервис целиком. Это тема отдельного урока про rollout, но само разделение обязанностей стоит запомнить сейчас.
Практика: задеплойте свой FastAPI-образ
Понадобится образ hello-fastapi:0.1, собранный в уроке 1, и кластер minikube из урока 2.
-
Проверьте, что образ действительно есть локально:
Если пусто — вернитесь в папку сdocker images | grep hello-fastapiDockerfileиз урока 1 и соберите его:docker build -t hello-fastapi:0.1 . -
minikube по умолчанию не видит образы вашего локального Docker — у него свой собственный. Загрузите образ внутрь кластера явно:
Это разовая операция для каждой новой версии образа — реальный registry (Docker Hub и подобные) появится в курсе позже и снимет это неудобство.minikube image load hello-fastapi:0.1 -
Создайте файл
deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: hello-fastapi spec: replicas: 2 selector: matchLabels: app: hello-fastapi template: metadata: labels: app: hello-fastapi spec: containers: - name: hello-fastapi image: hello-fastapi:0.1 ports: - containerPort: 8000selector.matchLabelsиtemplate.metadata.labelsдолжны совпадать буквально — этой парой ярлыков ReplicaSet находит «свои» Pod'ы среди всех остальных в кластере. -
Примените манифест:
kubectl apply -f deployment.yaml -
Проверьте, что получилось на каждом уровне схемы выше:
Вkubectl get deployments kubectl get podsSTATUSу Pod'ов должно бытьRunning, а вREADYу Deployment —2/2. -
Пробросьте порт одного из Pod'ов на свою машину и откройте знакомую страницу:
Откройте localhost:8000/docs — тот же интерфейс, что в уроке 1, но теперь за ним стоит кластер, а не одиночныйkubectl port-forward deployment/hello-fastapi 8000:8000docker run. Остановите проброс сочетанием Ctrl+C, когда закончите.
kubectl get pods, скопируйте имя любого Pod'а и удалите его:
kubectl delete pod <имя-pod>
Сразу выполните kubectl get pods ещё раз — вы увидите, что удалённый Pod пропал, но тут же появился новый с другим именем, а общее число снова стало равно 2. Это и есть работа ReplicaSet из схемы выше: он не спрашивает, почему Pod исчез, — просто восстанавливает заявленное число.
replicas: 1. Он почти ничего не стоит по ресурсам, зато при падении узла или самого Pod'а кластер восстановит его автоматически. Голый Pod в такой ситуации просто исчезнет навсегда.
Проверьте себя
Вы вручную удалили один из двух Pod'ов, созданных Deployment'ом. Что произойдёт дальше?
Напишите команду, которая применит манифест deployment.yaml к кластеру:
Напишите команду, которая покажет список Pod'ов и их статус: