Сетевые политики Cilium
Обзор
Сетевые политики Cilium ограничивают, какой трафик может приходить в поды (Ingress) и уходить из подов (Egress). Без политик весь трафик разрешён. После добавления хотя бы одной политики для неймспейса или пода действует принцип «запрещено всё, что не разрешено явно».
Где настраивать: Сетевые политики в разделе сетей кластера или Администрирование → Кастомные ресурсы. Политики можно создавать через графический интерфейс или импорт манифеста.
Скриншот: статус сетевой политики

Важно: как работают политики
Поведение по умолчанию
| Ситуация | Результат |
|---|---|
| В неймспейсе нет сетевых политик | Весь трафик разрешён (входящий и исходящий) |
| В неймспейсе есть хотя бы одна политика | Разрешён только трафик, явно описанный в правилах. Всё остальное блокируется |
Обратите внимание! Частая ошибка: Добавили политику «разрешить Ingress» и забыли разрешить DNS. Поды перестали резолвить имена — приложение «сломалось». Всегда добавляйте все нужные правила в одной политике или несколькими политиками.
Что такое endpointSelector
endpointSelector определяет, к каким подам применяется политика:
endpointSelector: {}— ко всем подам в неймспейсе (пустой селектор = все поды)endpointSelector: { matchLabels: { app: my-app } }— только к подам с лейбломapp=my-app
Политика с endpointSelector: {} и правилами ingress/egress задаёт, какой трафик разрешён для выбранных подов. Всё, что не попало в правила, блокируется.
Кластерные и неймспейсные политики
| Тип | Применение | Когда использовать |
|---|---|---|
| ClusterwideCiliumNetworkPolicy | Ко всему кластеру | Общие правила (например, доступ к DNS для всех) |
| CiliumNetworkPolicy | К одному неймспейсу | Изоляция конкретного приложения |
Рекомендация для начала: Используйте неймспейсные политики (CiliumNetworkPolicy). Они проще и не затрагивают весь кластер.
Скриншот: редактор кластерных сетевых политик

Скриншот: редактор неймспейсных сетевых политик

