Компьютерные сети
Сети в Kubernetes
В Docker микросервисы находят друг друга по имени. Но что если pods на разных машинах? Что если нужен load balancing? Что если нужно ограничить кто с кем может общаться? Kubernetes networking решает эти проблемы для production масштаба.
- **Spotify** запускает тысячи pods. Без плоской сети и service discovery это был бы хаос IP адресов
- **Netflix** использует Cilium для security policies и observability - видят весь трафик между микросервисами
- **Ingress controller** экономит деньги: один LB вместо сотни. При 100 сервисах это существенно
Предварительные знания
Цели урока
- Понимать плоскую сеть pods: каждый pod имеет cluster-unique IP, no NAT между pods
- Различать ClusterIP, NodePort, LoadBalancer, ExternalName и когда какой Service использовать
- Объяснить kube-proxy modes (iptables vs IPVS) и почему IPVS лучше при тысячах сервисов
- Прорисовать путь пакета: client → Ingress → Service → Endpoint → pod (через CNI: Calico/Cilium/Flannel)
- Применить NetworkPolicy для изоляции namespace и понять что без CNI с поддержкой policy они noop
Pod Networking Model
**Pod Networking** - фундамент K8s сети. Правила: 1) Каждый pod получает уникальный IP. 2) Все pods могут общаться друг с другом без NAT. 3) Агенты на node (kubelet) могут общаться с pods на этой node. Flat network - все в одной L3 сети.
**CNI (Container Network Interface)** - стандарт плагинов для pod networking. Calico, Flannel, Cilium, Weave - реализации. Выбор CNI определяет как именно pods получают IP и маршрутизируются между nodes.
Почему контейнеры в одном pod делят IP адрес?
ClusterIP Service
**ClusterIP** - виртуальный IP для группы pods. Pod IP меняется при рестарте. Service IP стабилен. kube-proxy на каждой node программирует iptables/IPVS для маршрутизации на живые pods. Load balancing встроен.
**Endpoints** - список IP:port живых pods под Service. kube-proxy watch'ит endpoints и обновляет iptables при изменениях. Pod умер → endpoint удалён → трафик не идёт на мёртвый pod.
Где 'живёт' ClusterIP адрес?
NodePort и LoadBalancer
**NodePort** - открывает порт на каждой node (30000-32767). Трафик на NodeIP:NodePort → Service → Pods. **LoadBalancer** - создаёт облачный LB (AWS ELB, GCP GLB), который направляет на NodePorts. Это путь трафика извне в кластер.
**externalTrafficPolicy: Local** - трафик идёт только на pods на той же node, куда пришёл. Сохраняет client IP (no SNAT). Но если на node нет pods - health check fails, LB не шлёт трафик.
Почему LoadBalancer service дорогой в облаке?
Ingress Controller
**Ingress** - L7 reverse proxy для HTTP(S) трафика. Один LoadBalancer → много сервисов. Routing по host/path: api.example.com → api-svc, example.com/blog → blog-svc. TLS termination, rate limiting, auth - всё здесь.
**Ingress Controller** - pod с nginx/traefik/envoy, который читает Ingress ресурсы и конфигурирует reverse proxy. Это не часть K8s core - нужно установить отдельно (nginx-ingress, traefik, istio-ingress).
Чем Ingress отличается от LoadBalancer Service?
CNI Plugins
**CNI (Container Network Interface)** - плагины для pod networking. Calico, Flannel, Cilium, Weave - разные реализации одного стандарта. Выбор CNI влияет на: производительность, security features (NetworkPolicy), overlay vs direct routing.
**NetworkPolicy** - firewall для pods. Без policy - all-allow. С policy - default deny, explicit allow. Требует CNI с поддержкой (Calico, Cilium). Flannel не поддерживает - нужен дополнительный controller.
Kubernetes networking работает из коробки без дополнительных компонентов
K8s требует CNI plugin для pod networking - это обязательный компонент
Kubernetes определяет модель (flat network, pod IP), но не реализацию. CNI plugin (Calico, Flannel, Cilium) обязателен. Без него pods не получат IP и не смогут общаться
Почему Cilium использует eBPF вместо iptables?
Итоги
- **Pod Network:** плоская сеть, каждый pod имеет уникальный IP, все pods видят друг друга без NAT
- **Service (ClusterIP):** стабильный виртуальный IP, load balancing на pods, DNS discovery
- **NodePort/LoadBalancer:** внешний доступ. NodePort - порт на всех nodes. LoadBalancer - cloud LB
- **Ingress:** L7 routing (host/path), TLS termination, один LB на много сервисов
- **CNI Plugins:** реализация pod networking (Calico, Flannel, Cilium). NetworkPolicy требует поддержки CNI
Связанные темы
K8s networking строится на базовых концепциях:
- Docker Networking — Pod networking использует те же примитивы: namespaces, veth, bridges
- Service Mesh — Istio/Linkerd добавляют L7 features поверх K8s networking
- Load Balancing — kube-proxy реализует L4 load balancing, Ingress - L7
Вопросы для размышления
- Когда выбрать Calico вместо Flannel? Когда Cilium?
- Почему default NetworkPolicy - allow all? Не опасно ли это?
- Как отладить 'connection refused' между двумя pods в разных namespaces?