Как организовать доступ к контейнеру извне в Kubernetes?

«Как организовать доступ к контейнеру извне в Kubernetes?» — вопрос из категории Kubernetes, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Kubernetes доступ к контейнерам извне организуется через несколько механизмов, которые я выбираю в зависимости от требований к доступности, безопасности и нагрузке.

1. Service с типом NodePort Использую для разработки, тестирования или когда нет облачного балансировщика нагрузки.

apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
    - name: http
      port: 80           # Порт сервиса внутри кластера
      targetPort: 8080   # Порт контейнера
      nodePort: 30080    # Порт на нодах (30000-32767)
      protocol: TCP

Доступ: http://<node-ip>:30080

2. Service с типом LoadBalancer Использую в облачных средах (AWS, GCP, Azure) для автоматического создания внешнего балансировщика нагрузки.

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080

3. Ingress Controller Для HTTP/HTTPS трафика с маршрутизацией по хостам и путям — это мой основной выбор для production.

# Ingress для маршрутизации
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80

# TLS termination
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls-secret

4. Port Forwarding для отладки Для локальной отладки без настройки внешнего доступа:

# Доступ к поду
kubectl port-forward pod/my-pod 8080:80

# Доступ к сервису
kubectl port-forward service/my-service 8080:80

# Доступ к конкретному deployment
kubectl port-forward deployment/my-deployment 8080:80

5. ExternalName Service Для проксирования к внешним сервисам:

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: api.external-provider.com

Мой типичный production-стек:

  • Ingress Controller: NGINX Ingress или Traefik
  • Service Mesh: Istio для сложной маршрутизации и безопасности
  • Load Balancer: Cloud Provider Load Balancer + ExternalDNS для автоматического управления DNS
  • WAF: Cloudflare или AWS WAF перед ingress

Пример полной конфигурации:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: app.company.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-service
            port:
              number: 80