Kubernetes для новичков: просто о сложном
Kubernetes — это как операционная система для серверов, на которых работают ваши приложения. Только не для одного сервера, а для целого зоопарка.
- запускали сервер на
python manage.py runserver
, - писали
docker run
, - переносили проекты с одной машины на другую...
...то Kubernetes создан, чтобы всё это делать автоматически, масштабируемо и без боли.
❓ Что такое Kubernetes?
Kubernetes (k8s) — это платформа с открытым исходным кодом для управления контейнерами, которая:
- запускает приложения в контейнерах (чаще всего — Docker),
- распределяет их по нескольким серверам (нодам),
- следит, чтобы всё работало и перезапускало, если что-то падает,
- масштабирует приложения при росте нагрузки.
📦 Kubernetes не запускает сами приложения — он управляет контейнерами, в которых они работают.
🧠 Ключевые понятия (и как их понять)
🔹 Cluster (кластер)
Это вся ваша "система" — набор серверов, объединённых для запуска контейнеров.
🔹 Node (нода)
Один сервер в кластере. Может быть физическим или виртуальным.
Бывает: Master (Control Plane) — управляет кластером. Worker — запускает приложения.
🔹 Pod (под)
Минимальная "единица" в Kubernetes. Это один или несколько контейнеров, объединённых вместе (чаще — один). K8s не запускает контейнеры напрямую — он всегда запускает Pod'ы.
🔹 Deployment
Шаблон, который описывает, что запускать, сколько копий, как обновлять.
Kubernetes следит за тем, чтобы всё соответствовало этому описанию.
🔹 Service
Постоянный адрес (IP и порт) для доступа к Pod'ам.
Без сервиса — у пода нет «имени», к которому можно подключиться.
🏁 Как всё это работает вместе?
- Вы создали образ своего приложения (
Dockerfile
). - Написали Deployment манифест, сказав: "Запусти 3 копии этого контейнера".
- Kubernetes сам выберет ноды, на которых запустить эти Pod'ы.
- Если один под "умрёт" — он его перезапустит.
- Вы создали Service — и теперь у приложения есть стабильный адрес.
- Нагрузку можно распределить, масштабировать, обновлять без даунтайма.
📋 Пример: минимальный Deployment
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 2 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: app image: myuser/myapp:latest ports: - containerPort: 8000
Этот YAML-файл говорит:
🛠 «Запусти 2 экземпляра контейнера myuser/myapp
, слушай порт 8000».
🔌 Как снаружи подключаться?
apiVersion: v1 kind: Service metadata: name: my-app-service spec: selector: app: my-app ports: - port: 80 targetPort: 8000 type: LoadBalancer
Kubernetes сам раздаст запросы между подами, обеспечив балансировку нагрузки.
🔄 Обновление без остановки (rolling update)
Kubernetes умеет мягко обновлять приложение:
Так вы не теряете доступ даже во время деплоя.
🐾 Простой образ кота
Kubernetes — это как кот-менеджер: вы даёте ему инструкцию "надо запустить 3 будки с едой", а он сам решает, где и как. Если одна миска опрокинулась — он ставит новую. Он не кормит сам, но организует кормёжку на уровне продакшена.
✅ Почему это круто?
- Масштабирование в одну строку (
replicas: 10
) - Само-восстановление: упал под — запустит новый
- Удобные обновления и откаты
- Разделение ролей (Dev, Ops)
- Кроссплатформенность (AWS, GCP, bare metal, локально)
📝 Манифесты Kubernetes — как "написать" кластеру, что делать
В Kubernetes вы не запускаете команды вручную, а описываете желаемое состояние системы в виде YAML-файлов. Это и есть манифесты.
🧑💻 «Хочу 3 копии этого приложения, с таким образом, доступом и хранилищем».
Kubernetes отвечает:
🤖 «Ок. Я всё сделаю и буду следить, чтобы так всегда и было».
🧠 Что такое манифест?
Манифест в Kubernetes — это YAML-файл, который описывает ресурс, который вы хотите создать:
Pod, Deployment, Service, ConfigMap, Ingress, Volume и т.д.
- описывает структуру и параметры объекта,
- передаётся в кластер с помощью
kubectl apply
, - позволяет декларативно управлять инфраструктурой.
🔧 Общая структура манифеста
apiVersion: apps/v1 # версия API kind: Deployment # тип ресурса metadata: # метаданные name: my-app spec: # спецификация (что должно быть) ...
💡 Всегда состоит из четырёх основных блоков:
Версия API, к которой относится ресурс (v1
, apps/v1
)
Тип ресурса (Pod
, Service
, Deployment
, и т.д.)
Конкретные настройки ресурса (что запускать, как, где)
🛠 Как применить манифест?
kubectl apply -f deployment.yaml
kubectl get all
🧾 Организация манифестов
- Разделять манифесты по ресурсам:
pod.yaml
,service.yaml
,ingress.yaml
- Хранить их в Git (инфраструктура как код)
- Использовать шаблонизаторы (например, Helm или Kustomize)
- Использовать
kubectl kustomize
,kustomization.yaml
илиhelm values.yaml
📌 Полезные команды
kubectl apply -f file.yaml # применить манифест kubectl delete -f file.yaml # удалить объект kubectl get -f file.yaml # посмотреть объект kubectl explain pod # объяснение структуры манифеста kubectl diff -f file.yaml # что изменится при применении
🐾 Кошачий пример
Манифест — это как инструкция по уходу за котом:
сколько мисок, где он спит, какие игрушки и сколько внимания.
Kubernetes — это заботливый автоматизированный котоняня, который всегда следит, чтобы всё соответствовало плану.
✅ Вывод
Манифесты — это язык общения с Kubernetes.
Они:
- определяют структуру приложения,
- делают поведение системы предсказуемым,
- позволяют версионировать инфраструктуру, как код.
💡 Овладев манифестами, вы перестаёте "жать кнопки" и начинаете управлять системой как архитектор.
🛠 kubectl
— главный инструмент общения с Kubernetes
kubectl
(произносится "куб-кей-тл" или просто "куб-контрол") — это клиентская утилита, с помощью которой вы управляете кластером Kubernetes.
Она позволяет:
- создавать и изменять ресурсы,
- просматривать состояние приложений,
- масштабировать, обновлять, удалять,
- получать логи и доступ внутрь контейнеров.
🐱 Образно: Kubernetes — это целый кошачий город, а kubectl
— это ваш пульт управления: кормить, запускать, лечить, переселять и перезапускать 🐾
🧠 Общая структура команды
kubectl [глагол] [ресурс] [имя] [флаги]
kubectl get pods kubectl describe pod my-pod kubectl delete deployment my-app kubectl apply -f app.yaml
📚 Команда kubectl explain
Хочешь узнать, какие поля есть у ресурса?
kubectl explain deployment kubectl explain deployment.spec.template
kubectl
— это основной инструмент для взаимодействия с Kubernetes.
Он:
- даёт полный контроль над кластером,
- позволяет работать как с манифестами, так и напрямую,
- делает управление инфраструктурой быстрым, удобным и скриптуемым.
💡 Если вы изучаете Kubernetes — изучайте kubectl
первым делом. Он поможет разобраться во всём остальном.
Далее разберем основные виды ресурсов в Kubernetes.
⚙️ Deployment в Kubernetes — сердце управляемого запуска
🧩 Что такое Deployment?
Deployment — это ресурс в Kubernetes, который:
- описывает, как должно работать ваше приложение (какой контейнер, сколько копий и т.д.),
- обеспечивает стабильность (следит, чтобы нужное количество копий всегда было в работе),
- позволяет обновлять приложение без простоя (rolling updates),
- и даже откатывать неудачные обновления.
📌 В реальности: вы не "запускаете" приложение вручную, вы говорите Kubernetes:
"Я хочу, чтобы это приложение всегда работало в таком виде".
А он сам следит за этим.
🛠 Что включает в себя Deployment?
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: app image: myuser/myapp:1.0 ports: - containerPort: 8000
replicas
: сколько копий приложения нужно.selector
: как находить связанные Pod'ы.template
: шаблон Pod'а, который Kubernetes будет создавать.image
: контейнер, который запускать (из Docker Hub, GitLab, ECR и т.д.).
🔄 Rolling Updates — обновление без даунтайма
Допустим, вы поменяли image: myuser/myapp:1.0
на image: myuser/myapp:2.0
.
- Запускает новую версию по одной.
- Ждёт, пока под станет готовым.
- Удаляет один старый.
- Повторяет, пока все поды не станут новыми.
Вы ничего не выключаете — обновление "на лету" ✈️
🔙 Rollback — откат на предыдущую версию
Что, если что-то пошло не так? Kubernetes хранит историю деплойментов и позволяет откатиться одной командой:
kubectl rollout undo deployment my-app
🐱 Это как кнопка "отмена" в редакторе — но для всего приложения.
📈 Масштабирование
Нужно больше мощности? Меняем количество реплик:
kubectl scale deployment my-app --replicas=10
replicas: 10
Kubernetes создаст недостающие поды автоматически.
🐾 Кошачий пример
Deployment — это как список требований к коту в приюте: "Хочу 3 кота, серых, с кормушкой и будкой". Kubernetes как добросовестный волонтёр — найдёт, поселит, проверит, и если один сбежал — сразу привезёт нового.
✅ Вывод
Deployment
— это основной способ управлять жизненным циклом приложений в Kubernetes.
С его помощью вы:
- запускаете приложения,
- обновляете их безопасно,
- масштабируете нагрузку,
- и получаете автоматическое восстановление в случае сбоев.
Это ваш контракт с кластером: вы пишете, как должно быть, Kubernetes делает, чтобы оно так и было.
🌐 Service в Kubernetes — как поды находят друг друга
В Kubernetes вы запускаете поды. Они живут, работают... но как к ним обращаться?
Ведь каждый под — это временная сущность. Он может "умереть", перезапуститься, получить новый IP.
Вот здесь и появляется герой — Service.
🐱 Пример: Под — это кот. Сегодня он спит на диване, завтра — на окне.
А Service — это табличка «здесь живёт Кот Барсик», по которой его всегда можно найти, где бы он ни спал 🐾
❓ Зачем нужен Service?
- Обеспечить постоянный доступ к подам, даже если они перезапускаются.
- Распределять трафик между несколькими репликами.
- Позволить другим подам внутри кластера (или снаружи) обращаться к вашему приложению.
🛠 Виды Service
Kubernetes предлагает несколько типов Service — каждый для своей задачи:
ClusterIP
Доступ внутри кластера (по умолчанию)
NodePort
Открывает порт на всех нодах (для отладки/доступа)
LoadBalancer
Использует внешний балансировщик (в облаках)
ExternalName
Прокси на внешний DNS-адрес (например, внешние API)
🔧 Пример Service с ClusterIP
apiVersion: v1 kind: Service metadata: name: my-app-service spec: selector: app: my-app ports: - port: 80 targetPort: 8000
selector
— связывает Service с подами (app: my-app
),port
— внешний порт, по которому обращаются к сервису,targetPort
— внутренний порт, который слушает контейнер.
📌 Теперь другие поды в кластере могут обращаться к вашему приложению через http://my-app-service:80
🚪 NodePort — доступ снаружи
spec: type: NodePort ports: - port: 80 targetPort: 8000 nodePort: 30080
Теперь можно обратиться к приложению через IP любой ноды:
http://<node-ip>:30080
⚠️ Не рекомендуется для продакшена — только для тестов и отладки.
☁️ LoadBalancer — для облаков
Если вы используете Kubernetes в облаке (GCP, AWS, Azure), то можно указать:
spec: type: LoadBalancer
И Kubernetes создаст внешний балансировщик, направляющий трафик на ваши поды.
🔁 Как всё работает внутри
Service создаёт виртуальный IP (ClusterIP), который:
- получает DNS-имя,
- проксирует трафик на нужные поды (по
selector
), - умеет распределять трафик между репликами (round-robin).
🔍 Как посмотреть и протестировать
kubectl get service kubectl describe service my-app-service
Внутри кластера можно сделать:
curl http://my-app-service
И убедиться, что всё работает!
🐾 Кошачий факт:
Service — это как GPS-ошейник у кота:
коты меняются, бегают и прячутся, но вы всегда можете найти «котика по имени Барсик», и Kubernetes приведёт вас к одному из них.
✅ Вывод
Service
— один из самых важных компонентов Kubernetes. Он:
- даёт стабильный способ обратиться к подам,
- обеспечивает балансировку,
- делает возможным общение между сервисами,
- открывает доступ наружу (если нужно).
В связке с Deployment
и Pod
это — основа архитектуры любого K8s-приложения.
📦 Pod в Kubernetes — минимальный, но мощный
Если вы только начинаете работать с Kubernetes, слово "Pod" может звучать загадочно. Но на самом деле — это самая простая единица выполнения в кластере.
Под — это обёртка над контейнером, которая знает, как его запустить, где он живёт, и что ему нужно.
🐱 Образно: Контейнер — это кот. А Pod — это его коробка: в ней уютно, в ней миска и подстилка, и она знает, где кот должен спать.
❓ Что такое Pod?
Pod — это объект в Kubernetes, который содержит:
Почти всегда в поде — один контейнер. Под с несколькими контейнерами — редкость (и продвинутая тема).
🔍 Почему Pod, а не сразу контейнер?
Потому что Kubernetes не работает напрямую с контейнерами (например, Docker), а всегда управляет именно Pod’ами.
- добавлять общие volume,
- прокидывать переменные окружения,
- управлять сетью и доступами,
- наблюдать за состоянием.
🧠 Что есть у Pod'а?
- IP-адрес — свой собственный внутри кластера.
- Общий namespace — контейнеры в поде видят друг друга через
localhost
. - Volume’ы — хранилище, которое можно разделить.
- Метаданные — лейблы, аннотации, имя и т.д.
🛠 Пример Pod-манифеста (YAML)
apiVersion: v1 kind: Pod metadata: name: my-simple-pod spec: containers: - name: my-container image: python:3.10 command: ["python", "-m", "http.server", "8000"] ports: - containerPort: 8000
📌 Этот pod запускает python -m http.server
внутри контейнера и слушает порт 8000.
🧪 Команды работы с Pod
kubectl get pods # список подов kubectl describe pod my-pod # подробная информация kubectl logs my-pod # логи контейнера в поде kubectl exec -it my-pod -- bash # зайти внутрь (если есть bash)
🔁 Что происходит, если под "умирает"?
- Если вы запустили под напрямую (
kind: Pod
), и он завершился — всё, он "умер". - Но если вы используете Deployment, ReplicaSet, или Job — Kubernetes сам пересоздаст его.
❗ Под — одноразовый. Его можно пересоздать, но сам он не восстанавливается.
🧱 Множественные контейнеры в поде
Такое бывает редко, но возможно. Например, если нужен sidecar-контейнер для логов или прокси:
spec: containers: - name: app image: myapp - name: logger image: fluentd
Контейнеры внутри одного пода разделяют IP и volume, но не обязаны быть связаны логически.
🐾 Кошачий пример
Контейнер — это кот. Под — это коробка, в которой кот живёт: с подстилкой, едой, названием и GPS. Контейнер можно вынуть, но под — это его дом.
✅ Вывод
Pod
— это основа всех приложений в Kubernetes:
- это то, что реально запускается,
- оборачивает контейнеры,
- даёт им сеть, окружение и хранилище,
- управляется через более высокоуровневые абстракции (
Deployment
,Job
,DaemonSet
и т.д.).
💡 Вы почти никогда не создаёте поды напрямую в реальной жизни — но понимание, как они работают, критично важно.
🌐 Ingress в Kubernetes — входная дверь в ваш кластер
Ваше приложение уже запущено в Kubernetes. Оно работает, его поды живы, сервисы раздают трафик.
Но тут встаёт вопрос:
"А как вообще попасть на мой сайт по адресу вроде https://myapp.com
?"
Вот тут и появляется Ingress — контроллер, который управляет входящим HTTP/HTTPS-трафиком и направляет его на нужные сервисы.
❓ Что такое Ingress?
Ingress — это объект в Kubernetes, который:
- принимает входящие HTTP(S)-запросы,
- сопоставляет их с доменами, путями и сервисами внутри кластера,
- маршрутизирует трафик на соответствующие backend-приложения.
🐱 Аналогия: Ingress — это кот-привратник: он сидит у двери с табличкой и говорит: «Ты идёшь на/api
— тебе туда → сервис backend. А ты просишь/
? Иди во frontend».
🧠 Как работает Ingress?
Ingress состоит из двух компонентов:
- Ingress ресурс — YAML-описание правил маршрутизации.
- Ingress контроллер — программа, которая эти правила исполняет (чаще всего это NGINX Ingress Controller).
⚠️ Важно: Ingress не работает сам по себе. Нужен установленный контроллер, который будет его обрабатывать.
📦 Пример простого Ingress манифеста
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: myapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 80
- При обращении к
http://myapp.example.com
трафик пойдёт вmy-app-service
на порт 80. Ingress
свяжет внешний адрес с внутренним сервисом.
🔐 HTTPS и TLS
Ingress умеет работать с HTTPS:
spec: tls: - hosts: - myapp.example.com secretName: tls-secret
Секрет (tls-secret
) должен содержать сертификат и ключ.
Можно использовать cert-manager для автоматического получения TLS от Let’s Encrypt!
🛠 Как установить Ingress-контроллер?
Пример с NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml
После этого вы сможете использовать Ingress
-ресурсы, и трафик будет маршрутизироваться.
kubectl get ingress kubectl describe ingress my-app-ingress kubectl logs -n ingress-nginx <ingress-controller-pod>
✅ Вывод
Ingress — ключевой компонент для продакшен-приложений в Kubernetes. Он:
- обеспечивает доступ к приложениям по HTTP/HTTPS,
- маршрутизирует трафик на нужные сервисы по правилам,
- поддерживает TLS (HTTPS),
- делает ваши сервисы доступными извне, с красивыми доменами и маршрутизацией.
💡 Если Service
— это "внутренний адрес", то Ingress
— это "внешняя входная дверь" в ваш кластер.
🧠 Часто задаваемые вопросы
Q: Что происходит, если под упал?
A: Kubernetes автоматически запустит новый — он следит за тем, чтобы количество реплик всегда совпадало с тем, что вы указали.
Q: Что если кластер перезагрузился?
A: Deployment «вспомнит» всё, что нужно — и поднимет приложение в нужном количестве.
Q: Зачем нужен Deployment, если есть Pod?
A: Pod — одноразовая сущность. Deployment — это контроллер, который следит, чтобы подов нужного вида всегда было нужное количество.