Как опубликовать приложение (Services/Ingress)
Публикация приложений внутри кластера и наружу.
Публикация приложения в Kubernetes обычно строится как цепочка нагрузка → Service → Ingress. Нагрузка запускает поды приложения, Service даёт им стабильную точку доступа, а Ingress открывает HTTP/HTTPS-доступ извне кластера.
Если приложение ещё не развёрнуто, сначала создайте Deployment, StatefulSet или другой тип нагрузки по инструкции Как задеплоить приложение.
Как выбрать способ доступа
Service
| Способ | Когда использовать |
|---|---|
| ClusterIP | Доступ нужен только внутри кластера. Это базовый вариант для связи приложений между собой. |
| NodePort | Нужен внешний доступ через статический порт на каждом узле кластера. Подходит для тестовых и инфраструктурных сценариев. |
| LoadBalancer | Нужен внешний IP через поддерживаемый провайдер инфраструктуры или балансировщик. |
| ExternalName | Нужно создать DNS-алиас Service на внешнее имя, например foo.bar.example.com, без проксирования трафика. |
Ingress
| Способ | Когда использовать |
|---|---|
| Ingress | Нужна публикация HTTP/HTTPS по доменному имени, пути, TLS и правилам маршрутизации к Service. |
| Gateway API | Нужна современная переносимая маршрутизация через Gateway API; разделение ролей между инфраструктурой и приложением. См. Маршруты Gateway API. |
В модели Kubernetes каждый Pod получает собственный IP-адрес, но Pod может быть пересоздан. Service скрывает эту изменчивость за стабильным IP-адресом или DNS-именем, а Ingress маршрутизирует внешний HTTP/HTTPS-трафик к Service.
Что подготовить перед публикацией
Перед созданием Service и Ingress проверьте:
- Нагрузка приложения создана и поды переходят в состояние
Running/Ready. - У подов есть стабильные labels, по которым Service сможет выбрать backend-поды, например
app: my-app. - Известен порт контейнера, на котором приложение принимает трафик, например
8080. - У пользователя есть права на создание
Service,Ingressи при необходимостиSecretв нужном неймспейсе. - Для внешнего доступа настроен Ingress Controller и доступ к его IP-адресу, VIP, NodePort или балансировщику. Подробнее о потоке трафика см. Архитектурные схемы сетей кластера.
- Для доступа по доменному имени настроена DNS-запись. До настройки DNS можно проверить Ingress запросом с заголовком
Host. - Для HTTPS подготовлен TLS Secret типа
kubernetes.io/tlsс ключамиtls.crtиtls.key.
Создавать Service и Ingress можно из раздела Сети в неймспейсе или с дашборда неймспейса, где отображается связь между нагрузками, сервисами и ингрессами. Подробнее см. Обзор дашборда неймспейса.
Шаг 1. Создайте Service
Service определяет логический набор подов и политику доступа к ним. Для приложения с labels app: my-app Service должен использовать такой же selector, иначе трафик не попадёт в нужные поды.
- Откройте кластер и выберите неймспейс, в котором развёрнуто приложение.
- Перейдите в Сети → Services.
- Нажмите + Добавить Service.
- Заполните имя Service, например
my-app-service. - При необходимости добавьте лейблы и аннотации.
- В сведениях о развёртывании выберите тип Service:
ClusterIP,NodePort,LoadBalancerилиExternalName. - Оставьте параметр игнорирования статуса Pod в значении по умолчанию, если нет отдельного требования менять его.
- Добавьте порт и заполните:
- Имя порта — например
http; - AppProtocol — при необходимости;
- NodePort — для Service типа
NodePort, если требуется конкретный порт; - Port — порт Service, например
80; - TargetPort — порт контейнера, например
8080; - Protocol —
TCP,UDPилиSCTP.
- Имя порта — например
- При необходимости задайте внешние IP-адреса.
- Добавьте labels селектора подов, например
app: my-app. - Нажмите Сохранить.
Скриншот: страница Service

