Rețea Kubernetes: CNI, Cilium cu eBPF și Politică de rețea
Kubernetes abstractizează rețeaua într-un mod magistral: fiecare Pod primește o adresă IP rutabilă, containerele din același Pod partajează spațiul de nume de rețea, iar Pod-urile pot comunica între ei pe orice nod fără NAT. Cu toate acestea, aparenta simplitate se ascunde o reală complexitate: cum funcționează de fapt acest model? Cu cine se ocupa atribui IP-uri, direcționează traficul între noduri, implementează politici de rețea?
Răspunsul constă în Interfață de rețea de containere (CNI), un standard care definește modul în care pluginurile de rețea ar trebui să se integreze cu Kubernetes. În acest articol vom explora modelul de rețea Kubernetes din interior: cum funcționează kube-proxy, de ce Cilium cu eBPF înlocuiește soluțiile tradiționale și cum implementați Politica de rețea pentru a izola sarcinile de lucru din clusterele de producție.
Ce vei învăța
- Modelul de rețea Kubernetes: IP-per-Pod, rețea plată, fără NAT
- Cum funcționează Container Network Interface (CNI) și principalele sale pluginuri
- Diferența dintre kube-proxy (iptables/IPVS) și Cilium cu eBPF
- Deoarece eBPF aduce -30% latență și +60% throughput comparativ cu iptables
- Cum se instalează și se configurează Cilium ca CNI
- Politica de rețea: sintaxă, exemple practice, refuz implicit și izolarea spațiului de nume
- CiliumNetworkPolicy pentru regulile de nivel 7 (HTTP, gRPC, Kafka)
Modelul de rețea Kubernetes
Kubernetes impune un model de rețea cu patru cerințe fundamentale Implementarea CNI trebuie să respecte:
- Toate podurile pot comunica cu toate celelalte poduri fără NAT
- Toate nodurile pot comunica cu toate podurile fără NAT
- IP-ul pe care un Pod îl vede ca fiind propriu și același IP pe care îl folosesc alții pentru a-l ajunge
- Containerele dintr-un Pod partajează spații de nume de rețea și IP-uri
Acest „model de rețea plat” simplifică foarte mult raționamentul aplicației: a microservice nu trebuie să știe dacă serviciul pe care îl apelează este pe același nod sau pe un nod telecomanda. Complexitatea este mutată la nivelul rețelei cluster.
Cum funcționează comunicarea între poduri
Când un Pod A dorește să comunice cu un Pod B pe diferite noduri, fluxul tipic este Urmează o soluție bazată pe rețea suprapusă (de exemplu, VXLAN):
- Pachetul iese din containerul Pod A prin interfață
eth0 - Introduceți spațiul de nume al nodului prin a
veth pair - Pluginul CNI îl interceptează și îl încapsulează în VXLAN (sau GRE, Geneve...)
- Pachetul traversează rețeaua fizică către nodul Pod B
- CNI-ul de pe nodul destinație dezcapsulează pachetul
- Pachetul ajunge la Pod B prin perechea a vecea
Cu soluții bazate pe BGP sau rutare nativă (cum ar fi Cilium în modul de rutare nativ), încapsularea nu este necesară și performanța se îmbunătățește semnificativ.
Interfață de rețea de containere (CNI)
CNI este o specificație CNCF care definește modul în care ar trebui să invoce timpii de rulare a containerului pluginuri de rețea. Kubernetes folosește CNI pentru a delega gestionarea rețelei pluginurilor: când kubelet creează un Pod, apelează pluginul CNI configurat pentru a aloca adresa IP și configurați interfața de rețea.
Pluginuri CNI principale
| Pluginuri | Tehnologie | Politica de rețea | Politica L7 | Caz de utilizare |
|---|---|---|---|---|
| Flanel | Suprapunere VXLAN | Nu (nativ) | No | Dezvoltare, clustere simple |
| Stambă | BGP/suprapunere | Si | No | On-premise, performanță |
| Cilium | eBPF | Si | Da (HTTP, gRPC) | Productie, service plasa |
| AWS VPC CNI | nativ ENI | Da (SG) | No | EKS |
| Azure CNI | Rețea virtuală nativă | Da (NSG) | No | AKS |
kube-proxy: Vechea abordare
kube-proxy este componenta Kubernetes responsabilă de implementarea Serviciilor: când un client apelează un serviciu, kube-proxy se asigură că traficul ajunge la unul dintre Backend pod. Utilizează în mod tradițional iptables în acest scop.
Problema cu iptables este că complexitatea crește liniar cu numărul de reguli. Într-un cluster cu 10.000 de servicii și 100.000 de puncte finale, iptables gestionează milioane de reguli. Fiecare pachet trebuie să treacă prin acest lanț de reguli, cu impact semnificativ asupra latenței și CPU-ului nodului.
Alternativa în arbore e IPVS (Server virtual IP), care utilizează un tabel hash pentru căutarea O(1) în loc de scanare liniară iptables. Dar IPVS are și limitări: Nu acceptă politici avansate și necesită în continuare gestionarea regulilor iptables suplimentare.
Problemă de scalare iptables
Cu 10.000 de Servicii, kube-proxy cu iptables creează aproximativ 40.000 de reguli numai pentru Servicii. Timpul de actualizare a acestor reguli crește de la milisecunde la minute. Grupate mare, acest lucru duce la latențe mari în timpul evenimentelor de scalare și a actualizărilor de implementare. Acesta este unul dintre principalele motive pentru care Cilium înlocuiește kube-proxy.
Cilium și eBPF: Viitorul rețelei Kubernetes
eBPF (Extended Berkeley Packet Filter) este o tehnologie de nucleu Linux care vă permite să rulați programe sandbox direct în kernel, fără a-l modifica e fără module kernel. Cilium folosește eBPF pentru a intercepta și procesa traficul de rețea la nivel de kernel, ocolind complet iptables și kube-proxy.
Beneficiile Cilium cu eBPF
- Performanţă: Latența a fost redusă cu până la 30%, debitul a crescut cu 60% în comparație cu iptables
- Scalabilitate: Căutare O(1) cu hărți BPF în loc de scanare liniară iptables
- Observabilitate: Hubble oferă vizibilitate în timp real a traficului L3/L4/L7
- Politica de nivel 7: Politici bazate pe calea HTTP, metoda, antetul, metoda gRPC, subiectul Kafka
- Service Mesh fără sidecar: mTLS și echilibrarea încărcăturii implementate în nucleu, zero sidecar overhead
- Înlocuire proxy Kube: Cilium poate înlocui complet kube-proxy
Instalare Cilium
Instalăm Cilium pe un cluster Kubernetes folosind Helm, configurându-l să îl înlocuiască kube-proxy și activați Hubble pentru observabilitate:
# Aggiungi il repo Helm di Cilium
helm repo add cilium https://helm.cilium.io/
helm repo update
# Installa Cilium con kube-proxy replacement e Hubble abilitati
helm install cilium cilium/cilium \
--version 1.16.0 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set k8sServiceHost=API_SERVER_HOST \
--set k8sServicePort=API_SERVER_PORT \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set ipam.mode=kubernetes
# Verifica installazione
cilium status --wait
# Verifica connettivita
cilium connectivity test
Cilium în producție: configurație avansată
Pentru un cluster de producție, iată o configurație completă a valorilor Helm cu rutare nativă (fără încapsulare VXLAN) pentru a maximiza performanța:
# cilium-values-production.yaml
kubeProxyReplacement: true
k8sServiceHost: "10.0.0.1" # indirizzo API server
k8sServicePort: "6443"
# Native routing mode (senza overlay VXLAN)
# Richiede che la rete sottostante supporti il routing dei pod CIDR
tunnel: disabled
autoDirectNodeRoutes: true
ipv4NativeRoutingCIDR: "10.244.0.0/16"
# IPAM
ipam:
mode: kubernetes
# BGP per annunciare i pod CIDR ai router
bgp:
enabled: true
announce:
podCIDR: true
lbIP: true
# Hubble - osservabilita Layer 7
hubble:
enabled: true
metrics:
enabled:
- dns:query;ignoreAAAA
- drop
- tcp
- flow
- icmp
- http
relay:
enabled: true
replicas: 2
ui:
enabled: true
# Monitoring con Prometheus
prometheus:
enabled: true
serviceMonitor:
enabled: true
# Encryption (WireGuard)
encryption:
enabled: true
type: wireguard
# Load Balancing con DSR (Direct Server Return)
loadBalancer:
mode: dsr # elimina un hop di rete nel path di ritorno
# Limita connessioni per Pod
bpf:
mapDynamicSizeRatio: 0.0025
Politica de rețea în Kubernetes
În mod implicit, toate podurile dintr-un cluster Kubernetes pot comunica liber între ele. Acest lucru este convenabil pentru dezvoltare, dar este o problemă de securitate în producție. The NetworkPolicy vă permit să definiți regulile de intrare și ieșire pentru poduri.
Atenție: este necesar pluginul CNI
NetworkPolicies sunt o resursă Kubernetes, dar implementarea lor depinde de Pluginuri CNI. Flannel nu acceptă NetworkPolicy în mod nativ. Pentru a le folosi, aveți nevoie de Cilium, Calico, sau alt CNI care le implementează. Resursa este acceptată de API-ul serverului dar ignorat dacă CNI nu o susţine.
Respingerea implicită: cea mai bună practică fundamentală
Primul pas pentru a izola sarcinile de lucru și a aplica o politică implicit-nega pe fiecare spațiu de nume. Acest lucru respinge tot traficul neautorizat în mod explicit:
# default-deny-all.yaml
# Nega tutto il traffico ingress e egress nel namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # seleziona TUTTI i pod nel namespace
policyTypes:
- Ingress
- Egress
---
# Permetti il traffico DNS (necessario per la risoluzione dei nomi)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
NetworkPolicy pentru o aplicație tipică
Să vedem cum să izolăm o aplicație cu trei niveluri: frontend, backend, bază de date. Doar front-end-ul acceptă trafic din exterior, doar backend-ul poate ajunge la DB:
# network-policies-app.yaml
# Frontend: accetta traffico dall'ingress controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-to-frontend
namespace: production
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8000
- ports:
- protocol: UDP
port: 53
---
# Backend: accetta solo dal frontend, puo raggiungere DB
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8000
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- ports:
- protocol: UDP
port: 53
---
# Database: accetta solo dal backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-database
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
CiliumNetworkPolicy: Stratul de politică 7
Politicile de rețea standard Kubernetes funcționează la nivelul 3/4 (IP și port). Ciliul se extinde asta cu CiliumNetworkPolicy, care permite politici bazate pe conținut de comunicare: cale HTTP, metoda gRPC, subiect Kafka, interogare DNS.
Politica HTTP cu Cilium
Permitem frontend-ului să apeleze numai anumite puncte finale backend:
# cilium-http-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: frontend-to-backend-l7
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8000"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/products.*"
- method: "POST"
path: "/api/v1/orders"
- method: "GET"
path: "/health"
Politica DNS cu Cilium
Limitați domeniile DNS pe care le poate rezolva un Pod (util pentru prevenirea exfiltrării datelor):
# cilium-dns-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: restrict-dns-egress
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
egress:
# Permetti solo DNS verso il cluster DNS
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s:k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*.internal.company.com"
- matchPattern: "*.svc.cluster.local"
- matchPattern: "api.stripe.com"
Hubble: Observabilitatea rețelei
Hubble și stratul de observabilitate Cilium. Oferă vizibilitate în timp real tot traficul de rețea de cluster, cu identități de comunicații bazate pe etichete Kubernetes în loc de adrese IP.
# Installa il CLI di Hubble
export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --fail --remote-name-all \
https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
tar xzvf hubble-linux-amd64.tar.gz
sudo mv hubble /usr/local/bin
# Port-forward al relay Hubble
cilium hubble port-forward &
# Osserva il traffico in tempo reale
hubble observe --namespace production --follow
# Filtra per Pod specifici
hubble observe \
--namespace production \
--from-pod frontend-7d9d6b8f-abc12 \
--to-pod backend-5c4f8d9-xyz99 \
--follow
# Mostra solo i drop (traffico bloccato dalle policy)
hubble observe \
--namespace production \
--verdict DROPPED \
--follow
# Statistiche per service
hubble observe \
--namespace production \
--output json | jq '.flow.destination.namespace'
Politica de rețea Depanare și depanare
Depanarea NetworkPolicies este una dintre cele mai frecvente provocări în Kubernetes. Iată o abordare sistematic:
# 1. Verifica quali NetworkPolicy si applicano a un Pod
kubectl get networkpolicies -n production -o wide
# 2. Test di connettivita con un Pod temporaneo
kubectl run test-pod \
--image=nicolaka/netshoot \
--rm \
-it \
--restart=Never \
-n production \
-- bash
# All'interno del Pod:
# Test TCP
nc -zv backend-service 8000
# Test DNS
nslookup backend-service.production.svc.cluster.local
# Test HTTP
curl -v http://backend-service:8000/health
# 3. Con Cilium, usa il tool di policy verification
cilium policy get # mostra tutte le policy caricate
# 4. Testa la connettivita specifica
kubectl exec -n production frontend-pod -- \
curl -v http://backend-service:8000/api/v1/products
# 5. Con Hubble, vedi perche un pacchetto viene droppato
hubble observe \
--namespace production \
--verdict DROPPED \
--from-pod frontend-7d9d6b8f \
--follow
Izolare cu mai multe spații de nume
În clusterele cu mai mulți locatari, este esențial să izolați spațiile de nume. În mod implicit, NetworkPolicies nu blochează traficul între spațiile de nume. Iată cum să implementați izolarea completă:
# Isola completamente un namespace da tutti gli altri
# (ma permette il traffico interno al namespace)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-isolation
namespace: tenant-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
# Permetti solo traffico dallo stesso namespace
- from:
- podSelector: {}
# Permetti da monitoring namespace
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
egress:
# Permetti solo traffico verso lo stesso namespace
- to:
- podSelector: {}
# Permetti DNS
- ports:
- protocol: UDP
port: 53
# Permetti verso monitoring namespace
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
Benchmark de performanță: Cilium vs kube-proxy
Benchmark-urile arată diferențe semnificative între Cilium cu eBPF și kube-proxy cu iptables în clustere cu un număr mare de Servicii:
| Metric | kube-proxy iptables | Cilium eBPF | Îmbunătăţire |
|---|---|---|---|
| Latență P50 (10K svc) | 450 µs | 130 µs | -71% |
| Latență P99 (10K svc) | 2,1 ms | 320 µs | -85% |
| Debit (Gbps) | 22 Gbps | 36 Gbps | +64% |
| Reguli de actualizare CPU (10K svc) | 180 sec | 2 sec | -99% |
| Conexiuni/sec | 220K | 380K | +73% |
Cele mai bune practici pentru rețele Kubernetes
Lista de verificare a rețelei de producție
- Alege acum CNI-ul potrivit: Migare CNI in productie si complex. Luați în considerare Cilium dacă plănuiți politici de rețea avansate sau rețea de servicii
- Implicit-deny în fiecare spațiu de nume: Începeți întotdeauna cu o politică de refuz totul, apoi adăugați excepții
- Etichete consecvente pe poduri: NetworkPolicies depind de etichete; utilizați convenții clare (aplicație, nivel, versiune)
- Testați politicile înainte de implementare: STATELE UNITE ALE AMERICII
cilium connectivity testsau testați capsule pentru a verifica - Activați Hubble: În producție, vizibilitatea traficului este esențială pentru depanare și conformitate
- Pisări de urmărire: Configurați alerte pe Prometheus pentru trafic neașteptat
- Nu blocați DNS: Nu uitați întotdeauna să permiteți UDP/TCP 53 să kube-dns în politicile dvs. de ieșire
- Politicile documentelor: Utilizați adnotările Kubernetes pentru a descrie scopul fiecărei politici de rețea
Anti-modele de evitat
Erori frecvente cu NetworkPolicies
- Politici prea laxe: Utilizare
namespaceSelector: {}fără matchLabels permite traficul din TOATE spațiile de nume, inclusiv cele compromise - Am uitat DNS: Dacă blocați toate ieșirile și uitați portul 53, podurile dvs. nu vor mai rezolva niciun nume de gazdă
- Etichetele nu au fost actualizate: Dacă adăugați poduri noi fără etichetele corecte, NetworkPolicies nu le protejează
- Teste doar în dezvoltare: Politicile de rețea pot bloca traficul neașteptat în producție. Testați întotdeauna în montaj cu trafic realist
- Folosiți IP în loc de selectoare: IP-urile podurilor se schimbă; folosiți întotdeauna podSelector și namespaceSelector, niciodată ipBlock pentru traficul intern
Concluzii și pașii următori
Modelul de rețea Kubernetes, cu abordarea sa plată, IP-per-Pod, are un design elegant simplitatea sa, dar sofisticată în implementare. Alegerea pluginului CNI este una dintre cele cele mai importante decizii arhitecturale pentru un cluster de producție: influențarea caracteristici de performanță, securitate și observabilitate disponibile.
Cilium cu eBPF este cel mai avansat CNI disponibil astăzi: înlocuiți kube-proxy cu performanță superioară, oferă politici de nivel 7, integrează observabilitatea cu Hubble și poate înlocui o rețea de serviciu tradițională pentru mTLS. Pentru noi clustere în producție, și alegerea recomandată de comunitatea CNCF și de jucători mari precum Google, Amazon și Microsoft care îl utilizează în serviciile Kubernetes gestionate.
Politicile de rețea, implementate corect cu o abordare implicită de refuz, reduc suprafața de atac drastic dacă un Pod este compromis. nu sunt opționale în producție: sunt o cerință fundamentală de siguranță.
Articole viitoare din seria Kubernetes la scară
Serii înrudite
- MLOps și Machine Learning în producție — Sarcini de lucru GPU pe Kubernetes
- Ingineria platformei — Platforme interne pentru dezvoltatori pe K8s
- Observabilitate și OpenTelemetry — monitorizarea clusterelor







