Сетевая политика K8s Cilium eBPF: 5 ключевых паттернов для Zero-Trust безопасности подов
Сетевые технологии Kubernetes в 2026 году полностью вошли в эру eBPF. Cilium, как проект CNCF уровня «Graduated», стал де-факто стандартом для Zero-Trust безопасности подов благодаря своим программируемым сетевым возможностям на уровне ядра. От традиционных iptables до dataplane eBPF, от сетевых политик L3/L4 до фильтрации на прикладном уровне L7, от одного кластера до межкластерной сети Cluster Mesh — Cilium переопределяет границы облачной сети. Эта статья глубоко погружается в 5 ключевых паттернов эксплуатации, проводя вас от установки до production-развёртывания и помогая полностью освоить сетевые политики Cilium eBPF.
Ключевые концепции
| Концепция | Описание | Традиционное сравнение |
|---|---|---|
| eBPF | Программируемая песочница ядра, расширяющая сеть без изменения исходного кода ядра | цепочки правил iptables, соответствие O(n) по мере роста правил |
| Cilium | CNI-плагин K8s на базе eBPF, обеспечивающий сеть, безопасность, наблюдаемость | Calico/Flannel, только политики L3/L4 |
| Identity Label | Метка безопасности на основе Labels, а не IP-адресов | сетевая политика на основе IP |
| L7 Policy | Фильтрация на прикладном уровне HTTP/gRPC, точная до путей API | только фильтрация на уровне портов L4 |
| Cluster Mesh | Межкластерная сетевая взаимосвязь, прямая связь между подами кластеров | передача через VPN/шлюз |
| Hubble | Платформа наблюдаемости сети Cilium, визуализация трафика в реальном времени | ручной захват пакетов tcpdump/Wireshark |
Анализ проблем: 5 болевых точек традиционных сетевых политик K8s
Болевая точка 1: узкое место производительности iptables — В крупных кластерах правила iptables могут достигать десятков тысяч. Каждое изменение правила вызывает полную замену, вызывая сильную нестабильность сетевой задержки.
Болевая точка 2: недостаточная детализация политик L3/L4 — Нативная NetworkPolicy может контролировать доступ только на уровне портов, не умея различать GET /api/users и DELETE /api/users.
Болевая точка 3: хрупкие политики безопасности на основе IP — IP-адреса подов меняются после пересоздания, IP-правила брандмауэра мгновенно становятся недействительными, делая Zero-Trust невозможным.
Болевая точка 4: фрагментированная межкластерная сеть — Межкластерная связь сервисов опирается на передачу через Ingress/шлюз, с высокой задержкой и трудной унификацией политик.
Болевая точка 5: чёрный ящик при диагностике сети — Сбои связи между подами можно диагностировать только шаг за шагом через tcpdump, без сквозной визуализации трафика.
Паттерн 1: Установка Cilium и принципы сети eBPF
Принципы сети eBPF
Программы eBPF прикрепляются к сетевым хукам ядра (xdp, tc, cgroup и т.д.), обрабатывая пакеты до того, как они достигнут стека протоколов, избегая накладных расходов на обход цепочек правил iptables:
Packet In → XDP(eBPF) → tc ingress(eBPF) → Protocol Stack → tc egress(eBPF) → Out
↓ ↓ ↓
DDoS Protection Policy Match/Routing Policy Match/NAT
Установка через Helm (замена kube-proxy)
# cilium-values.yaml
# Cilium Helm installation config, kube-proxy replacement mode
kubeProxyReplacement: true
operator:
replicas: 2
# eBPF map sizes (large-scale cluster tuning)
bpf:
mapDynamicSizeRatio: 0.0025
lbMapMax: 65536
ctMapMax: 524288
# Auto-detect node networking
autoDirectNodeRoutes: true
tunnel: vxlan
# Identity allocation mode
identityAllocationMode: kvstore
# Monitoring and observability
hubble:
enabled: true
listenAddress: ":4244"
metrics:
enabled:
- dns
- drop
- tcp
- flow
- port-distribution
- http
relay:
enabled: true
replicas: 2
ui:
enabled: true
# Resource limits
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
# Security context
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_MODULE
#!/bin/bash
# install-cilium.sh
# Cilium installation script
set -euo pipefail
CLUSTER_NAME="prod-cluster"
NAMESPACE="kube-system"
echo "=== Step 1: Add Cilium Helm repository ==="
helm repo add cilium https://helm.cilium.io/
helm repo update
echo "=== Step 2: Get API Server address ==="
API_SERVER_IP=$(kubectl get endpoints kubernetes -o jsonpath='{.subsets[0].addresses[0].ip}')
API_SERVER_PORT=$(kubectl get endpoints kubernetes -o jsonpath='{.subsets[0].ports[0].port}')
echo "API Server: ${API_SERVER_IP}:${API_SERVER_PORT}"
echo "=== Step 3: Install Cilium ==="
helm install cilium cilium/cilium \
--namespace ${NAMESPACE} \
--values cilium-values.yaml \
--set kubeProxyReplacement=true \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--wait
echo "=== Step 4: Wait for Cilium readiness ==="
kubectl -n ${NAMESPACE} rollout status ds/cilium --timeout=300s
kubectl -n ${NAMESPACE} rollout status deploy/cilium-operator --timeout=120s
echo "=== Step 5: Verify eBPF program loading ==="
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium bpf lb list
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium status
echo "=== Step 6: Verify kube-proxy replacement ==="
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium service list
echo "=== Step 7: Status check ==="
cilium status --wait
echo "✅ Cilium installation complete!"
Проверка dataplane eBPF
#!/bin/bash
# verify-ebpf.sh
# Verify eBPF dataplane is working correctly
echo "=== Check Cilium eBPF programs ==="
kubectl -n kube-system exec ds/cilium -- cilium bpf tunnel list
kubectl -n kube-system exec ds/cilium -- cilium bpf ct list global
echo "=== Check identity mapping ==="
kubectl -n kube-system exec ds/cilium -- cilium identity list
echo "=== Network connectivity test ==="
kubectl run test-net --image=cilium/cilium:latest --restart=Never -- sleep infinity
kubectl exec test-net -- curl -s https://kubernetes.default.svc.cluster.local:443/api/v1/namespaces
echo "=== Bandwidth benchmark ==="
kubectl run iperf3-server --image=networkstatic/iperf3 --restart=Never -- iperf3 -s
kubectl run iperf3-client --image=networkstatic/iperf3 --restart=Never -- sleep infinity
CLIENT_POD=$(kubectl get pods -l run=iperf3-client -o jsonpath='{.items[0].metadata.name}')
SERVER_IP=$(kubectl get pod iperf3-server -o jsonpath='{.status.podIP}')
kubectl exec ${CLIENT_POD} -- iperf3 -c ${SERVER_IP} -t 10 -P 4
echo "✅ eBPF dataplane verification complete!"
Паттерн 2: Сетевые политики L3/L4 и метки идентичности
Механизм меток идентичности Cilium
Cilium использует Labels для вычисления идентификаторов безопасности (Identity), а не полагается на IP-адреса. Поды с одинаковыми Labels разделяют одну Identity, и сопоставление политик основано на Identity, а не на IP:
Pod(app=api, env=prod) → Identity: 1001 → Policy allows Identity:1001 → Identity:2001
Pod(app=web, env=prod) → Identity: 2001
Базовые сетевые политики L3/L4
# cilium-l3-l4-policy.yaml
# L3/L4 network policy: Zero-trust access control based on identity labels
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: api-server-policy
namespace: production
spec:
description: "API service only allows frontend and internal service access, denies all other traffic"
endpointSelector:
matchLabels:
app: api-server
env: production
ingress:
# Rule 1: Allow frontend Pods to access API port 8080
- fromEndpoints:
- matchLabels:
app: web-frontend
env: production
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/v1/.*"
- method: POST
path: "/api/v1/.*"
# Rule 2: Allow internal microservices to access gRPC port
- fromEndpoints:
- matchLabels:
app: internal-service
env: production
toPorts:
- ports:
- port: "9090"
protocol: TCP
# Rule 3: Allow Prometheus monitoring scrape
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: prometheus
toPorts:
- ports:
- port: "9090"
protocol: TCP
endPort: 9091
egress:
# Allow database access
- toEndpoints:
- matchLabels:
app: postgres
env: production
toPorts:
- ports:
- port: "5432"
protocol: TCP
# Allow DNS resolution
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
# Allow external API calls
- toFQDNs:
- matchName: "api.stripe.com"
- matchPattern: "*.amazonaws.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
---
# Default deny policy (zero-trust foundation)
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny-all
spec:
description: "Default deny all ingress traffic, zero-trust baseline policy"
endpointSelector: {}
ingressDeny:
- fromRequires:
- {}
---
# Namespace isolation policy
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: namespace-isolation
spec:
description: "Namespace-level isolation, only allow same-namespace communication"
endpointSelector:
matchLabels: {}
ingress:
- fromEndpoints:
- matchLabels: {}
Сетевые политики на основе сущностей
# entity-based-policy.yaml
# Entity-based network policy: Control intra-cluster and external traffic
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: entity-policy
spec:
description: "Control network access between Pods and cluster entities"
endpointSelector:
matchLabels:
app: api-server
ingress:
# Allow traffic from within the cluster
- fromEntities:
- cluster
- host
- remote-node
egress:
# Allow access to outside the cluster
- toEntities:
- world
# Allow access to K8s API Server
- toEntities:
- kube-apiserver
Паттерн 3: Политики прикладного уровня L7 (фильтрация HTTP/gRPC)
Точный контроль доступа на уровне HTTP
# cilium-l7-policy.yaml
# L7 application-layer policy: HTTP/gRPC fine-grained filtering
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-api-policy
namespace: production
spec:
description: "L7 policy: HTTP method + path precise control, implementing API-level zero-trust"
endpointSelector:
matchLabels:
app: api-server
env: production
ingress:
- fromEndpoints:
- matchLabels:
app: web-frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
# Allow read-only APIs
- method: GET
path: "/api/v1/users(/.*)?"
- method: GET
path: "/api/v1/products(/.*)?"
- method: GET
path: "/api/v1/orders(/.*)?"
# Allow order creation
- method: POST
path: "/api/v1/orders"
# Deny delete operations (requests not in this list will be denied)
---
# gRPC method-level filtering
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: grpc-policy
namespace: production
spec:
description: "gRPC method-level access control"
endpointSelector:
matchLabels:
app: order-service
ingress:
- fromEndpoints:
- matchLabels:
app: api-gateway
toPorts:
- ports:
- port: "50051"
protocol: TCP
rules:
http:
- method: POST
path: "/order.OrderService/GetOrder"
- method: POST
path: "/order.OrderService/ListOrders"
- method: POST
path: "/order.OrderService/CreateOrder"
---
# HTTP Header filtering policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: header-filter-policy
namespace: production
spec:
description: "HTTP Header-based access control"
endpointSelector:
matchLabels:
app: internal-api
ingress:
- fromEndpoints:
- matchLabels:
app: gateway
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/internal/.*"
headers:
- "X-Internal-Token: ^secret-token-.*$"
---
# Kafka protocol-aware policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: kafka-policy
namespace: production
spec:
description: "Kafka topic-level access control"
endpointSelector:
matchLabels:
app: kafka-broker
ingress:
- fromEndpoints:
- matchLabels:
app: order-processor
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- role: produce
topic: orders
- role: consume
topic: orders
- fromEndpoints:
- matchLabels:
app: analytics
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- role: consume
topic: orders
Скрипт проверки политик L7
#!/bin/bash
# verify-l7-policy.sh
# Verify L7 application-layer policies
echo "=== Test HTTP GET allowed ==="
kubectl exec deploy/web-frontend -- curl -s -o /dev/null -w "%{http_code}" http://api-server:8080/api/v1/users
# Expected: 200
echo ""
echo "=== Test HTTP DELETE denied ==="
kubectl exec deploy/web-frontend -- curl -s -o /dev/null -w "%{http_code}" -X DELETE http://api-server:8080/api/v1/users/123
# Expected: 403
echo ""
echo "=== Test access without Header denied ==="
kubectl exec deploy/gateway -- curl -s -o /dev/null -w "%{http_code}" http://internal-api:8080/internal/config
# Expected: 403
echo ""
echo "=== Test access with Token Header allowed ==="
kubectl exec deploy/gateway -- curl -s -o /dev/null -w "%{http_code}" -H "X-Internal-Token: secret-token-abc" http://internal-api:8080/internal/config
# Expected: 200
echo ""
echo "=== Check Cilium L7 policy status ==="
kubectl -n kube-system exec ds/cilium -- cilium policy get
kubectl -n kube-system exec ds/cilium -- cilium policy select
echo "✅ L7 policy verification complete!"
Паттерн 4: Межкластерная сеть Cluster Mesh
Архитектура Cluster Mesh
Cluster A (us-west) Cluster B (eu-central)
┌─────────────────┐ ┌─────────────────┐
│ Pod: api-server │◄────────►│ Pod: api-server │
│ Identity: 1001 │ │ Identity: 1001 │
│ Service: global │ │ Service: global │
└─────────────────┘ └─────────────────┘
│ │
└──────── etcd sync ─────────┘
Конфигурация Cluster Mesh
# cluster-mesh-config.yaml
# Cluster Mesh multi-cluster network configuration
# Cluster A: us-west
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-clustermesh
namespace: kube-system
data:
cluster-id: "1"
cluster-name: "us-west"
---
# Cluster B: eu-central
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-clustermesh
namespace: kube-system
data:
cluster-id: "2"
cluster-name: "eu-central"
---
# Global Service (cross-cluster load balancing)
apiVersion: v1
kind: Service
metadata:
name: global-api-server
namespace: production
annotations:
service.cilium.io/global: "true"
service.cilium.io/affinity: "local"
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
selector:
app: api-server
---
# Cross-cluster network policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: cross-cluster-policy
namespace: production
spec:
description: "Cross-cluster network policy: Allow us-west and eu-central mutual access"
endpointSelector:
matchLabels:
app: api-server
ingress:
- fromEndpoints:
- matchLabels:
app: api-server
io.cilium.k8s.policy.cluster: us-west
- matchLabels:
app: api-server
io.cilium.k8s.policy.cluster: eu-central
toPorts:
- ports:
- port: "8080"
protocol: TCP
#!/bin/bash
# setup-cluster-mesh.sh
# Cluster Mesh setup script
set -euo pipefail
CLUSTER_A="us-west"
CLUSTER_B="eu-central"
CONTEXT_A="kind-${CLUSTER_A}"
CONTEXT_B="kind-${CLUSTER_B}"
echo "=== Step 1: Enable Cluster Mesh on both clusters ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
cilium clustermesh enable --cluster-id 1 --cluster-name ${CLUSTER_A}
kubectl --context ${CONTEXT_B} -n kube-system exec ds/cilium -- \
cilium clustermesh enable --cluster-id 2 --cluster-name ${CLUSTER_B}
echo "=== Step 2: Wait for Cluster Mesh API readiness ==="
kubectl --context ${CONTEXT_A} -n kube-system rollout status deploy/clustermesh-apiserver --timeout=120s
kubectl --context ${CONTEXT_B} -n kube-system rollout status deploy/clustermesh-apiserver --timeout=120s
echo "=== Step 3: Connect the two clusters ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
cilium clustermesh connect --destination-context ${CONTEXT_B}
echo "=== Step 4: Verify cluster connection status ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
cilium clustermesh status
kubectl --context ${CONTEXT_B} -n kube-system exec ds/cilium -- \
cilium clustermesh status
echo "=== Step 5: Test cross-cluster service discovery ==="
kubectl --context ${CONTEXT_A} run test-cross-cluster \
--image=cilium/cilium:latest --restart=Never -- \
curl -s http://global-api-server.production.svc.cluster.local:8080/health
echo "=== Step 6: Verify global Service ==="
kubectl --context ${CONTEXT_A} get svc global-api-server -n production -o yaml
kubectl --context ${CONTEXT_B} get svc global-api-server -n production -o yaml
echo "✅ Cluster Mesh setup complete!"
Тестирование межкластерного отказоустойчивого переключения
#!/bin/bash
# test-cross-cluster-failover.sh
# Cross-cluster failover testing
CLUSTER_A="us-west"
CLUSTER_B="eu-central"
CONTEXT_A="kind-${CLUSTER_A}"
CONTEXT_B="kind-${CLUSTER_B}"
echo "=== Baseline test: Normal cross-cluster access ==="
for i in $(seq 1 10); do
RESULT=$(kubectl --context ${CONTEXT_A} exec deploy/test-client -- \
curl -s http://global-api-server.production.svc.cluster.local:8080/cluster-name)
echo "Request ${i}: ${RESULT}"
done
echo ""
echo "=== Simulate cluster B failure ==="
kubectl --context ${CONTEXT_B} scale deploy api-server -n production --replicas=0
echo "=== Verify traffic auto-switches to cluster A ==="
for i in $(seq 1 10); do
RESULT=$(kubectl --context ${CONTEXT_A} exec deploy/test-client -- \
curl -s http://global-api-server.production.svc.cluster.local:8080/cluster-name)
echo "Failover Request ${i}: ${RESULT}"
done
echo "=== Restore cluster B ==="
kubectl --context ${CONTEXT_B} scale deploy api-server -n production --replicas=3
echo "✅ Failover testing complete!"
Паттерн 5: Наблюдаемость Hubble и трассировка сети
Развёртывание и конфигурация Hubble
# hubble-values.yaml
# Hubble observability configuration
hubble:
enabled: true
listenAddress: ":4244"
metrics:
enabled:
- dns:query
- drop
- tcp
- flow
- port-distribution
- http:method;path;status
- icmp
serviceMonitor:
enabled: true
dashboards:
enabled: true
namespace: monitoring
relay:
enabled: true
replicas: 2
rollOutPods: true
ui:
enabled: true
replicas: 1
rollOutPods: true
ingress:
enabled: true
className: nginx
hosts:
- hubble.example.com
tls:
secretName: hubble-tls
Трассировка сети через Hubble CLI
#!/bin/bash
# hubble-observability.sh
# Hubble observability and network tracing
echo "=== Real-time traffic monitoring ==="
hubble observe --since 1m --output json | jq -r '
select(.source.namespace == "production") |
"\(.timestamp) \(.source.pod_name) → \(.destination.pod_name) \(.event.type) \(.l7.protocol // "L4") \(.l7.method // "") \(.l7.path // "") \(.response_status // "")"
'
echo ""
echo "=== Trace traffic for a specific Pod ==="
hubble observe --pod api-server-7d9f8b6c4-x2k1p --since 5m
echo ""
echo "=== Detect denied traffic ==="
hubble observe --since 10m --type trace --verdict DROPPED | head -50
echo ""
echo "=== HTTP traffic analysis ==="
hubble observe --since 5m --protocol http --output json | jq -r '
"\(.source.pod_name) → \(.destination.pod_name) [\(.l7.method)] \(.l7.path) → \(.l7.response_code)"
' | sort | uniq -c | sort -rn | head -20
echo ""
echo "=== DNS query monitoring ==="
hubble observe --since 5m --protocol dns --output json | jq -r '
"\(.source.pod_name) → \(.l7.dns.query) \(.l7.dns.rcode // "OK")"
' | sort | uniq -c | sort -rn | head -20
echo ""
echo "=== Network latency analysis ==="
hubble observe --since 5m --type trace --output json | jq -r '
select(.latency_ns != null) |
"\(.source.pod_name) → \(.destination.pod_name) latency: \(.latency_ns / 1000000)ms"
' | sort -t: -k2 -n | tail -20
echo "✅ Hubble observability analysis complete!"
Метрики Hubble Prometheus
# hubble-prometheus-rules.yaml
# Hubble alerting rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: hubble-alerts
namespace: monitoring
spec:
groups:
- name: hubble-network
rules:
# High drop rate alert
- alert: CiliumHighDropRate
expr: |
rate(hubble_drop_total{verdict="DROPPED"}[5m]) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "Cilium detected high drop rate"
description: "Pod {{ $labels.source_pod }} in namespace {{ $labels.namespace }} drop rate exceeds 10/s"
# DNS resolution failure alert
- alert: CiliumDNSFailures
expr: |
rate(hubble_dns_responses_total{rcode="NXDOMAIN"}[5m]) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "Abnormal DNS resolution failure rate"
description: "DNS NXDOMAIN responses in namespace {{ $labels.namespace }} exceed 5/s"
# TCP connection reset alert
- alert: CiliumTCPResets
expr: |
rate(hubble_tcp_flags_total{flag="RST"}[5m]) > 50
for: 5m
labels:
severity: critical
annotations:
summary: "Abnormal TCP RST packets"
description: "TCP RST packets in namespace {{ $labels.namespace }} exceed 50/s"
# Cross-cluster latency alert
- alert: CiliumCrossClusterLatency
expr: |
histogram_quantile(0.99, rate(hubble_flows_processed_duration_seconds_bucket{source_cluster!=""}[5m])) > 0.5
for: 10m
labels:
severity: warning
annotations:
summary: "High cross-cluster network latency"
description: "P99 latency exceeds 500ms"
Руководство по подводным камням
Подводный камень 1: Поды не могут связаться после установки Cilium
# ❌ Wrong: Incorrect tunnel mode configuration, incompatible node networking
tunnel: disabled
autoDirectNodeRoutes: false
# ✅ Correct: Choose tunnel mode based on network environment
# Cloud environment (VPC supports routing)
tunnel: disabled
autoDirectNodeRoutes: true
directRoutingSkipUnreachable: true
# General environment (VXLAN overlay)
tunnel: vxlan
tunnelPort: 8473
Подводный камень 2: Политики L7 не вступают в силу
# ❌ Wrong: L7 policy missing toPorts definition, Cilium cannot inject proxy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: bad-l7-policy
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
rules:
http:
- method: GET
path: "/api/.*"
# ✅ Correct: L7 rules must be defined under toPorts
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: good-l7-policy
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/.*"
Подводный камень 3: Сбой подключения Cluster Mesh
# ❌ Wrong: etcd certificates not properly synced
cilium clustermesh connect --destination-context other-cluster
# ✅ Correct: Ensure etcd certificates are correct first, then connect
# Check Cluster Mesh API Server status
kubectl -n kube-system get deploy/clustermesh-apiserver
kubectl -n kube-system logs deploy/clustermesh-apiserver
# Ensure certificate Secrets exist
kubectl -n kube-system get secret clustermesh-apiserver-server-certs
kubectl -n kube-system get secret clustermesh-apiserver-remote-certs
# Use the correct connection method
cilium clustermesh connect \
--destination-context other-cluster \
--destination-name other-cluster
Подводный камень 4: UI Hubble не показывает трафик
# ❌ Wrong: Hubble Relay cannot connect to Cilium Agent
hubble:
relay:
enabled: true
# Missing dialTimeout config causing timeout
# ✅ Correct: Configure Hubble Relay timeout and retry
hubble:
relay:
enabled: true
dialTimeout: "5s"
retryTimeout: "30s"
maxFlows: 10000
sortBufferLenMax: 1000
sortBufferFlushInterval: "1s"
port: 4245
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
Подводный камень 5: Сбой загрузки программы eBPF
# ❌ Wrong: Incompatible kernel version, installing directly
helm install cilium cilium/cilium
# ✅ Correct: Check kernel compatibility first
# Check kernel version (need >= 5.4, recommended >= 5.10)
uname -r
# Check eBPF feature support
kubectl -n kube-system exec ds/cilium -- cilium-dbg features
# If kernel version is low, enable compatibility mode
helm install cilium cilium/cilium \
--set bpf.preallocateMaps=false \
--set bpf.tproxy=false \
--set hostFirewall.enabled=false
# Check eBPF program loading status
kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf lb list
kubectl -n kube-system exec ds/cilium -- cilium-dbg status
Таблица устранения ошибок
| Симптом ошибки | Возможная причина | Диагностическая команда | Решение |
|---|---|---|---|
| Поды не могут связаться между узлами | Неправильная настройка туннеля | cilium bpf tunnel list |
Проверьте режим туннеля, убедитесь, что порт VXLAN 8473 открыт |
| Pod Cilium CrashLoopBackOff | Несовместимая версия ядра | dmesg | grep -i bpf |
Обновите ядро до 5.10+ или включите режим совместимости |
| Политики L7 неэффективны | Отсутствует определение toPorts | cilium policy get |
Правила L7 должны быть вложены в toPorts.ports.rules |
| Тайм-аут подключения Cluster Mesh | Истёк сертификат etcd | kubectl logs -n kube-system deploy/clustermesh-apiserver |
Перегенерируйте сертификаты: cilium clustermesh enable |
| Hubble не показывает данные трафика | Relay не может подключиться к агенту | kubectl logs -n kube-system deploy/hubble-relay |
Проверьте dialTimeout и порт агента 4244 |
| Сбой разрешения DNS | Аномальный eBPF DNS-прокси | cilium bpf ct list global | grep 53 |
Проверьте DNS-политику, убедитесь, что метки kube-dns корректны |
| Всплеск сетевой задержки | Карта eBPF заполнена | cilium bpf ct list global | wc -l |
Увеличьте ctMapMax, включите GC |
| Сервис недоступен | Остаточный конфликт kube-proxy | iptables -L -n | grep KUBE |
Тщательно очистите правила iptables, подтвердите удаление kube-proxy |
| Конфликт выделения идентичности | Аномальный бэкенд KVStore | cilium identity list |
Проверьте подключение etcd, перезапустите cilium-operator |
| Под кластера недоступен | Global Service не настроен | kubectl get svc -o yaml | grep global |
Добавьте аннотацию service.cilium.io/global: "true" |
Расширенная оптимизация
1. Настройка карт eBPF
# Large-scale cluster eBPF Map configuration
bpf:
mapDynamicSizeRatio: 0.0025
ctMapMax: 524288 # Connection tracking table
ctTcpMax: 262144 # TCP connection tracking
ctAnyMax: 262144 # Non-TCP connection tracking
lbMapMax: 65536 # Load balancing map
lbServiceMapMax: 65536
lbBackendMapMax: 65536
natMapMax: 524288 # NAT map
neighMapMax: 524288 # Neighbor table
policyMapMax: 16384 # Policy map
fragmentsMapMax: 8192 # Fragment map
2. Управление полосой пропускания (EDT)
# eBPF-based bandwidth management
bandwidthManager:
enabled: true
bbr: true # Enable BBR congestion control
# Set bandwidth limits for Pods
kubectl annotate pod api-server-xxx \
kubernetes.io/egress-bandwidth=100M \
kubernetes.io/ingress-bandwidth=100M
3. Оптимизация Big TCP
# Large-scale TCP optimization (kernel 5.19+)
bpf:
tcpRto: 100ms # TCP retransmission timeout
tproxy: true
kubeProxyReplacement:
true
hostPort:
enabled: true
externalIPs:
enabled: true
nodePort:
enabled: true
hostLegacyRouting:
enabled: false
4. Маршрутизация хоста eBPF
# Host routing optimization
bpf:
hostLegacyRouting: false # Use eBPF instead of host routing
lbExternalClusterIP: true
autoDirectNodeRoutes: true
5. Усиление безопасности
# Cilium security hardening configuration
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_MODULE
drop:
- ALL
seccompProfile:
type: RuntimeDefault
readOnlyRootFilesystem: true
# Enable encryption
encryption:
enabled: true
type: wireguard
nodeEncryption: true
Сравнительная таблица
| Функция | Cilium eBPF | Calico | Flannel | Weave |
|---|---|---|---|---|
| Dataplane | eBPF | iptables/eBPF | VXLAN | VXLAN |
| Политики L3/L4 | ✅ | ✅ | ❌ | ❌ |
| Политики L7 | ✅ HTTP/gRPC/Kafka | ❌ | ❌ | ❌ |
| Наблюдаемость | ✅ Hubble | ❌ | ❌ | ❌ |
| Cluster Mesh | ✅ | ❌ | ❌ | ❌ |
| Замена kube-proxy | ✅ | ❌ | ❌ | ❌ |
| Управление полосой пропускания | ✅ EDT/BBR | ❌ | ❌ | ❌ |
| Шифрование WireGuard | ✅ | ✅ | ❌ | ✅ |
| Политики FQDN | ✅ | ❌ | ❌ | ❌ |
| Производительность в большом масштабе | O(1) | O(n) | O(n) | O(n) |
| Требование к ядру | ≥5.4 | ≥4.9 | ≥3.10 | ≥3.10 |
💡 Резюме: Сетевые политики Cilium eBPF представляют будущее направление безопасности сети K8s. От меток идентичности L3/L4 до фильтрации на прикладном уровне L7, от Zero-Trust в одном кластере до межкластерной взаимосвязи Cluster Mesh, от наблюдаемости реального времени Hubble до оптимизации производительности eBPF — 5 ключевых паттернов строят полноценную систему облачной сетевой безопасности. Помните: Zero-Trust — это не продукт, а архитектурная философия, и Cilium — лучший инструмент для её реализации.
Рекомендация инструментов онлайн
- JSON Formatter — Форматировать вывод JSON политик Cilium, устранять неполадки конфигураций политик
- cURL to Code — Преобразовать запросы API Hubble в код, интегрировать наблюдаемость
- Hash Calculator — Вычислить хеши подписей политик, проверить целостность конфигурации
Попробуйте эти локальные браузерные инструменты — регистрация не требуется →