Короткий ответ
Однозначно лучшего CNI нет: оба решения поддерживают NetworkPolicy и расширенные возможности (Calico — через собственный GlobalNetworkPolicy и опциональный eBPF dataplane, Cilium — изначально построен на eBPF с L7-политиками и встроенной сетевой телеметрией), выбор зависит от требуемой глубины видимости и контроля трафика, существующей экспертизы команды и совместимости с остальной инфраструктурой (service mesh, облачный провайдер).
Как это работает подробнее
базовый Kubernetes NetworkPolicy API ограничен L3/L4 (IP, порты, namespace/pod selector); для более тонкого контроля (L7, например "разрешить только HTTP GET на /api, запретить DELETE") нужны расширения конкретного CNI — у Cilium это CiliumNetworkPolicy с L7-правилами на основе eBPF, у Calico — собственные Calico-специфичные политики с похожими, но не идентичными возможностями. eBPF-решения (Cilium, а также режим eBPF у Calico) дают более детальную наблюдаемость трафика на уровне ядра без классического iptables, что снижает накладные расходы на больших кластерах с большим числом Service/правил.
- Компромисс. eBPF-решения дают больше возможностей и часто лучшую производительность на масштабе, но требуют более новых версий ядра Linux и специфичной экспертизы для диагностики проблем (отладка eBPF сложнее классического iptables для большинства инженеров); выбор конкретного CNI также может диктоваться облачным провайдером (некоторые managed-сервисы ограничивают поддерживаемые CNI) — это стоит явно обсуждать с учётом текущей инфраструктуры, а не выбирать CNI изолированно от остального стека.
Пример кода
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata: { name: restrict-api-methods }
spec:
endpointSelector: { matchLabels: { app: api } }
ingress:
- toPorts:
- ports: [{ port: "8080", protocol: TCP }]
rules:
http: [{ method: "GET", path: "/public/.*" }]Что использовать на практике
- Практика. при миграции между CNI в уже работающем production-кластере возникает значительный риск — нет "горячей" миграции без простоя для большинства CNI, так как смена dataplane требует пересоздания сетевого стека узлов, что обычно означает поэтапный вывод узлов из кластера, их переконфигурацию и возврат (аналог rolling upgrade, но на уровне инфраструктуры, а не приложений), либо полное пересоздание кластера с переносом workload. Выбор CNI для multi-tenant окружения также должен учитывать, насколько команды сами способны писать и поддерживать специфичные для CNI политики, или стоит ограничиться базовым NetworkPolicy API для простоты.
Подводные камни
- Риски. частая ошибка — считать, что смену CNI в работающем кластере можно сделать "на горячую" без пересоздания узлов; также кандидаты нередко путают возможности базового NetworkPolicy (ограниченного L3/L4) с L7-фильтрацией, которая доступна только через CNI-специфичные CRD вроде
CiliumNetworkPolicy.