Service и Ingress в Kubernetes 2026: Практическое руководство по настройке внутреннего и внешнего доступа | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Service и Ingress в Kubernetes 2026: Практическое руководство по настройке внутреннего и внешнего доступа

26 мая 2026 9 мин. чтения
Содержание статьи

Настройка сетевого доступа к приложениям в Kubernetes - одна из первых и ключевых задач для DevOps инженеров и системных администраторов. В этой статье вы получите проверенные, актуальные для 2026 года инструкции по конфигурации основных типов Service и Ingress. Мы разберем готовые YAML-манифесты для ClusterIP, NodePort и LoadBalancer, детально рассмотрим установку и настройку nginx-ingress контроллера с TLS-шифрованием, а также покажем, как избежать типичных ошибок, которые приводят к часам отладки.

Service в Kubernetes: фундамент внутренней коммуникации Pod'ов

Service в Kubernetes - это абстракция, которая обеспечивает стабильную сетевую точку доступа к группе динамически меняющихся Pod'ов. Представьте его как постоянный номер телефона для постоянно меняющейся команды. Внутри кластера механизм работает через kube-proxy, который отслеживает Pod'ы через их метки (labels) и создает список Endpoints для каждого Service. Основная задача - выбрать правильный тип Service для конкретного сценария.

ClusterIP: стандартный способ внутренней связи

ClusterIP - это тип Service по умолчанию. Он создает внутренний IP-адрес, доступный только внутри кластера. Это оптимальный выбор для сервисов, которые не требуют внешнего доступа: внутренние API, базы данных, микросервисы бэкенда.

Другие Pod'ы могут обратиться к этому сервису по его DNS имени: <service-name>.<namespace>.svc.cluster.local. В пределах одного namespace достаточно использовать просто имя сервиса.

Вот пример манифеста Deployment и связанного с ним Service типа ClusterIP:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
      - name: api
        image: mycompany/backend-api:latest
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: backend-api-service
spec:
  type: ClusterIP
  selector:
    app: backend-api # Этот selector должен точно совпадать с labels Pod'ов из Deployment
  ports:
  - port: 80         # Порт, на котором Service будет доступен внутри кластера
    targetPort: 8080 # Порт, на который трафик будет направлен в Pod'ах

После применения этих манифестов (kubectl apply -f) вы можете проверить доступность сервиса из временного Pod:

kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never --command -- curl http://backend-api-service.default.svc.cluster.local

NodePort и LoadBalancer: мост во внешний мир

Когда приложение нужно сделать доступным извне кластера, используют NodePort или LoadBalancer.

NodePort открывает статический порт (в диапазоне 30000-32767) на каждом узле кластера. Трафик, поступающий на этот порт любого узла, перенаправляется к Service, а затем к Pod'ам. Это простое решение для быстрого тестирования или для инфраструктуры без внешнего балансировщика нагрузки.

apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080 # Можно указать конкретный порт (опционально)

Плюсы NodePort: простота и универсальность, работает в любой среде. Минусы: необходимо знать IP-адрес конкретного узла, управление портами вручную, потенциальные риски безопасности при открытии портов на узлах.

LoadBalancer - это тип Service, который взаимодействует с внешним балансировщиком нагрузки, предоставляемым облачным провайдером (AWS, GCP, Azure) или решениями для bare-metal, например MetalLB. При создании такого Service провайдер автоматически выделяет внешний IP-адрес и настраивает балансировщик.

apiVersion: v1
kind: Service
metadata:
  name: web-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 8080

Для специфичных настроек провайдера используются аннотации. Например, для AWS можно указать тип балансировщика: service.beta.kubernetes.io/aws-load-balancer-type: nlb. Важно помнить о стоимости облачных LoadBalancer и использовать их только для production-сервисов.

Для организации сложной маршрутизации HTTP/HTTPS трафика по доменным именам NodePort и LoadBalancer недостаточно. Здесь необходим Ingress.

Ingress и nginx-ingress: интеллектуальная маршрутизация HTTP/HTTPS трафика

Ingress - это объект Kubernetes, описывающий правила маршрутизации внешнего HTTP и HTTPS трафика к сервисам внутри кластера. Сам Ingress не выполняет эти правила. Для этого нужен Ingress Controller - специальное приложение, которое отслеживает объекты Ingress и реализует их. Самый популярный контроллер - nginx-ingress, основанный на Nginx.

Установка и базовая проверка nginx-ingress контроллера

