Кратко про то, как кастомизировать сетевой стек в Kubernetes с Cilium

от автора

Привет, Хабр! Сегодня у нас на повестке дня тема кастомизации сетевого стека в 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 практики и инструменты».


ссылка на оригинал статьи https://habr.com/ru/articles/866796/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *