Привет, Хабр! Сегодня у нас на повестке дня тема кастомизации сетевого стека в Kubernetes с Cilium.

Cilium — это сетевое решение, которое работает прямо в ядре Linux и построено на основе eBPF. Его главная задача — обеспечить эффективное, а главное, безопасное взаимодействие между подами в кластере Kubernetes. И это не просто замена стандартному kube-proxy. Это полноценный инструмент для построения сетевых политик, мониторинга и кастомизации сетевого стека.

Основные фичи:

  1. Гибкие сетевые политики: можно задать фильтры трафика на уровнях L3 (IP), L4 (TCP/UDP) и L7 (HTTP, gRPC).

  2. Интеграция с Envoy: вместо того, чтобы ограничиваться стандартными функциями, вы можете подключить Envoy для управления сетевыми запросами или даже написать собственные программы на eBPF для уникальных задач.

  3. Устранение узких мест: Cilium устраняет проблемы масштабирования iptables, переходя к использованию eBPF, который выполняет фильтрацию и маршрутизацию пакетов непосредственно в ядре Linux. Вместо линейного перебора правил, как в iptables, eBPF использует хэш-таблицы и карты, которые дают мгновенный доступ к нужным данным. Так трафик обратывается быстрее, с меньшей нагрузкой на процессор и без создания узких мест.

Установим

Перед тем как начать, убедитесь, что у вас есть:

  • Kubernetes-кластер.

  • Доступ к CLI kubectl.

  • Рабочий helm.

Установим Cilium CLI:

curl -L --remote-name https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64
chmod +x cilium-linux-amd64
sudo mv cilium-linux-amd64 /usr/local/bin/cilium

После устанавливаем Cilium с помощью Helm:

helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium \
  --namespace kube-system \
  --set kubeProxyReplacement=strict \
  --set k8sServiceHost= \
  --set k8sServicePort=

Проверяем статус:

kubectl -n kube-system get pods -l k8s-app=cilium

Если все поды в состоянии Running, можно двигаться дальше.

Кастомизация сетевых политик

Cilium позволяет создавать сетевые политики, которые гораздо мощнее стандартных NetworkPolicy в Kubernetes. Рассмотрим пару примеров.

Ограничение доступа по L7

Допустим, есть два пода: frontend и backend. Задача — разрешить доступ от frontend к backend только для HTTP GET-запросов.

Создаем CiliumNetworkPolicy:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-http-get
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/.*"

Применяем политику:

kubectl apply -f allow-http-get.yaml

Теперь фронтенд может обращаться к бэкенду только через GET-запросы. Попробуйте отправить POST-запрос — и он будет заблокирован.

Ограничение исходящего трафика

Допустим, нужно ограничить доступ из frontend ко всем внешним ресурсам, кроме одного сервиса.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: restrict-egress
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toEntities:
    - world
    toEndpoints:
    - matchLabels:
        app: trusted-service
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP

Применяем эту политику:

kubectl apply -f restrict-egress.yaml

Теперь трафик из frontend будет ограничен только к определённым ресурсам.

Разрешение доступа только к определенному домену

Теперь разрешим поду доступ только к домену example.com через HTTPS.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-specific-domain
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toFQDNs:
    - matchNames:
      - "example.com"
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP

Применяем:

kubectl apply -f allow-specific-domain.yaml

Теперь трафик из frontend будет разрешён только к example.com.

Ограничение доступа между namespace

Допустим, есть два namespace: dev и prod. Нужно запретить всем подам из dev доступ к подам в prod, кроме одного сервиса.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: restrict-dev-to-prod
  namespace: prod
spec:
  endpointSelector:
    matchLabels:
      app: prod-service
  ingress:
  - fromEndpoints:
    - matchLabels:
        namespace: dev
        app: allowed-dev-app

Применяем политику:

kubectl apply -f restrict-dev-to-prod.yaml

Теперь только под allowed-dev-app из dev может обращаться к prod-service в prod.

Мониторинг трафика с Hubble

Hubble — это встроенный инструмент для мониторинга трафика в Cilium. Его установка занимает пару минут:

cilium hubble enable
cilium hubble ui

Открываем веб-интерфейс Hubble и наблюдаем за всем, что происходит в сети кластера. Можно будет увидеть:

  • Какие поды взаимодействуют друг с другом.

  • Какие запросы блокируются политиками.

  • Статистику по каждому сервису.

Кастомные eBPF-программы

Если очень хочется пойти дальше, Cilium позволяет загружать свои eBPF-программы для реализации специфичных задач. Например, можно написать фильтр, который будет логировать только трафик, идущий через определенный порт.

Простой пример фильтра на eBPF, который логирует HTTP-трафик:

#include 
#include 
#include 

int log_http(struct __sk_buff *skb) {
    char msg[] = "HTTP request detected\n";
    bpf_trace_printk(msg, sizeof(msg));
    return 0;
}

Компилируем и загружаем:

ebpf-loader -o http_filter.o -s log_http.c

Загружаем программу через Cilium:

cilium bpf install http_filter.o

Теперь каждый HTTP-запрос будет логироваться на уровне ядра.

Фильтрация по IP

Добавим фильтр, который блокирует трафик с определённого IP-адреса:

#include 
#include 
#include 

int block_ip(struct __sk_buff *skb) {
    struct iphdr *ip = bpf_hdr_pointer(skb);
    if (ip->saddr == htonl(0xC0A80001)) { // 192.168.0.1
        return TC_ACT_SHOT; // Drop packet
    }
    return TC_ACT_OK;
}

Загружаем этот фильтр аналогично:

ebpf-loader -o block_ip.o -s block_ip.c
cilium bpf install block_ip.o

Теперь пакеты с заданного IP-адреса будут блокироваться.

Подробнее с Cilium можно ознакомиться здесь.


Больше об актуальных подходах и инструментах ИТ-инфраструктуры вы можете узнать в рамках онлайн-курсов от практикующих экспертов отрасли. Подробности в каталоге.

А 24 декабря пройдет открытый урок «Технология контейнеризации, введение в Docker» — записаться можно на странице курса «DevOps практики и инструменты».

Комментарии (0)