Олег Марков
Основы Network в Kubernetes
Введение
Kubernetes — это мощная система оркестрации контейнеров, которая автоматизирует развертывание, масштабирование и управление приложениями. Одной из ключевых составляющих для эффективной работы приложений является сеть — без нее Pod-ы не смогут ни взаимодействовать между собой, ни принимать трафик извне. В этой статье я расскажу вам о базовых принципах сетевого взаимодействия в Kubernetes, обсудим, как настраивается сетевое взаимодействие между Pod-ами, как работает сервис (Service), что такое Ingress, а также взглянем на особенности сетевых плагинов (CNI). Вы увидите примеры YAML-манифестов и узнаете, как управлять сетями на практике.
Модель сетевого взаимодействия в Kubernetes
Основные принципы сети Kubernetes
Сначала давайте вкратце разберемся, как Kubernetes строит свою сеть:
- Каждый Pod имеет уникальный IP-адрес, который доступен другим Pod-ам в той же Kubernetes-кластере.
- Коммуникация между Pod-ами происходит напрямую, без NAT.
- Сеть «плоская»: Pod-ы могут общаться между собой, несмотря на то, на каких Worker-нодах они запущены.
Этот подход позволяет приложениям вести себя так, как будто они работают на одной виртуальной машине, где все процессы видят друг друга через IP-протокол.
Как Pod получает IP-адрес
Когда новый Pod запускается на одной из нод, Kubernetes выделяет ему отдельный сетевой namespace и интерфейс. За выделение IP-адреса отвечает сеть-контроллер или CNI-плагин, о которых я расскажу чуть ниже.
Смотрите, вот как выглядит состояние Pod с точки зрения сети (пример вывода команды):
kubectl get pod my-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
my-pod 1/1 Running 0 22m 10.244.1.12 node1
Под с именем my-pod
получил внутренний IP-адрес — 10.244.1.12.
Основные сетевые компоненты Kubernetes
Pod network (Сеть Pod-ов)
Это основа коммуникации между Pod-ами: они должны быть доступны по своим IP из любой точки кластера.
Service network (Сеть сервисов)
Service в Kubernetes — это абстракция, которая позволяет получить стабильную точку доступа для набора Pod-ов. Сервисы получают свои виртуальные IP-адреса (ClusterIP) и могут балансировать трафик между Pod-ами.
Cluster network (Внутрикластерная сеть)
Обеспечивает связность между Pod-ами и другими сущностями внутри кластера.
Node network (Сеть узлов)
Используется для доступа админов, взаимодействия между компонентами Kubernetes и выхода приложения в интернет.
Container Network Interface (CNI)
Для работы сетей Kubernetes пользуется расширяемой системой сетевых плагинов — CNI (Container Network Interface). Они управляют процессом выделения IP для Pod-ов, настройкой маршрутов, firewall-ов и прочих сетевых аспектов.
Популярные CNI-плагины: Flannel, Calico, Weave, Cilium.
Давайте посмотрим, как устроена базовая установка сетевого плагина (пример для Flannel):
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
Этот манифест развернёт Flannel на всех ваших нодах.
Сервисы в Kubernetes
Как Service соединяет Pod-ы
Один из центральных концептов сети в Kubernetes — объект типа Service. Когда вы создаете Service, вы указываете, какой набор Pod-ов он должен обслуживать. Для выбора Pod-ов используется selector — набор меток.
Пример Service для web-приложения:
apiVersion: v1
kind: Service
metadata:
name: my-web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80 # Порт Service
targetPort: 8080 # Порт внутри Pod-а
Пояснения:
- Service будет ждать трафик на порту 80.
- Весь приходящий на этот порт трафик будет проксироваться сервисом на порт 8080 у Pod-ов, подходящих по метке
app: web
.
Теперь ко всем этим Pod-ам можно обращаться через имя сервиса (my-web-service
) внутри кластера.
Типы Service
Существует несколько типов сервисов. Они отвечают за разные сценарии доступа к вашему приложению:
ClusterIP
- Доступен только внутри кластера.
- Это тип сервиса по умолчанию.
NodePort
- Можно обратиться к Pod через внешний IP любой ноды (на определенном порту).
- Удобно для тестирования, но не рекомендуется для продакшна.
LoadBalancer
- Позволяет получить внешний IP-адрес через облачный Load Balancer (работает в облачных провайдерах).
ExternalName
- Создаёт DNS-алиас для ресурса вне кластера (например, внешний API).
Смотрите, как можно создать сервис типа NodePort:
apiVersion: v1
kind: Service
metadata:
name: example-nodeport
spec:
type: NodePort
selector:
app: demo
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Явно задаем порт
Теперь ваше приложение внутри Pod-ов с меткой app: demo
доступно по адресу http://<NodeIP>:30080
.
Endpoints
Service поддерживает список доступных Endpoints — это список IP:port, куда он реально проксирует трафик. Kubernetes обновляет этот список автоматически в зависимости от актуального состояния Pod-ов.
Ingress и управление внешним трафиком
Что такое Ingress
Ingress — это объект, который управляет входящим HTTP/HTTPS-трафиком снаружи кластера, проксируя его к нужному сервису внутри. Ingress похож на обратный прокси с возможностями маршрутизации по домену, пути и SSL-терминации.
Пример Ingress-манифеста
Я покажу, как устроить примитивный Ingress, который направляет запросы по доменному имени к определенному сервису:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-web-service
port:
number: 80
Если при этом установлен контроллер Ingress (например, NGINX Ingress Controller), то снаружи вы сможете обращаться по адресу http://demo.example.com
— весь трафик попадет на ваш сервис my-web-service
.
Как deploy-ить Ingress Controller
Сам по себе объект Ingress не работает — нужен контроллер. Смотрите пример установки NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
После установки контроллер слушает внешний трафик и следит за изменениями Ingress-ресурса.
DNS- и сервис-дискавери в Kubernetes
Kubernetes использует собственный DNS-сервер для резольвинга сервисов и Pod-ов внутри кластера. Это позволяет Pod-ам общаться не по IP, а по именам.
Строение DNS-имени сервиса:
<service-name>.<namespace>.svc.cluster.local
Пример: my-web-service.default.svc.cluster.local
Подключение к сервису из Kubernetes-приложения (фрагмент кода на Go):
resp, err := http.Get("http://my-web-service.default.svc.cluster.local:80")
// Здесь мы обращаемся к сервису по имени, а не по IP
Всегда используйте именно DNS-имя сервиса — так ваша конфигурация будет работать даже если IP-адреса изменятся.
Network Policies — управление доступом
По умолчанию Pod-ы в Kubernetes могут свободно общаться между собой. Если нужно ограничить трафик, используйте NetworkPolicy.
Пример, как разрешить доступ к Pod-ам с label role: db
только от Pod-ов с label role: backend
:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-allow-backend
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
Комментарии:
- Данное правило разрешает входящий (
Ingress
) трафик к Pod-ам с лейбломrole: db
только от Pod-ов с лейбломrole: backend
. - Все остальные входящие подключения будут блокироваться.
Это отличный способ улучшить безопасность внутри кластера.
Практические советы по отладке сети
Проверка состояния сети и Pod-ов
Для диагностики состояния сети используйте стандартные средства kubectl. Покажу варианты:
- Получить IP-адреса всех Pod-ов:
kubectl get pods -o wide
- Проверить Endpoints для сервиса:
kubectl get endpoints my-web-service
NAME ENDPOINTS AGE
my-web-service 10.244.1.17:8080 12m
- Войти в Pod и проверить интернет/вызовы по сети:
kubectl exec -it my-pod -- /bin/sh
# ping google.com
# curl my-web-service
Diagostic tools: netshoot, busybox
Часто нужен Pod с сетевыми утилитами для диагностики. Поднять его просто:
kubectl run -it --rm --restart=Never busybox --image=busybox sh
# Внутри pod-a доступны ping, nslookup, wget и другие инструменты
Если вы хотите ещё больше утилит, используйте netshoot:
kubectl run -it --rm --restart=Never netshoot --image=nicolaka/netshoot bash
LifeCycle Pod и сетевой работы: нюансы
Что происходит с IP при перезапуске Pod
Когда Pod пересоздается, он получает новый IP-адрес. Если ваше приложение завязано на конкретный IP Pod-а — пересмотрите архитектуру в пользу общения через сервисы и DNS-имена.
Когда и зачем менять дефолтное сетевое поведение
- Строгий контроль межсервисного трафика (используйте NetworkPolicy).
- Требуется создать сегменты сети внутри одного кластера (используйте namespace и policy).
- Интеграция с внешними сервисами (см. ExternalName и пробрасывание портов).
Заключение
Вы познакомились с основными принципами сетевого взаимодействия в Kubernetes. Мы рассмотрели, как Pod-ы получают IP, как сетевые плагины обеспечивают коммуникацию между ними, что такое сервисы и какие бывают их типы, как организовать доступ снаружи с помощью Ingress и как ограничить доступ между Pod-ами с помощью NetworkPolicy. Теперь вы умеете базово ориентироваться в сетях Kubernetes, различать типы сервисов и настраивать маршрутизацию трафика внутри кластера.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Почему мой Pod не может выйти в интернет?
Проверьте, корректно ли установлен и настроен сетевой CNI-плагин. Например, для Flannel или Calico требуется, чтобы все ноды могли общаться по нужным портам (обычно UDP 8472 для Flannel). Также проверьте настройку iptables на хостах и наличие default gateway внутри Pod-а. Для отладки войдите в Pod и попробуйте пинговать 8.8.8.8 и выполнять traceroute.
Как добиться связи между Pod-ами в разных namespace?
В Kubernetes связь между Pod-ами из разных namespace разрешена по умолчанию. Просто используйте полное DNS-имя вида <service-name>.<namespace>.svc.cluster.local
. Если доступ отсутствует, проверьте правила NetworkPolicy — возможно, межнеймспейсный трафик ограничен.
Сервис типа LoadBalancer не получает внешний IP — что делать?
Сервис типа LoadBalancer работает только в облачной среде (AWS, GCP, Azure), где контроллер создает балансировщик нагрузки. Если ваш кластер «голый» (bare metal), используйте MetalLB или Ingress Controller для эмуляции внешнего балансира.
Как пробросить нестандартный порт или порт ниже 1024 на Service NodePort?
Kubernetes по умолчанию позволяет использовать для NodePort диапазон 30000–32767. Чтобы разрешить меньшие порты, измените параметр --service-node-port-range=80-32767
в kube-apiserver и kubelet. Не забудьте перезапустить соответствующие сервисы. Имейте в виду, что порты ниже 1024 могут требовать дополнительных настроек прав для доступа.
Как соединить несколько кластеров Kubernetes по сети?
Для связи Pod-ов из разных кластеров используйте специальные решения типа Submariner или Istio Multicluster, либо настраивайте VPN-туннели между кластерами. Это требует продвинутой настройки CNI и маршрутизации на уровне Data Plane — такая задача выходит за рамки базовой сетевой конфигурации Kubernetes.
Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!
Kubernetes — часть карты развития DevOps
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Kubernetes
Лучшие курсы по теме

Kubernetes и Helm
Антон Ларичев
Docker и Ansible
Антон Ларичев