core code helper

Kubernetes з нуля: Pod, Deployment, Service і як трафік доходить до застосунку

Базові об'єкти Kubernetes на одному прикладі: від маніфесту Deployment до доступу ззовні через Gateway API — з поясненням, навіщо кожен шар.

0 імпортували Імпортувати собі

Kubernetes лякає кількістю абстракцій, але для запуску типового вебсервісу потрібні лише кілька. Розберемо їх на прикладі API, який має працювати у трьох копіях і бути доступним за доменом.

Декларативна модель

У Kubernetes ви не кажете «запусти контейнер». Ви описуєте бажаний стан — «хочу три копії образу api:1.4.2» — а контролери кластера постійно приводять реальний стан до бажаного. Впав вузол — поди перестворяться на іншому. Видалили под руками — з'явиться новий.

Pod — найменша одиниця

Pod — один або кілька контейнерів зі спільною мережею (одна IP-адреса) і томами. Напряму поди майже ніколи не створюють: ними керує Deployment.

Deployment — скільки копій і як оновлювати

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  labels: { app: api }
spec:
  replicas: 3
  selector:
    matchLabels: { app: api }
  strategy:
    type: RollingUpdate
    rollingUpdate: { maxUnavailable: 0, maxSurge: 1 }
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
        - name: api
          image: ghcr.io/acme/api:1.4.2
          ports:
            - containerPort: 8000
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef: { name: api-secrets, key: database-url }

Що тут відбувається:

  • replicas: 3 — три поди;
  • selector + labels — Deployment знаходить «свої» поди за мітками;
  • RollingUpdate з maxUnavailable: 0 — під час оновлення спочатку піднімається новий под, і лише потім гасне старий. Користувачі не бачать простою.
kubectl apply -f deployment.yaml
kubectl rollout status deployment/api
kubectl get pods -l app=api -o wide
kubectl rollout undo deployment/api      # відкотитися на попередню версію

Service — стабільна адреса для подів

Поди смертні: їхні IP змінюються після кожного перезапуску. Service дає стабільне ім'я і балансує трафік між усіма подами з потрібними мітками.

apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector: { app: api }
  ports:
    - port: 80          # порт сервісу
      targetPort: 8000  # порт контейнера

Тепер усередині кластера будь-який под звертається до http://api (або api.<namespace>.svc.cluster.local).

Тип Service Доступ
ClusterIP (за замовчуванням) Лише всередині кластера
NodePort Порт на кожному вузлі (30000–32767)
LoadBalancer Зовнішній балансувальник хмари

Доступ ззовні: Ingress і Gateway API

Тримати LoadBalancer на кожен сервіс дорого. Зазвичай є одна точка входу, яка маршрутизує HTTP-запити за доменом і шляхом.

Історично для цього використовували Ingress з контролером ingress-nginx. Але проєкт ingress-nginx у березні 2026 року завершив підтримку, і Kubernetes рекомендує переходити на Gateway API — сучасніший і виразніший стандарт.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api
spec:
  parentRefs:
    - name: public-gateway          # Gateway створює команда платформи
      namespace: infra
  hostnames: ["api.example.com"]
  rules:
    - matches:
        - path: { type: PathPrefix, value: / }
      backendRefs:
        - name: api
          port: 80
Примітка

Gateway API розділяє відповідальність: команда платформи керує Gateway (сертифікати, адреси, який контролер), а команди застосунків — своїми HTTPRoute. З Ingress усе це змішувалось в анотаціях конкретного контролера.

ConfigMap і Secret

Конфігурацію тримають окремо від образу:

kubectl create configmap api-config --from-literal=LOG_LEVEL=info
kubectl create secret generic api-secrets --from-literal=database-url='postgres://...'
Увага

Secret у Kubernetes за замовчуванням лише закодовано в base64, а не зашифровано. Увімкніть шифрування etcd, обмежте доступ через RBAC і не комітьте секрети в Git — для GitOps використовуйте Sealed Secrets, SOPS або External Secrets Operator.

Namespace

Простори імен ділять кластер на логічні частини: dev, staging, команди чи продукти. RBAC, квоти й мережеві політики зазвичай налаштовують саме на рівні namespace.

Шпаргалка kubectl

kubectl get pods,svc,deploy -n production
kubectl describe pod api-7d9f8-x2kq       # події: чому под не стартує
kubectl logs -f deploy/api                 # логи
kubectl logs api-7d9f8-x2kq --previous     # логи попереднього (упалого) контейнера
kubectl exec -it deploy/api -- sh          # shell у контейнері
kubectl port-forward svc/api 8080:80       # доступ до сервісу з ноутбука
kubectl get events --sort-by=.lastTimestamp
Чому застосунки в кластері звертаються до Service, а не напряму до IP подів?

IP подів змінюються при кожному перезапуску, масштабуванні чи оновленні. Service має стабільне ім'я та IP і сам розподіляє запити між актуальними подами з потрібними мітками.

Збережіть статтю собі

Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.

Увійти через Google Інші способи входу