Уявіть: Redis без пароля, Postgres без TLS, а будь-який pod у кластері може до них достукатися. Після злому веб-застосунку атакуючий сканує внутрішню мережу та знаходить відкритий порт 6379. Без Kubernetes Network Policies це фінал. Стандартний кластер — flat-мережа: будь-який Pod бачить будь-який інший за IP. Але ми налаштовуємо політики ізоляції так, щоб трафік ходив лише за узгодженими маршрутами. Досвід нашої команди — 5+ років у DevOps та 40+ проєктів із впровадження K8s у продакшн. Наші інженери мають сертифікації CKA та CKS. Знижуємо поверхню атаки в середньому на 80%. Середня економія після впровадження — 300 000 гривень на рік. Середня вартість впровадження для кластера з 10 сервісів — 15 000 грн.
У цій статті ми розглянемо налаштування Kubernetes Network Policies для мережевої ізоляції, включаючи default deny, роботу з Calico та Cilium, Ingress та Egress політики, міжнеймспейсну взаємодію та налагодження NetworkPolicy. Network Policies дозволяють реалізувати мікросегментацію, що істотно підвищує безпеку кластера.
Чому default deny — єдиний безпечний підхід?
Правильна стратегія — заборонити все, потім явно дозволяти необхідне. Базова політика для namespace:
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---Після застосування кластер стає «глухим» — ні вхідних, ні вихідних з'єднань, окрім DNS. DNS обов'язково дозволяємо окремо (політика з Egress на порти 53 UDP/TCP у namespace kube-system), інакше поди не зможуть резолвити імена сервісів. У 95% проєктів ця політика — основа безпеки. Це основа мікросегментації, яка забезпечує безпеку кластера.
Роздільний трафік між подами: приклад api-service
Типовий сценарій: сервіс api приймає трафік лише від Ingress Controller та звертається до postgres і redis. Створюємо дві політики — на вхідний та вихідний трафік.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-service-ingress
namespace: production
spec:
podSelector:
matchLabels:
app: api-service
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- port: 8080
protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-service-egress
namespace: production
spec:
podSelector:
matchLabels:
app: api-service
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- port: 6379
Повний приклад політики для мікросервісу
Для production-кластера з 5 мікросервісами потрібно близько 10 політик. Кожна включає Ingress та Egress правила. Нижче шаблон для типового сервісу з БД та кешем:
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: service-a
namespace: production
spec:
podSelector:
matchLabels:
app: service-a
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- port: 3000
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- port: 6379
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
Важливий момент: у сучасних версіях Kubernetes namespaceSelector та podSelector в одному блоці from трактуються як AND. У старіших версіях — як OR. Перевірте версію вашого кластера, наприклад, kubectl version --short.
Міжнеймспейсна взаємодія: allow-prometheus-scrape
Наприклад, моніторинговий namespace повинен збирати метрики з подів у production. Створюємо дозвільну політику в namespace production:
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus-scrape
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
ports:
- port: 9090
protocol: TCP
Це приклад міжнеймспейсної взаємодії, яка часто потрібна для моніторингу.
Проблема healthcheck в Kubernetes
kubelet виконує health-перевірки в Kubernetes з IP вузла (node IP) до пода. Якщо політики блокують вхідний трафік від будь-яких джерел, kubelet не зможе виконати probe. Рішення — дозволити трафік від CIDR вузлів кластера:
ingress: - from: - ipBlock: cidr: 10.0.0.0/16 # CIDR нод кластера ports: - port: 8080 Це запобігає 95% проблем із healthcheck після впровадження політик.
Як налагоджувати Network Policies?
Складність у відсутності логів блокувань у самому Kubernetes. Використовуйте спеціалізовані інструменти:
- Calico:
calicoctl get policy -n productionпоказує розпарсені правила;calicoctl node diagsзбирає стан dataplane. - Cilium:
cilium monitor --type dropвідображає відкинуті пакети;hubble observe --namespace production --verdict DROPPEDдає статистику через Hubble UI. Cilium — один із найпродуктивніших CNI з eBPF.
Без утиліт: запустіть pod з образом nicolaka/netshoot та перевіряйте nc -zv postgres 5432. Середній час налагодження однієї політики — 30 хвилин.
Порівняння CNI-плагінів для Network Policies
| Плагін | Підтримка | Продуктивність | Спостережуваність |
|---|---|---|---|
| Flannel | Ні (без доп.) | Висока | Низька |
| Calico | Повна | Середня-висока | Середня (Felix) |
| Cilium | Повна | Висока (eBPF) | Висока (Hubble) |
| Weave Net | Повна | Середня | Середня |
Cilium у 2-3 рази швидший за Calico при фільтрації на рівні L7 завдяки eBPF. Cilium забезпечує в 2 рази кращу спостережуваність, ніж Calico, завдяки Hubble. Для більшості продакшн-сценаріїв Calico достатньо, але якщо потрібна глибока спостережуваність та висока продуктивність — обирайте Cilium. Flannel без доповнень не підтримує політики, тому не розглядайте його для ізоляції.
Покрокове налаштування Network Policy
- Аудит поточної мережевої топології та моделі безпеки — визначте namespace та сервіси.
- Проектування політик на основі потоків: Ingress від Ingress-контролера, Egress до баз даних.
- Розробка маніфестів із покриттям усіх критичних потоків (не забувайте DNS!).
- Тестування на staging-оточенні — перевірте healthcheck, dns, та роботу застосунків.
- Документування кожної політики та схеми ізоляції для команди експлуатації.
Типові проблеми та помилки Network Policies
| Проблема | Причина | Рішення |
|---|---|---|
| Healthcheck не проходить | Блокування трафіку від вузлів | Додати ipBlock для CIDR нод |
| DNS не резолвиться | Немає Egress-правила для DNS | Дозволити порти 53 UDP/TCP у kube-system |
| Трафік між подами не йде | Неправильний podSelector | Перевірити мітки подів та правила |
| Реплікація StatefulSet зламана | Блокування трафіку між репліками | Дозволити Egress від подів з тим самим селектором |
Найчастіше (у 95% випадків) блокується healthcheck — завжди додавайте ipBlock для вузлів. Також забувають про Egress до DNS та реплікацію між репліками StatefulSet. Використовуйте kubectl describe networkpolicy для перевірки.
Що входить у роботу
- Аудит поточної мережевої топології та моделі загроз.
- Проектування політик ізоляції під ваш стек (Calico/Cilium).
- Написання та застосування маніфестів (default deny + дозвільні правила).
- Тестування всіх критичних потоків (healthcheck, DNS, моніторинг).
- Документація схеми ізоляції та runbook для операційної команди.
- Навчання інженерів роботі з політиками (2-годинний workshop).
Вартість типового проекту визначається після аналізу складності та кількості сервісів.
Строки виконання
- Простий кластер (3-5 сервісів в одному namespace) — 1-2 дні.
- Складна топологія з міжнеймспейсною взаємодією — до 3 днів.
- Повний аудит та впровадження в продакшн (включно з документацією) — від 4 днів.
Наш досвід — 5+ років та 40+ проєктів — гарантія якісного налаштування Network Policies. Усі роботи виконують сертифіковані інженери. Зверніться до наших інженерів для аудиту вашого кластера — розрахуємо строки та обсяг робіт під ваш проект. Замовте впровадження Network Policies під ключ: забезпечимо безпеку без простоїв.
Джерело: Kubernetes Documentation