Ключевые понятия
Ingress (входящий трафик)
Кто может подключаться к вашим подам:
- Вне кластера — пользователи, внешние сервисы, Ingress Controller
- Внутри кластера — поды из других неймспейсов
- Внутри неймспейса — поды из того же неймспейса
Egress (исходящий трафик)
Куда ваши поды могут подключаться от:
- Вне кластера — внешние API, интернет (по IP или FQDN)
- Внутри кластера — Kubernetes DNS, KubeAPI, другие поды и сервисы
- Внутри неймспейса — поды и сервисы в том же неймспейсе
matchLabels
Селектор по лейблам подов. Пример:
matchLabels:
app.kubernetes.io/name: my-backend
io.kubernetes.pod.namespace: my-app
Правило применяется только к подам, у которых есть все указанные лейблы. Посмотреть лейблы пода: kubectl get pod <name> -n <ns> --show-labels.
Пошаговая настройка: веб-приложение с Ingress
Типичный сценарий: приложение в неймспейсе my-app, доступно извне через Ingress.
Шаг 1. Определите, какой трафик нужен
| Направление | Кто/куда | Зачем |
|---|---|---|
| Ingress | От Ingress Controller | Пользователи заходят через браузер |
| Egress | К Kubernetes DNS | Резолв имён (Service, внешние домены) |
| Egress (опционально) | К KubeAPI | Нужно только операторам, контроллерам |
Шаг 2. Узнайте лейблы Ingress Controller
kubectl get pods -n ingress -l app.kubernetes.io/name=shturval-ingress-controller --show-labels
Обычно: app.kubernetes.io/name: shturval-ingress-controller, io.kubernetes.pod.namespace: ingress.
Шаг 3. Создайте политику
Одна политика с всеми нужными правилами:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: my-app-policy
namespace: my-app
spec:
description: "Web app: Ingress from controller + DNS"
endpointSelector: {}
ingress:
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: shturval-ingress-controller
io.kubernetes.pod.namespace: ingress
egress:
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- port: "9153"
protocol: TCP
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
app.kubernetes.io/name: shturval-caching-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "9253"
protocol: TCP
Что делает эта политика:
endpointSelector: {}— применяется ко всем подам вmy-appingress— разрешает входящий трафик только от Ingress Controlleregress— разрешает исходящий трафик к kube-dns и shturval-caching-dns (DNS)
Шаг 4. Проверьте
# Приложение отвечает
curl -H "Host: app.example.com" http://<INGRESS_IP>/
# Поды в Running
kubectl get pods -n my-app
Если приложение перестало работать — см. Траблшутинг.
Типичные сценарии
Сценарий 1: Frontend + Backend в одном неймспейсе
Frontend принимает трафик от Ingress, ходит в Backend по имени Service.
Нужно разрешить:
- Ingress: от Ingress Controller
- Egress: DNS, трафик к Backend (по лейблам или
toEndpoints: [{}]внутри неймспейса)
Сценарий 2: Backend вызывает внешний API
Backend обращается к https://api.external.com.
Нужно разрешить:
- Egress: DNS (обязательно для FQDN)
- Egress: до CIDR или FQDN внешнего API (по IP или домену)
Сценарий 3: Backend только для внутренних подов
Backend не должен быть доступен извне, только из других подов кластера.
Нужно разрешить:
- Ingress: от конкретных неймспейсов или подов (по лейблам)
- Egress: DNS, при необходимости — к другим сервисам
Сценарий 4: Оператор или контроллер
Поды, которым нужен доступ к KubeAPI (например, операторы).
Нужно разрешить:
- Egress:
toEntities: [kube-apiserver] - Egress: DNS (если нужно)
Примеры с пояснениями
Доступ к KubeAPI-серверу
Для подов, которым нужен доступ к API Kubernetes (операторы, контроллеры):
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-kube-apiserver
namespace: operators
spec:
description: "For endpoints in this namespace, allow egress to kube-apiserver"
endpointSelector: {}
egress:
- toEntities:
- kube-apiserver
toEntities: [kube-apiserver] — специальный селектор Cilium для API-сервера кластера.
Запрещающая политика (deny-all)
Блокирует весь трафик в неймспейсе. Используйте осторожно, только если нужна полная изоляция.
Скриншот: deny-all в редакторе

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: deny-all
namespace: yournamespacename
spec:
description: "Deny all traffic in this namespace"
endpointSelector: {}
ingress: [{}]
egress: [{}]
ingress: [{}] и egress: [{}] — пустые правила означают «ничего не разрешать».
Исходящий трафик к KubeDNS и NodeLocalDNS
Обязательно для подов, которые обращаются по имени (Service, FQDN):
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-dns
namespace: yournamespacename
spec:
description: "For endpoints in this namespace, allow egress to kube-dns and shturval-caching-dns"
endpointSelector: {}
egress:
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- port: "9153"
protocol: TCP
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
app.kubernetes.io/name: shturval-caching-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "9253"
protocol: TCP
Порт 9153 — метрики CoreDNS; 9253 — shturval-caching-dns. Без них DNS может работать нестабильно.
Исходящий трафик к определённому приложению
Разрешить подам в неймспейсе ходить только в конкретный backend:
Скриншот: allow-egress в редакторе

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-egress
namespace: frontend
spec:
description: "Allow egress to backend app only"
endpointSelector: {}
egress:
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: backend
app.kubernetes.io/name: api
toPorts:
- ports:
- port: "8080"
protocol: TCP
Замените backend, api, 8080 на реальные неймспейс, имя приложения и порт. Не забудьте добавить правило для DNS, если backend указывается по имени Service.
Входящий трафик из Ingress-контроллера
Обязательно для приложений, доступных извне через Ingress:
Скриншот: allow-ingress в редакторе

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-ingress
namespace: my-app
spec:
description: "Allow ingress from ingress-controller"
endpointSelector: {}
ingress:
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: shturval-ingress-controller
io.kubernetes.pod.namespace: ingress
Без этого правила запросы от пользователей не дойдут до подов приложения.
Трафик внутри неймспейса
Разрешить подам в неймспейсе общаться друг с другом:
Скриншот: allow-in-namespace в редакторе

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-in-namespace
namespace: my-app
spec:
description: "Allow all traffic within namespace"
endpointSelector: {}
ingress:
- fromEndpoints: [{}]
egress:
- toEndpoints: [{}]
fromEndpoints: [{}] и toEndpoints: [{}] — «любые поды в том же неймспейсе».
Полный пример: приложение с Ingress, DNS и внутренним API
Веб-приложение my-app в неймспейсе my-app: доступ извне через Ingress, внутри ходит в Redis по имени Service.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: my-app-full
namespace: my-app
spec:
description: "Web app: Ingress + DNS + Redis in same namespace"
endpointSelector: {}
ingress:
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: shturval-ingress-controller
io.kubernetes.pod.namespace: ingress
egress:
# DNS — обязательно
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- port: "9153"
protocol: TCP
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
app.kubernetes.io/name: shturval-caching-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "9253"
protocol: TCP
# Redis в том же неймспейсе
- toEndpoints:
- matchLabels:
app: redis
toPorts:
- ports:
- port: "6379"
protocol: TCP
Типичные ошибки
| Ошибка | Что происходит | Решение |
|---|---|---|
| Забыли разрешить DNS | Поды не резолвят имена, приложение не работает | Добавить egress к kube-dns и shturval-caching-dns |
| Забыли разрешить Ingress | Пользователи не могут зайти через браузер | Добавить ingress от shturval-ingress-controller |
| Указали только один порт DNS | Резолв может работать нестабильно | Добавить порты 53 (UDP/TCP), 9153, 9253 |
| Неправильные лейблы в matchLabels | Правило не срабатывает | Проверить kubectl get pod ... --show-labels |
| Применили deny-all без разрешающих правил | Всё заблокировано | Сначала добавить все нужные разрешения, потом при необходимости deny-all |
Проверка после настройки
- Поды запущены:
kubectl get pods -n <namespace> - Приложение отвечает:
curlили браузер по URL - Логи приложения:
kubectl logs -n <namespace> <pod> - Cilium: при проблемах — Траблшутинг
Подробнее о подходах к настройке — Справочная информация.