После создания Service можно открыть из списка. На странице Service доступны просмотр и редактирование манифеста на вкладке Манифест, изменение типа Service, внешних IP-адресов, портов, селектора подов, лейблов и аннотаций.
Подготовьте манифест и загрузите его через Импорт манифестов или примените через kubectl.
apiVersion: v1
kind: Service
metadata:
name: my-app-service
namespace: my-namespace
spec:
type: ClusterIP
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
Для внешнего доступа через Service измените spec.type на NodePort или LoadBalancer. Для DNS-алиаса на внешний ресурс используйте ExternalName.
apiVersion: v1
kind: Service
metadata:
name: external-api
namespace: my-namespace
spec:
type: ExternalName
externalName: api.example.com
Если Deployment уже создан и его поды имеют label app=my-app, Service можно создать командой:
kubectl expose deployment my-app \
--name my-app-service \
--port 80 \
--target-port 8080 \
-n my-namespace
Или примените YAML-файл:
kubectl apply -f service.yaml
Проверьте Service и backend-поды:
kubectl get svc my-app-service -n my-namespace
kubectl describe svc my-app-service -n my-namespace
kubectl get endpointslices -n my-namespace -l kubernetes.io/service-name=my-app-service
Шаг 2. Настройте TLS Secret
Для HTTPS в Ingress нужен Secret, содержащий закрытый ключ и сертификат TLS. В Secret должны быть ключи tls.crt и tls.key, а сертификат должен соответствовать доменному имени, по которому публикуется приложение.
Ingress использует TLS на порту 443 и завершает TLS-соединение на точке входа. Трафик от Ingress к Service и подам после этого передаётся как внутренний трафик кластера. Если в секции tls указано несколько хостов, они обрабатываются на этом же порту с помощью SNI. Хосты в tls.hosts должны явно соответствовать хостам в rules.
- В неймспейсе приложения перейдите в Хранилище → Secrets.
- Нажмите + Добавить Secret.
- Укажите имя, например
my-app-tls. - Выберите тип
kubernetes.io/tls. - Добавьте файл сертификата и файл закрытого ключа для публикуемого домена.
- Нажмите Сохранить.
Если сертификаты выпускаются через cert-manager, настройку ClusterIssuer или Issuer выполняют отдельно. Подробнее см. ClusterIssuer и Issuer.
apiVersion: v1
kind: Secret
metadata:
name: my-app-tls
namespace: my-namespace
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded-cert>
tls.key: <base64-encoded-key>
kubectl create secret tls my-app-tls \
--cert=./tls.crt \
--key=./tls.key \
-n my-namespace
Проверьте, что Secret создан в том же неймспейсе, где будет создан Ingress:
kubectl get secret my-app-tls -n my-namespace
Шаг 3. Создайте Ingress
Ingress управляет внешним доступом к сервисам в кластере. Он задаёт HTTP/HTTPS-маршруты извне кластера к Service внутри кластера, может использовать балансировку нагрузки, TLS и виртуальный хостинг на основе имени.
- Перейдите в Сети → Ingresses.
- Нажмите + Добавить Ingress.
- Укажите имя Ingress, например
my-app-ingress. - При необходимости добавьте лейблы и аннотации.
- В спецификации объекта заполните:
- IngressClassName — выберите нужный
IngressClassиз списка или оставьте пустым, если класс указывать не требуется; - Ingress Service Backend — выберите Service
my-app-service, имя портаhttpили номер порта80.
- IngressClassName — выберите нужный
- Добавьте правило:
- Host — доменное имя, например
my-app.example.com; - HTTPIngressPath — путь
/; - Path type —
Prefix,ExactилиImplementationSpecific; - Ingress Backend Service — Service
my-app-serviceи порт80.
- Host — доменное имя, например
- Для HTTPS добавьте IngressTLS:
- Secret name — выберите созданный TLS Secret, например
my-app-tls; - Hosts — укажите один или несколько хостов. Значения должны соответствовать хостам в правилах Ingress.
- Secret name — выберите созданный TLS Secret, например
- Нажмите Сохранить.
Скриншот: страница Ingress

