CNI в kubeadm-кластерах: Calico против Flannel в enterprise-среде
Тестируем Calico и Flannel при развёртывании кластеров через kubeadm: сравниваем сетевые политики, сложность настройки и поведение в реальных условиях.
Выбор CNI-плагинов для Kubernetes: Calico vs Flannel в enterprise-среде
Каждый раз когда поднимаешь кластер через kubeadm, на определённом шаге документация вежливо сообщает: «установите CNI-плагин на свой вкус» - и даёт список из десяти вариантов. Хороший способ зависнуть на полчаса. На практике выбор быстро сужается до двух: Calico и Flannel. Мы потратили несколько недель на параллельное тестирование обоих в контексте наших managed-кластеров - вот что получилось.
Зачем вообще выбирать
Kubernetes сам по себе не предоставляет сетевую реализацию - только интерфейс CNI и требования: каждый Pod должен получить уникальный IP, Pods должны видеть друг друга без NAT, Nodes должны видеть Pods. Как именно это реализовано - дело плагина.
Разница между Calico и Flannel не в том, выполняют ли они эти базовые требования - оба выполняют. Разница в том, что поверх этого базиса каждый предлагает.
Flannel: всё работает, и ладно
Начали с Flannel - он часто идёт первым в документации и воспринимается как «дефолтный» вариант. Установка через один манифест:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Кластер поднялся с первого раза. Flannel создаёт оверлейную сеть через VXLAN - каждый узел получает подсеть из общего диапазона, между узлами трафик инкапсулируется. С точки зрения оператора это просто работает: поды друг друга видят, DNS резолвится, Ingress поднимается.
Проблема началась когда мы попытались прикрутить NetworkPolicy. Спойлер - Flannel их не реализует. Сам по себе он сетевую изоляцию не обеспечивает, только маршрутизацию. Да, можно поставить рядом Calico только как enforcement-движок политик поверх Flannel (Canal), но это уже гибридная конструкция со своими нюансами. Для нас это оказался принципиальный момент: в enterprise-среде жить без сетевой изоляции неудобно.
Что у Flannel хорошо:
- Установка и отладка. Один YAML, минимум движущихся частей, логи понятные.
- Ресурсы. Демон лёгкий, не замечали влияния на общую утилизацию узла.
- Стабильность. За несколько недель тестов ни одного инцидента связанного с сетью.
Calico: мощнее, но платишь сложностью
Calico работает принципиально иначе - BGP для маршрутизации между узлами без оверлея. Трафик идёт нативно, каждый Pod-адрес реально маршрутизируется на уровне L3. В локальной сети это обычно быстрее чем VXLAN, хотя для большинства прикладных задач разница не ощущается.
Установка немного сложнее - нужно скачать манифест, отредактировать CALICO_IPV4POOL_CIDR под свой --pod-network-cidr из kubeadm init, применить:
kubectl apply -f calico.yaml
Это мелочь, но уже первый признак что Calico требует чуть больше внимания к конфигурации.
Зато NetworkPolicy работают из коробки - и не просто работают, Calico расширяет стандартный Kubernetes API своими CRD: GlobalNetworkPolicy, HostEndpoint, NetworkSet. Стандартные NetworkPolicy Kubernetes можно применять без изменений, плюс есть возможность прописывать политики на уровне узла и между пространствами имён глобально.
Мы тестировали типовой сценарий: namespace с фронтенд-подами должен ходить только в namespace с API, API - только в namespace с базой, прямого доступа фронт-база быть не должно. На Calico это решается четырьмя манифестами NetworkPolicy и работает предсказуемо. Проверяли через kubectl exec и nc - запрещённые соединения действительно не проходят.
Что у Calico вызвало вопросы:
- BGP в средах с ограниченным L2. В одной из тестовых сред хосты были на разных коммутаторах и BGP-пиринг потребовал отдельного разбирательства с сетевой командой. В конечном счёте решили через режим IP-in-IP - работает, но надо знать о такой возможности.
calico-nodeDaemonSet просит привилегированный доступ. Технически это не уникально для Calico - многие CNI так работают - но в контексте аудита безопасности это предмет для объяснений.- Troubleshooting сложнее. При проблемах с сетью нужно разбираться с
calicoctl, Felix-агентом, BGP-сессиями. Кривая обучения заметная.
Что выбрали и почему
Для кластеров где нужна изоляция на уровне NetworkPolicy - а в enterprise-среде это практически всегда - мы остановились на Calico. Логика простая: добавить изоляцию поверх Flannel потом - это либо Canal (дополнительная сложность) либо миграция CNI (ещё большая головная боль). Лучше сразу выбрать инструмент с нужными возможностями.
Flannel имеет смысл для небольших кластеров где сетевая изоляция не нужна, скорость поднятия важна и операционная нагрузка минимальна. Dev-кластеры, тестовые окружения, внутренние инструменты без требований по изоляции - здесь Flannel выигрывает именно простотой.
Важная оговорка: мы тестировали на kubeadm-кластерах с Ubuntu 16.04, ядро 4.13-4.15. Поведение может отличаться на других конфигурациях - в частности, BGP Calico чувствителен к сетевой топологии, и то что легко работает в одной среде, может требовать дополнительной настройки в другой.
Где мы сейчас
Новые кластеры поднимаем с Calico - BGP-режим там где L2 позволяет, IP-in-IP там где нет. Пишем runbook по типовым сценариям NetworkPolicy чтобы не изобретать каждый раз. Flannel остался на паре legacy-кластеров где менять CNI смысла нет - там и изоляция не нужна, и всё стабильно работает.
Если у вас kubeadm-кластер и вопрос про CNI - обращайтесь, покажем конфигурации которые уже обкатали.
- Kubernetes 1.10: CSI в beta - подключаем Ceph RBD без патчей ядра · 10 апреля 2018
- Kubernetes 1.9: Workloads API в GA - планируем миграцию stateful-сервисов · 23 января 2018