Наиболее удобный способ установки nginx-ingress в 2026 году - использование Helm. Актуальный репозиторий и chart можно найти в документации проекта.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace

После установки проверьте состояние Pod'ов контроллера:

kubectl get pods -n ingress-nginx

Все Pod'ы должны быть в состоянии Running. Также проверьте созданные Service:

kubectl get svc -n ingress-nginx

Вы увидите Service типа LoadBalancer (или NodePort, если в кластере нет поддержки LoadBalancer), который принимает внешний трафик и направляет его контроллеру.

Создание правил маршрутизации: от простого к сложному

После установки контроллера можно создавать правила Ingress. Базовый пример маршрутизации по хосту (host):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-host-ingress
spec:
  rules:
  - host: "myapp.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: web-service # Имя существующего Service в кластере
            port:
              number: 80      # Порт этого Service

Пример маршрутизации по пути (path) для разных частей приложения:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
spec:
  rules:
  - host: "myapp.com"
    http:
      paths:
      - pathType: Prefix
        path: "/api"
        backend:
          service:
            name: backend-service
            port:
              number: 8080
      - pathType: Prefix
        path: "/admin"
        backend:
          service:
            name: admin-service
            port:
              number: (8080)

Для корректной работы SPA или некоторых API часто требуется аннотация nginx.ingress.kubernetes.io/rewrite-target. Она указывает контроллеру, как преобразовать исходный путь перед отправкой в бэкенд.

Настройка TLS/HTTPS: подключаем SSL-сертификаты

Организация HTTPS в Kubernetes начинается с создания Secret типа tls, который хранит сертификат и приватный ключ.

kubectl create secret tls myapp-tls-secret --cert=path/to/cert.crt --key=path/to/key.key

Критически важно: никогда не коммитить файлы сертификатов и ключей в git. Secret должен создаваться непосредственно в кластере.

После этого Secret ссылается в манифесте Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  tls:
  - hosts:
    - "myapp.com"
    secretName: myapp-tls-secret
  rules:
  - host: "myapp.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: web-service
            port:
              number: 80

Для автоматического перенаправления всех HTTP запросов на HTTPS добавьте аннотацию:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"

Это обеспечивает безопасное соединение для всех пользователей.

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

Готовые примеры манифестов для типовых сценариев

Ниже приведены полные, самодостаточные примеры конфигураций для двух распространенных сценариев. Все манифесты используют актуальные для 2026 года apiVersion.

Сценарий 1: Внутренний микросервис (Backend API + ClusterIP)

Этот набор манифестов разворачивает внутренний веб-сервис, доступный только другим Pod'ам в кластере.

# Deployment для внутреннего API
apiVersion: apps/v1
kind: Deployment
metadata:
  name: internal-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: internal-api
  template:
    metadata:
      labels:
        app: internal-api
    spec:
      containers:
      - name: api-container
        image: nginx:alpine # Пример с простым веб-сервером
        ports:
        - containerPort: 80
---
# Service типа ClusterIP для внутреннего доступа
apiVersion: v1
kind: Service
metadata:
  name: internal-api-service
spec:
  type: ClusterIP
  selector:
    app: internal-api
  ports:
  - port: 8080
    targetPort: 80

Примените манифесты: kubectl apply -f internal-api.yaml. Проверить работу можно с помощью команды kubectl port-forward service/internal-api-service 8080:8080 и обращения к localhost:8080, или из временного Pod внутри кластера.

Сценарий 2: Публичное веб-приложение с HTTPS (Deployment + Service + Ingress)

Это комплексный пример для публичного сайта или приложения, доступного по HTTPS.

# 1. Deployment приложения
apiVersion: apps/v1
kind: Deployment
metadata:
  name: public-web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: public-web-app
  template:
    metadata:
      labels:
        app: public-web-app
    spec:
      containers:
      - name: web
        image: mycompany/web-app:latest
        ports:
        - containerPort: 3000
---
# 2. Service (используется ClusterIP, так как внешний трафик идет через Ingress)
apiVersion: v1
kind: Service
metadata:
  name: public-web-service
spec:
  type: ClusterIP
  selector:
    app: public-web-app
  ports:
  - port: 80
    targetPort: 3000
---
# 3. Ingress с правилом для домена и TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: public-web-ingress
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - "example.com"
    secretName: example-tls-secret # Предварительно созданный Secret
  rules:
  - host: "example.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: public-web-service
            port:
              number: 80

Последовательность действий: создать TLS Secret, затем выполнить kubectl apply -f для всех трех манифестов. После этого приложение будет доступно по https://example.com.

Для управления конфигурацией и секретами приложений в Kubernetes рекомендуем ознакомиться с практическим руководством по ConfigMap и Secret, которое детально разбирает безопасное хранение настроек.

Типичные ошибки конфигурации и их решение

Знание распространенных ошибок и их симптомов экономит часы на отладке.

Ошибки селекторов (selector) и меток (labels)

Симптом: команда kubectl describe service <name> показывает Endpoints: <none>. Service не может найти Pod'ы для маршрутизации трафика.

Причина: метки (labels) Pod'ов, созданных Deployment или другими контроллерами, не совпадают с селектором (selector) в манифесте Service.

Решение: Проверить labels Pod'ов: kubectl get pods --show-labels. Затем сравнить их с полем spec.selector в манифесте Service. Убедиться, что ключи и значения совпадают. Исправить манифест и переприменить его.

Проблемы с портами (ports) и целевыми портами (targetPort)

Симптом: Service создан, Endpoints есть, но запросы не проходят или приложение не отвечает.

Причина: путаница в настройке портов. Поле port определяет порт, на котором Service доступен внутри кластера. Поле targetPort указывает порт, который открыт внутри контейнера Pod'а. Для NodePort также существует поле nodePort - порт на узле кластера.

Решение: Проверить, какой порт действительно открыт в контейнере (поле containerPort в Deployment). Убедиться, что targetPort в Service совпадает с этим значением. Для отладки можно временно использовать kubectl port-forward для прямого подключения к Pod'у и проверки его работоспособности.

Проблемы с Ingress: 404 ошибки и неправильная маршрутизация

Симптом: Ingress Controller работает, но запросы возвращают 404 или направляются не на нужный сервис.

Причины и решения:

  • Аннотация rewrite-target: убедитесь, что она правильно настроена для вашего бэкенда, особенно если используются сложные пути.
  • Backend в правиле Ingress: имя Service и порт (spec.rules.http.paths.backend.service.name и port.number) должны точно совпадать с существующим Service в кластере.
  • Логи контроллера: просмотрите логи Ingress Controller для анализа маршрутизации: kubectl logs -n ingress-nginx <pod-name>.
  • TLS Secret: если используется HTTPS, убедитесь, что Secret существует в namespace Ingress и содержит валидные сертификат и ключ.

Для предотвращения подобных ошибок при внедрении новых практик полезно использовать подходы из практического справочника по DevSecOps, который систематизирует процессы интеграции безопасности.

Полезные аннотации nginx-ingress для гибкой настройки

Аннотации позволяют тонко настроить поведение nginx-ingress контроллера без изменения его исходного кода. Это "удаленный пульт управления" для встроенного Nginx.

Управление сессиями и балансировкой

Для приложений, требующих закрепления сессии пользователя за конкретным Pod'ом (sticky sessions), используйте аннотацию:

nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

Это обеспечивает балансировку нагрузки с учетом сессии.

Ограничение скорости (Rate Limiting) и размеров запросов

Для защиты бэкенда от чрезмерной нагрузки или DDoS-атак:

  • nginx.ingress.kubernetes.io/limit-connections: ограничивает количество одновременных соединений с одного IP.
  • nginx.ingress.kubernetes.io/limit-rps: ограничивает количество запросов в секунду с одного IP.
  • nginx.ingress.kubernetes.io/proxy-body-size: ограничивает максимальный размер тела запроса (например, "8m" для 8 мегабайт).

Настройка CORS и редиректов

Для разрешения кросс-доменных запросов (CORS):

nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"

Для организации редиректов, например, при изменении структуры URL:

nginx.ingress.kubernetes.io/permanent-redirect: "https://new.example.com$request_uri"

Использование этих аннотации позволяет реализовать сложную логику маршрутизации без написания собственного контроллера. Для задач, связанных с географическим ограничением трафика, также можно рассмотреть специализированные методы, описанные в руководстве по геофильтрации трафика в Kubernetes.

Инструменты автоматизации и готовые конфигурации для комплексного управления инфраструктурой можно найти в сборнике практических руководств по DevOps и Linux.

Для автоматизации работы с API различных моделей ИИ, что может быть полезно при создании инструментов мониторинга или анализа логов, можно использовать универсальные сервисы, например AiTunnel, который предоставляет единый интерфейс для более 200 моделей нейросетей.

Поделиться:
Сохранить гайд? В закладки браузера