linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Контейнеры (бонус)/cni-plugins

kb/containers ── Контейнеры (бонус) ── advanced

CNI plugins - сеть Kubernetes (calico, cilium, flannel)

CNI - спека плагина: дай pod IP и сеть. Реализации: flannel (VXLAN L2-overlay), calico (BGP routing), cilium (eBPF в kernel). Каждая даёт NetworkPolicy для firewall'а между подами. IPAM - часть CNI, выделяет адреса.

view as markdownaka: cni, calico, cilium, flannel, k8s-network, container-network-interface

Зачем CNI

Когда kubelet запускает pod, ему надо: создать [[namespaces|netns]], присоединить pod к сети кластера, дать IP. Делать это руками для каждого CNI-implementation, тысячи строк в kubelet. Вместо этого есть Container Network Interface (CNI), простой контракт.

CNI plugin, бинарник, kubelet его вызывает с параметрами через stdin/JSON. Plugin делает что хочет (создаёт veth, навешивает routes, заводит overlay), возвращает выделенный IP в JSON.

Контракт:

ADD     - подключить pod к сети, вернуть IP
DEL     - отключить, освободить IP
CHECK   - проверить состояние
VERSION - какие версии CNI поддерживаешь

Конфиг лежит в /etc/cni/net.d/*.conflist, бинарники в /opt/cni/bin/. Это то, что DaemonSet CNI-плагина раскатывает при старте.

Что должен обеспечить любой CNI в k8s

Помимо CNI-spec'и есть требования k8s:

  1. Каждому pod'у, уникальный IP в pod-CIDR
  2. Pod-to-pod без NAT, pod видит pod по реальному IP, не через proxy и не через NAT
  3. Pod-to-node работает в обе стороны
  4. NetworkPolicy, поддержка firewall'а между подами
  5. (Опционально) сервисы, encryption, observability

Некоторые CNI добавляют сверху: BGP-объявления, IPAM с reservations, bandwidth-shaping, encryption (WireGuard/IPsec), service-mesh.

Три подхода

ПодходКак pod-to-pod трафик ходитProCon
L2 overlay (flannel/VXLAN)encap пакета в UDP, decap на нодеработает поверх любой сетиoverhead 50 байт, MTU-сюрпризы
L3 routing (calico/BGP)каждая нода объявляет pod-CIDR через BGPнет encap, native MTU, fastнужна BGP-friendly сеть (или IPIP fallback)
eBPF (cilium)программируемые маршруты в kernel-spaceобходят kube-proxy, observability, encryptionсложнее debug, нужен новый kernel

flannel, простейший VXLAN-overlay

Архитектура:

  • DaemonSet flanneld на каждой ноде
  • Считывает Node CIDR из k8s API
  • Создаёт flannel.1 VXLAN interface
  • Пакеты pod-to-pod cross-node инкапсулируются в UDP/8472
pod-A (10.244.1.5) ──► veth ──► flannel.1 ──► encap ──► UDP ──► node-B
                                                                  │
                                                            decap ──► flannel.1 ──► veth ──► pod-B (10.244.2.7)

Минусы:

  • MTU 1450 (вместо 1500) из-за VXLAN overhead. Если приложение шлёт 1500-байтные пакеты с DF=1, теряются. Сюда же проблема Path MTU Discovery в облаке (GCP/AWS режут ICMP).
  • Нет NetworkPolicy в простой flannel (только с patch'ами).
  • Нет BGP/encryption из коробки.

Плюсы: 5 минут до запуска, работает где угодно. Default для kind/minikube.

calico, BGP + native routing

Подход: вместо overlay'я анонсировать pod-CIDR'ы каждой ноды как маршруты по BGP. Тогда любой pod-to-pod пакет идёт нативно по сети, без encap.

Архитектура:

  • calico-node DaemonSet с BIRD (BGP-демон)
  • Каждая нода, BGP peer
  • Анонсируют свои pod-CIDR'ы соседям (full mesh или через route reflector)
  • Backend для NetworkPolicy, iptables (стандарт) или eBPF (опция)
Node-A (pod-CIDR 10.244.1.0/24)  ◄──── BGP ────►  Node-B (10.244.2.0/24)
     │                                                  │
     └─► routing table:                              └─► routing table:
         10.244.2.0/24 via Node-B                       10.244.1.0/24 via Node-A

Если сеть не BGP-friendly (типичный AWS/GCP, где L3 не пропускает чужие src/dst), включают IP-in-IP или VXLAN encapsulation фактически фолбек на overlay.

Сильные стороны:

  • NetworkPolicy реализована глубже, чем у flannel: помимо стандартных k8s-policy есть GlobalNetworkPolicy, HostEndpoint, DNS-based rules
  • Observability через calicoctl, метрики
  • eBPF datapath (опция), заменяет kube-proxy, faster

Когда выбирать: production-кластеры, нужна гранулярная NetworkPolicy. Дефолт во многих managed k8s (GKE Dataplane v1, OpenShift).

cilium, eBPF first

Радикально другой подход: всё в eBPF в kernel. Нет iptables-цепочек для kube-proxy/policy, всё компилируется в BPF-программу.

Архитектура:

  • cilium-agent DaemonSet
  • Подключает eBPF-программы к XDP / tc-ingress / tc-egress / cgroup
  • Identity-based policy (вместо src-IP/dst-IP, namespace+labels)
  • Может полностью заменить kube-proxy (Service routing в eBPF)

Возможности (некоторые уникальные):

  • Hubble, observability в eBPF, видит каждый flow
  • Encryption, WireGuard или IPsec между нодами
  • L7 NetworkPolicy, фильтр по HTTP method/path, DNS-name
  • Cluster Mesh, несколько кластеров как один
  • Service Mesh, sidecar-free через eBPF (cilium service mesh)

Минусы:

  • Требует kernel 5.4+ (lots of eBPF features), реально 5.10+ для full feature set
  • Сложнее debug, bpftool prog list вместо iptables -t nat -L
  • Высокая потребность в RAM на больших policy-sets

Когда выбирать: новые кластеры на современном kernel, нужна observability и L7-policy, есть готовность к steeper learning curve. Backend в EKS Anywhere, GKE Dataplane v2, AKS Cilium.

NetworkPolicy

Стандартный k8s-объект для pod-уровня firewall'а:

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: api-deny-egress, namespace: prod }
spec:
  podSelector:
    matchLabels: { app: api }
  policyTypes: [Ingress, Egress]
  ingress:
  - from:
    - podSelector:
        matchLabels: { app: web }
    - namespaceSelector:
        matchLabels: { name: monitoring }
    ports:
    - { protocol: TCP, port: 8080 }
  egress:
  - to:
    - podSelector:
        matchLabels: { app: postgres }
    ports:
    - { protocol: TCP, port: 5432 }
  - to:                              # разрешить DNS
    - namespaceSelector: {}
      podSelector: { matchLabels: { k8s-app: kube-dns } }
    ports: [{ protocol: UDP, port: 53 }]

Семантика default-deny: если на pod есть хотя бы один NetworkPolicy с типом Ingress, весь не-разрешённый Ingress блокируется. Поэтому часто пишут pair: default-deny-all + конкретные allow'ы.

Реализация, на CNI. flannel без patch'а игнорирует NetworkPolicy (silently!). calico/cilium соблюдают. Проверить, пометить namespace и попробовать kubectl exec curl.

IPAM, IP Address Management

Часть CNI: кто и как выделяет IP подам. Варианты:

IPAMКак работаетГде использовать
host-localкаждой ноде block IP, выдаёт из негоflannel, single-cluster
calico-ipamцентрализованно через etcd, IP Pool с reservationcalico
cilium-ipamкак host-local, плюс multi-poolcilium
AWS VPC CNIкаждый pod, настоящий VPC IP (ENI secondary IP)EKS
Azure CNIкак AWS, в Azure VNETAKS
whereaboutscluster-wide IPAM из range'а, для multusmulti-net

AWS VPC CNI и Azure CNI дают routable pod IP в облачной сети не нужен overlay, NLB балансирует прямо в pod. Минус: лимиты ENI на инстанс (m5.large = 30 IP), при больших pods-per-node нужны большие инстансы.

Multus, несколько сетей одному pod'у

Стандартная k8s-сеть, одна на pod. Если нужны две (management + data, RAN-functions, NFV), Multus CNI как мета-плагин:

yaml
metadata:
  annotations:
    k8s.v1.cni.cncf.io/networks: macvlan-conf, sriov-conf

Применяется в телеком, edge, ML-кластерах. Не для типичного web-prod.

Когда что-то пошло не так

  • Pod в ContainerCreating бесконечно, NetworkReady=false CNI не работает. kubectl logs -n kube-system <cni-daemonset>, journalctl -u kubelet | grep -i cni. Часто CNI binary не установлен или конфиг неверный.
  • Pod-to-pod cross-node не работает, у flannel/VXLAN, UDP/8472 блокируется firewall'ом. У calico, BGP-сессии не установились, calicoctl node status.
  • MTU блекхол, крупные пакеты теряются, мелкие проходят. Симптом: SSH работает, apt update зависает на каком-то пакете. Лечится подгонкой MTU pod-сети под underlay (flannel: 1450 если underlay 1500).
  • NetworkPolicy не работает, CNI не реализует её (флэннел!), либо есть baseline allow-all правило, либо kube-system namespace в исключениях.
  • Calico/IPIP рост encap latency, overlay включился сам потому что BGP не сошёлся. Проверь calicoctl node status.
  • Pod IP exhaust в EKS, упёрлись в лимит ENI/IP per node, kubectl get events | grep "no IP". Решение: больший instance type или prefix-delegation в VPC CNI.
  • cilium eBPF program не загружается, старый kernel, или отключен CONFIG_BPF_SYSCALL. cilium status покажет что падает.

Полезные команды

  • cat /etc/cni/net.d/*, конфиг текущего CNI
  • ls /opt/cni/bin/, какие плагины установлены
  • crictl exec <containerid> ip addr, pod-network изнутри
  • calicoctl node status (для calico), состояние BGP
  • cilium status / cilium connectivity test, для cilium
  • kubectl get pods -n kube-system, здоровье CNI DaemonSet'а

§ команды

bash
kubectl get pods -n kube-system -l k8s-app=calico-node

Проверить, что CNI-DaemonSet запущен на всех нодах

bash
calicoctl node status

Состояние BGP-сессий между нодами в calico-кластере

bash
cilium status --verbose

Полный статус cilium: eBPF datapath, kube-proxy replacement, encryption

bash
kubectl get networkpolicy -A

Все NetworkPolicy в кластере - смотреть до подозрений на неправильную блокировку

bash
kubectl exec -it pod-a -- nc -zv pod-b 8080

Проверить L4-связность между подами - быстрый тест NetworkPolicy

bash
ip route show table all | grep -E 'cali|flannel|cilium'

Маршруты на ноде, добавленные CNI - debug при проблемах с pod-to-pod

bash
kubectl get pods -A -o wide | awk '{print $7}' | sort -u | wc -l

Сколько уникальных IP занято подами - на лимит per-node влияет IPAM

§ см. также

  • kubernetes-services-and-ingressKubernetes Service и Ingress - сетевая публикация подовService - стабильный VIP перед группой подов (label selector). Типы: ClusterIP (внутри), NodePort (порт на каждой ноде), LoadBalancer (внешний LB облака), ExternalName (CNAME). Ingress - L7 reverse-proxy (nginx/traefik) для HTTP-роутинга.
  • kubernetes-pod-lifecycleKubernetes pod lifecycle - от Pending до TerminatedPod проходит фазы Pending → Running → Succeeded/Failed/Unknown. Init-containers выполняются последовательно до основных. Probes: startup → readiness/liveness. SIGTERM + grace period при удалении.
  • veth-pairveth pairveth-pair - два связанных виртуальных Ethernet-интерфейса. Что заходит в один конец - выходит из другого. Базовый кирпич всех Linux-контейнерных сетей.
  • linux-bridgeLinux bridge - программный свитчBridge - программный L2-свитч в ядре Linux. Учит MAC в FDB, форвардит фреймы между интерфейсами. Основа Docker default network, KVM bridge, libvirt. С vlan_filtering эмулирует управляемый свитч.
  • vxlan-overlayVXLAN - L2 overlay поверх L3-сетиVXLAN - L2-overlay через UDP/4789. 24-битный VNI = 16M сегментов (vs 4K у VLAN). VTEP делает encap/decap. BUM-трафик идёт через multicast или head-end replication. EVPN-VXLAN - control plane через BGP. Underlay MTU 1550 минимум.
  • ebpf-xdpeBPF XDP - kernel data-planeXDP - eBPF-программа на самом раннем RX-hook (до skb_alloc). Actions: DROP, PASS, TX, REDIRECT. Native-mode в драйвере, generic в стеке. AF_XDP - zero-copy в userspace. Use cases - DDoS-фильтр, L4 load balancer, cilium kube-proxy.
  • ebpf-basicseBPF - программируемый kerneleBPF - запуск sandboxed-программ в kernel без kernel-modules. Прицепляются к hooks (kprobe, uprobe, tracepoint, perf, socket, XDP). Verifier гарантирует завершение и safety. JIT компилирует в native. bpftool/libbpf/BCC - userspace tooling.
  • policy-routingPolicy routing - rule-based маршрутизацияPolicy routing - выбор routing-таблицы по src-IP, fwmark, iif, tos. ip rule + ip route table N. Multi-uplink, source-based routing, VRF, split-tunnel VPN. RPDB - Routing Policy Database.
  • service-discovery-prometheusService discovery в Prometheus: k8s, Consul, file_sd, relabelProm discoverит targets через k8s API, Consul, file_sd (static). relabel_configs - до scrape (filter+rewrite labels). metric_relabel - после scrape (drop bad metrics). Без relabel - cardinality из k8s взрывается.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки