# Сетевые плагины (CNI)

> Container Network Interface — стандарт подключения контейнеров к сети и семейство плагинов (Calico, Cilium, Flannel), реализующих сеть подов в Kubernetes.

Источник: https://llmdocs.ru/wiki/cni/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Полное название**: 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](https://llmdocs.ru/wiki/kubernetes.md) сеть подов не реализует — он вызывает **CNI-плагин**, выбранный при установке кластера. От плагина зависят производительность сети, поддержка сетевых политик, шифрование трафика между узлами и наблюдаемость.

## Сетевая модель Kubernetes

Kubernetes требует от сети трёх свойств:[2]

1. каждый [Pod](https://llmdocs.ru/wiki/pod.md) получает собственный IP-адрес;
2. поды на любых узлах общаются друг с другом напрямую, без [NAT](https://llmdocs.ru/wiki/nat.md);
3. агенты на узле (kubelet) видят все поды этого узла.

Как именно это обеспечить — задача плагина. Адреса подов выделяются из отдельного диапазона (например, `10.244.0.0/16`, см. [IP-адрес и подсети (CIDR)](https://llmdocs.ru/wiki/ip-cidr.md)), обычно каждому узлу достаётся своя подсеть.

## Как работает CNI

Спецификация очень проста: плагин — исполняемый файл в `/opt/cni/bin/`, который среда выполнения (containerd, CRI-O) вызывает с командой `ADD`, `DEL` или `CHECK` в переменной окружения и JSON-конфигурацией из `/etc/cni/net.d/` на стандартном вводе.[1] В ответ плагин возвращает назначенный адрес. Плагины можно выстраивать в цепочку: один создаёт интерфейс, другой выделяет адрес (IPAM), третий настраивает ограничение полосы.

Внутри типичная схема такова: для пода создаётся пара виртуальных интерфейсов `veth` — один конец в сетевом пространстве имён пода (см. [Namespaces и cgroups](https://llmdocs.ru/wiki/namespaces-cgroups.md)), другой на узле. Дальше пакеты между узлами передаются одним из способов:

| Способ | Как | Плюсы и минусы |
|---|---|---|
| Оверлей (VXLAN, Geneve) | пакеты подов упаковываются в UDP между узлами | работает в любой сети; накладные расходы и меньший MTU |
| Прямая маршрутизация (BGP) | маршруты к подсетям подов анонсируются в сеть | без инкапсуляции, быстро; нужна поддержка сети |
| Нативная сеть облака | поды получают адреса из сети VPC | интеграция с облаком; расход адресов |

## Популярные плагины

- **Flannel** — простейший вариант: оверлей VXLAN, без сетевых политик. Используется по умолчанию в [k3s](https://llmdocs.ru/wiki/k3s.md).[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]

```yaml
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](https://llmdocs.ru/wiki/service-ingress.md) и [балансировку](https://llmdocs.ru/wiki/load-balancing.md) между подами обычно реализует kube-proxy через iptables или IPVS. Плагины на eBPF (Cilium, Calico eBPF) берут эту функцию на себя и заметно ускоряют кластеры с тысячами сервисов. Шифрование и политики уровня приложений частично пересекаются с возможностями [Service mesh](https://llmdocs.ru/wiki/service-mesh.md).

## Диагностика

```bash
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», чаще всего плагин ещё не установлен или его под на этом узле не запустился.

## См. также

- [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md)
- [Service и Ingress](https://llmdocs.ru/wiki/service-ingress.md)
- [Namespaces и cgroups](https://llmdocs.ru/wiki/namespaces-cgroups.md)
- [Service mesh](https://llmdocs.ru/wiki/service-mesh.md)

## Источники

1. [CNI — Container Network Interface specification](https://www.cni.dev/docs/spec/)
2. [Kubernetes Docs — Cluster Networking](https://kubernetes.io/docs/concepts/cluster-administration/networking/)
3. [Kubernetes Docs — Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
4. [Cilium Documentation](https://docs.cilium.io/)
5. [Calico Documentation](https://docs.tigera.io/calico/latest/about/)
6. [Flannel — репозиторий](https://github.com/flannel-io/flannel)