На странице Ingress можно перейти к вкладке Манифест, изменить backend, правила и IngressTLS, а также обновить лейблы и аннотации.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
namespace: my-namespace
spec:
tls:
- hosts:
- my-app.example.com
secretName: my-app-tls
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
Если в вашем кластере требуется конкретный IngressClass, добавьте поле spec.ingressClassName.
spec:
ingressClassName: nginx
В платформе «Штурвал» в качестве Ingress Controller используется NGINX. Подробнее о базовой настройке Ingress см. в документации NGINX Ingress Controller.
Создайте объект, проставив свои значения параметров:
kubectl create ingress my-app-ingress \
--namespace=my-namespace \
--class=nginx \
--rule="my-app.example.com/*=my-app-service:80,tls=my-app-tls"
Проверьте Ingress:
kubectl get ingress my-app-ingress -n my-namespace
kubectl describe ingress my-app-ingress -n my-namespace
Если DNS ещё не настроен, проверьте маршрут по IP-адресу Ingress Controller или балансировщика с заголовком Host:
curl -H "Host: my-app.example.com" http://<INGRESS_IP>/
Полный пример публикации приложения
В примере Deployment создаёт поды с label app: my-app, Service выбирает эти поды через selector, а Ingress направляет внешний трафик по хосту my-app.example.com на Service my-app-service.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: my-namespace
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: registry.example.com/my-app:v1.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-service
namespace: my-namespace
spec:
type: ClusterIP
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
namespace: my-namespace
spec:
tls:
- hosts:
- my-app.example.com
secretName: my-app-tls
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
Применение и базовая проверка:
kubectl apply -f publish-my-app.yaml
kubectl get deploy,po,svc,ingress -n my-namespace
kubectl describe svc my-app-service -n my-namespace
kubectl describe ingress my-app-ingress -n my-namespace
Проверка доступа внутри кластера:
kubectl run curl-test --rm -it \
--image=curlimages/curl \
--restart=Never \
-n my-namespace \
-- curl http://my-app-service.my-namespace.svc.cluster.local
Проверка внешнего доступа:
# До настройки DNS
curl -H "Host: my-app.example.com" http://<INGRESS_IP>/
# После настройки DNS и TLS
curl https://my-app.example.com
Проверка и диагностика
Service
Если приложение недоступно через Service, проверьте:
- Service создан в том же неймспейсе, где находятся поды приложения.
spec.selectorService совпадает с labels подов.portService иtargetPortконтейнера соответствуют реальным портам приложения.- У Service появились EndpointSlice для backend-подов. Бэкенд под должны быть в состоянии Running и Ready=true, в противном случае эндпоинт не попадет в Service.
- Внутри кластера используется корректное DNS-имя:
<service-name>.<namespace>.svc.cluster.local. В том же неймспейсе можно использовать короткое имя Service.
kubectl get svc -n my-namespace
kubectl describe svc my-app-service -n my-namespace
kubectl get pods -n my-namespace --show-labels
kubectl get endpointslices -n my-namespace -l kubernetes.io/service-name=my-app-service
Ingress
Если Ingress не открывает приложение, проверьте:
- Ingress Controller установлен и его поды работают.
- У Service есть backend-поды.
host,path,pathType, backend Service и порт в Ingress указаны корректно.- DNS-запись указывает на IP-адрес, VIP, NodePort или балансировщик Ingress Controller.
- Для HTTPS Secret существует в том же неймспейсе, содержит
tls.crtиtls.key, а сертификат выпущен на нужный FQDN. - В событиях Ingress и подов нет ошибок.
kubectl get ingress -n my-namespace
kubectl describe ingress my-app-ingress -n my-namespace
kubectl get events -n my-namespace --sort-by='.lastTimestamp'
Подробные команды для проверки Ingress Controller, Service и логов контроллера см. в разделе Траблшутинг сетей. Частые проблемы приложений описаны в Траблшутинге нагрузок.
Сетевые политики
Если в кластере включены сетевые политики, они могут блокировать трафик от Ingress Controller к backend-подам. Разрешите входящий трафик от Ingress Controller к приложению. Пример политики см. в разделе Разрешить входящий трафик от Ingress Controller.
Рекомендации
- Для внутренних зависимостей между приложениями используйте
ClusterIPи DNS-имя Service. - Для production-публикации HTTP/HTTPS-приложений используйте
Ingressс доменным именем и TLS. LoadBalancerиспользуйте, когда нужен прямой внешний IP без HTTP/HTTPS-маршрутизации на уровне Ingress.NodePortприменяйте для тестирования или специальных инфраструктурных сценариев.- Не храните приватные ключи и сертификаты в открытых манифестах. Используйте Kubernetes Secrets.
Дополнительные материалы
- Как задеплоить приложение — создание и проверка workload перед публикацией.
- Обзор дашборда неймспейса — где посмотреть связи между нагрузками, Services и Ingresses.
- Импорт манифестов — загрузка YAML без
kubectl. - ClusterIssuer и Issuer — выпуск сертификатов через cert-manager.
- Как подключить приватный registry — подготовка доступа к образам приложения.
- Траблшутинг сетей — проверка Ingress, Service и сетевого доступа.