ADG Оставить заявку
Блог DevOps 5 мин чтения

Cilium вместо Flannel: Network Policy на L7 для микросегментации под требования КИИ

Внедряем Cilium в production-кластер заказчика. Network Policy на уровне HTTP path и gRPC метода дают микросегментацию, сопоставимую с требованиями ФСТЭК по сегментации КИИ.

Контекст момента

Рост зрелости Kubernetes Network Policy: Cilium и Calico как production CNI с политиками уровня L7

Заказчик - производственная компания с объектами КИИ второй категории. Кластер Kubernetes поднят несколько месяцев назад на Flannel, живёт на нём CI/CD и несколько внутренних сервисов. Когда начали готовиться к аттестации, выяснился предсказуемый факт: ФСТЭК в методических рекомендациях по защите КИИ ждёт не «у нас есть Kubernetes», а обоснованную сегментацию с управляемыми точками контроля трафика.

Flannel - отличный CNI, когда нужна простая L2/L3-связность в кластере. Но Network Policy он не поддерживает вообще. Это значит, что pod из любого namespace может стучаться к pod-у в любом другом - без ограничений и без видимости этого трафика.

Почему Cilium, а не Calico

У нас была развилка. Calico - проверенный выбор, поддерживает стандартные Kubernetes Network Policy, хорошо документирован, много кейсов в production. Если нужна базовая L3/L4-сегментация - Calico закрывает задачу.

Cilium мы выбрали из-за L7. В Cilium есть собственный ресурс CiliumNetworkPolicy, который позволяет описывать политики не только по IP/порту, но и по HTTP-методу, HTTP-пути, заголовкам и gRPC-методу. Это другой уровень детализации.

Для заказчика это принципиально: внутри кластера живут несколько микросервисов, которые общаются через REST API. Требование ФСТЭК по сегментации (мера ЗИС.17) подразумевает контроль информационных потоков - и «порт 8080 открыт» как обоснование слабее, чем «сервис А может делать GET /api/v1/data, но не может делать POST /api/v1/admin».

Под капотом Cilium использует eBPF - программы загружаются прямо в ядро Linux вместо традиционных iptables-цепочек. Это даёт и производительность, и возможность реализовывать логику, которая в iptables недостижима в принципе.

Как выглядит L7-политика

Вот упрощённый пример того, что мы пишем для разграничения доступа внутри кластера:

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: api-gateway-to-backend
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend-service
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: api-gateway
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/v1/data"
        - method: "POST"
          path: "/api/v1/events"

Всё остальное - заблокировано. Если какой-то сервис попытается обратиться к /api/v1/admin или использовать метод DELETE - запрос упадёт с 403, и это событие попадёт в лог Cilium. Никаких дополнительных middleware, никакого кода в самом сервисе.

Для gRPC аналогично - можно ограничить конкретные методы по имени пакета и метода:

rules:
  l7proto: grpc
  l7:
  - path: "/mypackage.MyService/GetData"

Как мы мигрировали с Flannel

Замена CNI на работающем кластере - операция с риском. Flannel и Cilium несовместимы по модели адресации, и «просто поменять» не получается.

Схема, которую мы применили:

Первое - подготовка нового кластера параллельно. Поднять чистый кластер с Cilium, перенести туда workloads в staging-режиме, проверить что всё работает и что L7-политики ведут себя ожидаемо.

Второе - инвентаризация реального трафика перед написанием политик. Cilium Hubble (observability-компонент) умеет показывать фактические потоки трафика между pod-ами - без политик, просто в режиме наблюдения. Мы включили его в staging и несколько дней собирали реальную карту взаимодействий. Это позволило не придумывать политики из головы, а написать их на основе того, что происходит на самом деле.

Третье - deny-all как исходная точка. После переноса workloads включили default-deny для всех namespace-ов и добавляли разрешения по одному потоку. Несколько раз обнаруживали трафик, который никто не ожидал: например, один из вспомогательных сервисов стучался к другому, потому что когда-то так решили и никто это не задокументировал.

Четвёртое - полный переезд в maintenance window. Старый кластер - в cordon, трафик переключается на новый, старый идёт в утиль.

Что получилось и что нет

Получили реальную сегментацию на уровне HTTP-глаголов и путей. На вопрос аудиторов «как контролируется трафик между сервисами» теперь есть ответ в виде конкретных манифестов, а не «у нас Kubernetes и там всё хорошо».

Hubble оказался полезен не только при переезде - он остался как постоянный инструмент мониторинга трафика внутри кластера. Видно кто к кому ходит, видно что блокируется, видно нарушения политик в реальном времени.

Сложности тоже были. L7-инспекция в Cilium требует, чтобы трафик был незашифрованным на уровне CNI - то есть если сервисы используют mTLS между собой (например, через Istio), L7-правила Cilium не видят содержимое. В нашем кластере mTLS не было, но это ограничение надо держать в голове при проектировании.

Вторая сложность: CiliumNetworkPolicy - это кастомный ресурс, не стандартный Kubernetes NetworkPolicy. Если когда-нибудь понадобится сменить CNI - политики придётся переписывать. Это осознанный trade-off.

Где мы сейчас

Кластер работает на Cilium чуть больше месяца. Workloads стабильны, производительность не деградировала. Материалы для аттестации по части сегментации - собраны.

Соответствие приказу ФСТЭК № 239 (мера ЗИС.17) выглядит убедительнее, когда за ней стоят не общие слова про «изоляцию», а конкретные политики в git с описанием что кому разрешено и почему. Managed-сопровождение в данном случае позволило провести переезд в рамках обычных рабочих задач, не привлекая отдельную проектную команду.

Дальше планируем добавить политики для namespace-level изоляции - сейчас микросервисы из разных команд живут в разных namespace-ах, но трафик между ними ничем не ограничен, кроме договорённостей. Это будет следующий шаг.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.