Kubernetes: Pods, Services, Deployments

Pod, Service и Deployment — три основных объекта Kubernetes: Pod запускает контейнер, Deployment управляет набором Pod-ов, Service предоставляет стабильный сетевой адрес для доступа к ним.

Зачем нужно

Понимание этих трёх объектов — минимальный набор для работы с Kubernetes. Deployment гарантирует, что нужное количество Pod-ов всегда запущено и выполняет rolling update при деплое. Service обеспечивает единую точку доступа к Pod-ам, даже когда их IP-адреса меняются.

Где используется

  • Деплой любого контейнеризированного приложения в Kubernetes
  • Rolling update без даунтайма через kubectl apply
  • Внутренняя маршрутизация между микросервисами через Service

Основной контент

Pod

# pod.yaml (обычно не создаётся напрямую — используй Deployment)
apiVersion: v1
kind: Pod
metadata:
  name: my-api
  namespace: production
  labels:
    app: my-api
spec:
  containers:
    - name: api
      image: myuser/myapp:abc123
      ports:
        - containerPort: 3000
      env:
        - name: NODE_ENV
          value: production
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
      resources:
        requests:
          memory: "128Mi"
          cpu: "100m"
        limits:
          memory: "256Mi"
          cpu: "500m"

Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-api
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # +1 Pod во время обновления
      maxUnavailable: 0  # никогда не убивать Pod до появления нового
  template:
    metadata:
      labels:
        app: my-api
    spec:
      containers:
        - name: api
          image: myuser/myapp:abc123
          ports:
            - containerPort: 3000
          readinessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"

Service

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-api-svc
  namespace: production
spec:
  selector:
    app: my-api          # маршрутизирует трафик к Pod-ам с этим label
  ports:
    - protocol: TCP
      port: 80           # порт Service
      targetPort: 3000   # порт контейнера
  type: ClusterIP        # только внутри кластера
  # type: LoadBalancer   # создаёт внешний облачный балансировщик
  # type: NodePort       # доступен через IP Node

Ingress (HTTP-маршрутизация)

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-api-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.example.com
      secretName: api-tls
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-api-svc
                port:
                  number: 80

Применение манифестов

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

# Следить за rolling update
kubectl rollout status deployment/my-api -n production

# Откат
kubectl rollout undo deployment/my-api -n production

# Масштабирование
kubectl scale deployment my-api --replicas=5 -n production

Частые ошибки

  • Не указывать selector.matchLabels в Deployment — Service не найдёт Pod-ы
  • Не задавать resources.requests — Scheduler размещает Pod-ы неоптимально, OOMKill неожиданен
  • Использовать тег latest в image — нет воспроизводимости, Kubernetes не знает когда обновить Pod
  • Нет readinessProbe — трафик идёт на Pod до его готовности (502 ошибки)

Связанные темы

Ресурсы