Создание Service типа NodePort в Kubernetes
Введение

Сервис в Kubernetes — это абстракция над набором Pod’ов. Он предоставляет стабильный IP и DNS-имя, через которые клиенты обращаются к Pod’ам. Сервис маршрутизирует трафик к Pod’ам, выбранным по меткам.
Ключевые типы Service в Kubernetes:
- ClusterIP — доступен только внутри кластера.
- NodePort — открывает статический порт на каждом узле (Node) кластера и пробрасывает трафик к Pod’ам.
- LoadBalancer — создаёт внешний балансировщик у облачного провайдера и получает публичный IP.
- ExternalName — возвращает CNAME и перенаправляет на внешний DNS-имя.
Важно: NodePort удобен для простого внешнего доступа без внешнего LB, но имеет ограничения по безопасности и масштабируемости.
Предварительные требования
- Kubernetes-кластер с как минимум одним рабочим узлом.
- Установленный kubectl, настроенный на ваш кластер.
Если нужно создать кластер, воспользуйтесь инструкцией провайдера или локальными инструментами (minikube, kind, k3s). Для production обычно используют облачные решения или управляемые кластеры.
Что мы сделаем
- Создадим Deployment с nginx (3 реплики).
- Создадим Service типа NodePort, который будет направлять трафик на Pod’ы.
- Проверим назначенный NodePort и протестируем доступ.
Создаём Deployment
Создайте файл my-deployment.yml и вставьте в него определение Deployment для nginx.
vim my-deployment.ymlapiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Примените конфигурацию:
kubectl create -f my-deployment.ymlПроверьте статус:
kubectl get deployment | grep nginx
kubectl get replicaset | grep nginx
kubectl get pod | grep nginx
В выводе вы увидите 3 запущенные реплики nginx.
Создаём Service типа NodePort
Создайте файл my-service.yml с определением Service.
vim my-service.ymlapiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
externalTrafficPolicy: Local
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: NodePort
Пояснения к ключевым полям:
- type: NodePort — сервис будет доступен с каждого узла кластера по IP узла и выделенному порту.
- port — порт сервиса внутри кластера (ClusterIP).
- targetPort — порт контейнера, на который перенаправляется трафик.
- externalTrafficPolicy:
- Local — сохраняет исходный IP клиента и отправляет трафик только на местные Pod’ы на узле. Удобно для логирования источника, но может потребовать дополнительных проверок на балансировку.
- Cluster — балансирует трафик внутри кластера.
Примените Service:
kubectl create -f my-service.ymlПроверьте его наличие и детали:
kubectl get service | grep nginx
kubectl describe service nginx
В выводе будет указан NodePort, например 30747. Порт назначается из диапазона по умолчанию 30000–32767, если вы не задали nodePort вручную.
Теперь доступ к приложению возможен по адресу NodeIP:NodePort, например 106.210.138.189:30747.
Важно: если у вас несколько рабочих узлов, у каждого будет прослушиван этот NodePort. Но с externalTrafficPolicy: Local запрос попадёт только к локальным Pod’ам на том узле.
Тестирование доступности
- Найдите IP одного из узлов (NodeIP):
kubectl get nodes -o wide- Сделайте запрос напрямую снаружи (если узел доступен):
curl http://: - Если узлы недоступны извне из-за облачного firewall, откройте порт или используйте LoadBalancer.
Альтернатива локальному тесту — проброс порта через kubectl (полезно для отладки):
kubectl port-forward deployment/nginx 8080:80Затем откройте http://localhost:8080.
Когда NodePort не подходит
- Высокая нагрузка и требования к масштабированию — лучше использовать LoadBalancer плюс внешние балансировщики или Ingress.
- Ограничения безопасности — NodePort открывает порт на всех узлах, что может нарушать политику безопасности.
- Ограниченный пул портов — диапазон 30000–32767 ограничен; при большом числе сервисов нужен LoadBalancer или Ingress.
Альтернативные подходы
- LoadBalancer — если вы используете облако, это упрощает получение публичного IP и встроенную балансировку.
- Ingress — для маршрутизации HTTP/HTTPS по виртуальным хостам и более гибких правил; обычно в связке с контроллером Ingress и внешним LB.
- Service Mesh — для сложной маршрутизации, наблюдаемости и политик сервисов.
Практическая методология для быстрой настройки
- Подготовьте Deployment с нужными метками.
- Создайте сервис с selector, который точно совпадает с метками Pod’ов.
- Примените конфигурации и дождитесь, пока Pod’ы не будут в состоянии Ready.
- Получите NodePort и проверьте доступность снаружи.
- Настройте правила firewall/NSG для разрешения входящего трафика на NodePort.
- Для production рассмотрите LoadBalancer или Ingress и TLS.
Чек-лист ролей
Администратор кластера:
- Убедиться, что диапазон NodePort доступен в сети.
- Настроить firewall/SG для NodePort.
- Контролировать externalTrafficPolicy.
DevOps-инженер:
- Создать Deployment и Service YAML.
- Настроить мониторинг и readiness/liveness проверки.
- Настроить логирование исходных IP (externalTrafficPolicy: Local при необходимости).
Разработчик приложения:
- Убедиться, что контейнер слушает нужный порт.
- Добавить метки, соответствующие Service.
- Тестировать отклик приложения локально.
Критерии приёмки
- Deployment запущен и имеет требуемое количество реплик.
- Service создан и имеет type: NodePort.
- NodePort назначен в корректном диапазоне (по умолчанию 30000–32767) или задан вручную и открыт в сетевом фаерволе.
- При запросе NodeIP:NodePort возвращается корректный HTTP-ответ от приложения.
Отладка и распространённые проблемы
Нет ответа по NodeIP:NodePort:
- Проверьте, слушает ли контейнер порт targetPort.
- Убедитесь, что Pod’ы имеют метку, соответствующую selector сервиса.
- Проверьте правила сети / firewall облака.
- Проверьте, находятся ли Pod’ы в состоянии Ready.
Порт назначен, но трафик идёт не ко всем репликам:
- externalTrafficPolicy: Local направляет трафик только к локальным Pod’ам. Для глобальной балансировки используйте Cluster.
Непредсказуемая балансировка:
- NodePort сам по себе не даёт интеллектуальной маршрутизации; используйте LoadBalancer или Ingress.
Безопасность и эксплуатация
- Ограничьте доступ к NodePort на уровне сетевого экрана.
- Для публичных сервисов лучше использовать LoadBalancer с настроенным WAF и TLS.
- Логи и метрики: собирайте информацию о исходных IP при помощи externalTrafficPolicy: Local.
Примеры отказов и варианты обхода
- Если кластер находится за NAT и узлы не имеют публичных IP, NodePort не даст доступа извне. Обходы:
- Воспользоваться LoadBalancer, который назначит публичный IP.
- Использовать Ingress с контроллером, который поддерживает внешнюю точку доступа.
- Настроить VPN или bastion-хост для доступа к узлам.
Быстрый SOP для развёртывания Service NodePort
- Подготовьте Deployment YAML.
- Примените Deployment: kubectl create -f my-deployment.yml
- Убедитесь в запущенных Pod’ах: kubectl get pods
- Подготовьте Service YAML с type: NodePort.
- Примените Service: kubectl create -f my-service.yml
- Получите NodePort: kubectl get svc nginx -o yaml
- Проверьте доступность: curl http://
: - Закройте ненужные порты после тестов.
Модель принятия решений (Mermaid)
graph TD
A[Нужно ли внешнее подключение?] -->|Нет| B[ClusterIP]
A -->|Да| C[Есть облачный LB?]
C -->|Да| D[LoadBalancer]
C -->|Нет| E[Нужен простой доступ]
E --> F[NodePort]
E --> G[Ingress с внешней точкой]Краткие факты
- Диапазон NodePort по умолчанию: 30000–32767.
- externalTrafficPolicy: Local сохраняет IP клиента.
- Service использует selector с метками Pod’ов для маршрутизации.
Часто задаваемые вопросы
Что такое Service и зачем он нужен?
Service стабилизирует доступ к динамическим Pod’ам. Он скрывает детали масштабирования и замены Pod’ов за стабильным интерфейсом.
Можно ли создать сервис без YAML?
Да. Команда kubectl expose позволяет создать Service из Deployment или Pod. Пример:
kubectl expose deployment nginx --type=NodePort --name=nginxКак узнать IP и порт сервиса?
Используйте kubectl get services или kubectl describe service
Что происходит, если все Pod’ы удалены?
Service остаётся, но не будет перенаправлять трафик, пока не появятся Pod’ы с подходящими метками.
Заключение
Мы создали Deployment с nginx и Service типа NodePort. После создания сервиса вы получили NodePort, по которому приложение стало доступно извне (при условии открытого сетевого доступа). Для production-окружения рассмотрите LoadBalancer или Ingress для большей гибкости и безопасности.
Важно: NodePort удобно для тестов и простых сценариев, но у него есть ограничения по безопасности и масштабируемости.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента