логотип PurpleSchool
логотип PurpleSchool

Основы 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.

Стрелочка влевоИспользование Vault в KubernetesГайд по Certificate Management в KubernetesСтрелочка вправо

Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!

Kubernetes — часть карты развития DevOps

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Kubernetes

Terraform и Kubernetes инфраструктура как кодНастройка и использование Runners в KubernetesНастройка и деплой PostgreSQL в KubernetesСравнение и интеграция Openshift и KubernetesПримеры интеграции GitHub Actions и KubernetesDeploy приложений в Kubernetes - пошаговое руководство для начинающих и не толькоКак настроить CD в KubernetesИнтеграция Ansible в KubernetesИнтеграция CI/CD с Jenkins и KubernetesИнтеграция Kubernetes с GitLab - Автоматизация CI CD в облачной инфраструктуреГайд по DevOps инструментам в KubernetesОсобенности платформы Deckhouse в Kubernetes
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Kubernetes и Helm

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Микросервисы

Антон Ларичев
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий