← Назад к вопросам

Как обеспечить доступ к Deployment в Kubernetes

2.0 Middle🔥 121 комментариев
#Docker, Kubernetes и DevOps#REST API и микросервисы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ответ

Как обеспечить доступ к Deployment в Kubernetes

Deployment в Kubernetes — это контроллер для управления подами. Но поды имеют временные IP адреса и автоматически пересоздаются. Поэтому нужны Service и Ingress для стабильного доступа.

1. Kubernetes Service — база для доступа

Service предоставляет стабильный сетевой эндпоинт для подов.

ClusterIP (по умолчанию) — доступ только внутри кластера:

apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: api-app
  ports:
    - port: 80              # Порт на Service
      targetPort: 8080      # Порт на поде
      protocol: TCP

Использование:

# Внутри другого пода
curl http://api-service:80

# С FQDN
curl http://api-service.default.svc.cluster.local:80

NodePort — доступ с машин снаружи:

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: NodePort
  selector:
    app: api-app
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080      # Порт на каждой ноде (30000-32767)
status:
  loadBalancer: {}

Использование:

# Снаружи кластера
curl http://<node-ip>:30080

LoadBalancer — облачный балансировщик нагрузки:

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: LoadBalancer
  selector:
    app: api-app
  ports:
    - port: 80
      targetPort: 8080
  externalIPs:
    - 203.0.113.1        # Опционально явно указать

Kubernetes автоматически создаст LoadBalancer в облаке (AWS, GCP, Azure).

2. Deployment + Service (связь)

# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-app          # Ключевая метка
  template:
    metadata:
      labels:
        app: api-app        # Те же лейблы
    spec:
      containers:
      - name: api
        image: myrepo/api:v1.0
        ports:
        - containerPort: 8080
---
# Service выбирает поды по лейблам
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP
  selector:
    app: api-app            # Соответствует лейблам Deployment
  ports:
    - port: 80
      targetPort: 8080

3. Ingress — внешний доступ с HTTP/HTTPS

Ingress управляет внешним доступом, поддерживает хосты и пути.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
spec:
  ingressClassName: nginx  # Используем nginx-ingress
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

Использование:

curl http://api.example.com/

С HTTPS и сертификатом:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress-secure
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - api.example.com
    secretName: api-tls-secret   # Cert-manager создаст сертификат
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

С несколькими путями (URL routing):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-path-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 3000
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 9000

4. Полный пример: Deployment + Service + Ingress

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-app
  template:
    metadata:
      labels:
        app: spring-app
    spec:
      containers:
      - name: app
        image: myrepo/spring-app:1.0.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: spring-app-service
spec:
  type: ClusterIP
  selector:
    app: spring-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-app-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: spring-app-service
            port:
              number: 80

Деплой:

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

# Проверка
kubectl get deployment
kubectl get service
kubectl get ingress
kubectl get pods

5. Типы Service — сравнение

ТипДоступИспользование
ClusterIPТолько внутри кластераМикросервисы между собой
NodePortСнаружи через IP:порт узлаРазработка, тестирование
LoadBalancerОблачный балансировщикProduction с облаком
ExternalNameВнешний DNSДоступ к внешним сервисам

6. Service Discovery в Kubernetes

// В Java коде приложение может обращаться к другим сервисам по имени
@RestTemplate
public class UserClient {
    
    @Autowired
    private RestTemplate restTemplate;
    
    public User getUser(Long id) {
        // Kubernetes автоматически разрешает имя в IP
        String url = "http://user-service/users/" + id;
        return restTemplate.getForObject(url, User.class);
    }
}

7. Проверка доступа к Deployment

# Проверить поды
kubectl get pods
kubectl describe pod <pod-name>

# Логи пода
kubectl logs <pod-name>
kubectl logs -f <pod-name>  # Tail логи

# Получить доступ к поду напрямую (для отладки)
kubectl port-forward pod/<pod-name> 8080:8080
# Теперь доступен на localhost:8080

# Выполнить команду в поде
kubectl exec -it <pod-name> -- /bin/sh

# Проверить Service
kubectl get svc
kubectl describe svc spring-app-service

# Проверить Ingress
kubectl get ingress
kubectl describe ingress spring-app-ingress

8. Best Practices

  1. Используй Service Discovery — приложения должны обращаться по имени сервиса, не по IP
  2. Используй Ingress для внешнего доступа (более гибко чем NodePort)
  3. Добавляй livenessProbe и readinessProbe — Kubernetes будет перезагружать упавшие поды
  4. Задавай ресурсы (requests/limits) — для корректного планирования подов
  5. Используй LoadBalancer в облаке — для production с автоматическим масштабированием
  6. Управляй трафиком через Ingress — вместо многих Service/NodePort

Кратко: Deployment создаёт поды, Service предоставляет сетевой доступ, Ingress управляет внешним доступом.

Как обеспечить доступ к Deployment в Kubernetes | PrepBro