Сетевые плагины (CNI)
| Полное название | Container Network Interface |
|---|---|
| Появление | 2015 (CoreOS), проект CNCF с 2017 |
| Тип | спецификация + библиотека + плагины |
| Конфигурация | /etc/cni/net.d/ |
| Плагины | /opt/cni/bin/ |
| Популярные реализации | Cilium, Calico, Flannel, Weave Net (архив), Antrea |
| Связанное | NetworkPolicy, kube-proxy, eBPF |
CNI (Container Network Interface) — открытая спецификация, описывающая, как среда выполнения контейнеров подключает контейнер к сети: создаёт сетевой интерфейс, выдаёт IP-адрес, настраивает маршруты и затем освобождает всё это при удалении. Сам Kubernetes сеть подов не реализует — он вызывает CNI-плагин, выбранный при установке кластера. От плагина зависят производительность сети, поддержка сетевых политик, шифрование трафика между узлами и наблюдаемость.
Сетевая модель Kubernetes
Kubernetes требует от сети трёх свойств:[2]
- каждый Pod получает собственный IP-адрес;
- поды на любых узлах общаются друг с другом напрямую, без NAT;
- агенты на узле (kubelet) видят все поды этого узла.
Как именно это обеспечить — задача плагина. Адреса подов выделяются из отдельного диапазона (например, 10.244.0.0/16, см. IP-адрес и подсети (CIDR)), обычно каждому узлу достаётся своя подсеть.
Как работает CNI
Спецификация очень проста: плагин — исполняемый файл в /opt/cni/bin/, который среда выполнения (containerd, CRI-O) вызывает с командой ADD, DEL или CHECK в переменной окружения и JSON-конфигурацией из /etc/cni/net.d/ на стандартном вводе.[1] В ответ плагин возвращает назначенный адрес. Плагины можно выстраивать в цепочку: один создаёт интерфейс, другой выделяет адрес (IPAM), третий настраивает ограничение полосы.
Внутри типичная схема такова: для пода создаётся пара виртуальных интерфейсов veth — один конец в сетевом пространстве имён пода (см. Namespaces и cgroups), другой на узле. Дальше пакеты между узлами передаются одним из способов:
| Способ | Как | Плюсы и минусы |
|---|---|---|
| Оверлей (VXLAN, Geneve) | пакеты подов упаковываются в UDP между узлами | работает в любой сети; накладные расходы и меньший MTU |
| Прямая маршрутизация (BGP) | маршруты к подсетям подов анонсируются в сеть | без инкапсуляции, быстро; нужна поддержка сети |
| Нативная сеть облака | поды получают адреса из сети VPC | интеграция с облаком; расход адресов |
Популярные плагины
- Flannel — простейший вариант: оверлей VXLAN, без сетевых политик. Используется по умолчанию в k3s.[6]
- Calico — маршрутизация через BGP или оверлей, развитые сетевые политики, режимы на iptables и eBPF. Один из самых распространённых плагинов в продакшене.[5]
- Cilium — построен на eBPF: программы в ядре Linux обрабатывают пакеты без длинных цепочек iptables. Может полностью заменить kube-proxy, поддерживает политики на уровне L7 (HTTP, gRPC), прозрачное шифрование WireGuard и наблюдаемость через Hubble. Выпускник CNCF и выбор по умолчанию во многих управляемых кластерах.[4]
- Облачные плагины — AWS VPC CNI, Azure CNI, GKE Dataplane V2 (на базе Cilium).
- Multus — метаплагин, позволяющий подключить к поду несколько сетей; используется в телекоме.
Сетевые политики
По умолчанию любой под может обращаться к любому. Объект NetworkPolicy ограничивает трафик по меткам подов, пространствам имён и портам — это базовый инструмент сегментации и принципа наименьших привилегий.[3]
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-allow-api
spec:
podSelector:
matchLabels: {app: postgres}
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels: {app: api}
ports:
- port: 5432
Важно: политики применяет именно CNI-плагин. Если плагин их не поддерживает (как Flannel), объекты создадутся без ошибок, но ничего не будут блокировать.
CNI и сервисы
CNI отвечает за связность подов, а виртуальные адреса Service и балансировку между подами обычно реализует kube-proxy через iptables или IPVS. Плагины на eBPF (Cilium, Calico eBPF) берут эту функцию на себя и заметно ускоряют кластеры с тысячами сервисов. Шифрование и политики уровня приложений частично пересекаются с возможностями Service mesh.
Диагностика
kubectl get pods -n kube-system # поды плагина (cilium, calico-node)
ls /etc/cni/net.d/ # активная конфигурация на узле
kubectl run tmp --rm -it --image=nicolaka/netshoot -- bash
cilium status && cilium connectivity test
Если узел в статусе NotReady с сообщением «network plugin is not ready», чаще всего плагин ещё не установлен или его под на этом узле не запустился.