Kubernetes Ağı: eBPF ve Ağ Politikası ile CNI, Cilium
Kubernetes ağı ustaca soyutlar: her Pod yönlendirilebilir bir IP adresi alır, aynı Pod'daki kapsayıcılar ağ ad alanını paylaşır ve Pod'lar NAT olmadan herhangi bir düğümde birbirleriyle iletişim kurun. Ancak görünen sadelik gizleniyor gerçek bir karmaşıklık: bu model gerçekte nasıl çalışıyor? Kiminle ilgileniyor IP atamak, düğümler arasındaki trafiği yönlendirmek, ağ politikalarını uygulamak mı istiyorsunuz?
Cevap yatıyor Konteyner Ağ Arayüzü (CNI), bir standart ağ eklentilerinin Kubernetes ile nasıl entegre olması gerektiğini tanımlar. Bu makalede Kubernetes ağ oluşturma modelini içeriden inceleyeceğiz: kube-proxy nasıl çalışır, neden eBPF'li silium geleneksel çözümlerin yerini mi alıyor ve nasıl Üretim kümelerindeki iş yüklerini yalıtmak için Ağ Politikasını uygulayın.
Ne Öğreneceksiniz
- Kubernetes ağ modeli: Pod başına IP, düz ağ, NAT yok
- Konteyner Ağ Arayüzü (CNI) nasıl çalışır ve ana eklentileri
- eBPF'li kube-proxy (iptables/IPVS) ve Cilium arasındaki fark
- Çünkü eBPF, iptables'a kıyasla -%30 gecikme ve +%60 verim sağlıyor
- Cilium'u CNI olarak kurma ve yapılandırma
- Ağ Politikası: sözdizimi, pratik örnekler, varsayılan reddetme ve ad alanı izolasyonu
- Katman 7 kuralları için CiliumNetworkPolicy (HTTP, gRPC, Kafka)
Kubernetes Ağ Modeli
Kubernetes, herkesin karşılayabileceği dört temel gereksinime sahip bir ağ modeli dayatıyor: CNI uygulaması aşağıdakilere uygun olmalıdır:
- Tüm Pod'lar diğer tüm Pod'larla NAT olmadan iletişim kurabilir
- Tüm düğümler NAT olmadan tüm Pod'larla iletişim kurabilir
- Bir Pod'un kendisine ait olarak gördüğü IP ve diğerlerinin ona ulaşmak için kullandığı IP'nin aynısı
- Bir Pod'daki kapsayıcılar ağ ad alanlarını ve IP'leri paylaşır
Bu "düz ağ modeli" uygulama mantığını büyük ölçüde basitleştirir: mikro hizmetin çağırdığı hizmetin aynı düğümde mi yoksa bir düğümde mi olduğunu bilmesine gerek yoktur uzak. Karmaşıklık küme ağ katmanına taşınır.
Pod'lar Arasındaki İletişim Nasıl Çalışır?
Bir Bölme A, farklı düğümlerdeki B Bölmesi ile iletişim kurmak istediğinde, tipik akış şu şekildedir: yer paylaşımlı ağa (örneğin VXLAN) dayalı bir çözümle aşağıdaki:
- Paket, arayüz aracılığıyla Pod A'nın konteynerinden çıkar
eth0 - Düğüm ad alanını bir aracılığıyla girin
veth pair - CNI eklentisi onu yakalar ve VXLAN'da (veya GRE, Geneve...) kapsüller.
- Paket fiziksel ağdan Pod B düğümüne geçer
- Hedef düğümdeki CNI paketin kapsülünü açar
- Paket, Veth çifti aracılığıyla Pod B'ye ulaşır.
BGP veya yerel yönlendirmeye dayalı çözümlerle (yerel yönlendirme modundaki Cilium gibi), kapsülleme gerekli değildir ve performans önemli ölçüde artar.
Konteyner Ağ Arayüzü (CNI)
CNI, konteyner çalışma zamanlarının nasıl çağrılması gerektiğini tanımlayan bir CNCF spesifikasyonudur ağ eklentileri. Kubernetes, ağ yönetimini eklentilere devretmek için CNI'yı kullanır: kubelet bir Pod oluşturduğunda adresi tahsis etmek için yapılandırılmış CNI eklentisini çağırır IP'yi seçin ve ağ arayüzünü yapılandırın.
Ana CNI Eklentileri
| Eklentiler | Teknoloji | Ağ Politikası | L7 Politikası | Kullanım Örneği |
|---|---|---|---|---|
| Flanel | VXLAN katmanı | Hayır (yerli) | No | Geliştirme, basit kümeler |
| Patiska | BGP/yer paylaşımı | Si | No | Yerinde, performans |
| Silium | eBPF | Si | Evet (HTTP, gRPC) | Üretim, hizmet ağı |
| AWS VPC CNI | ENI yerel | Evet (SG) | No | EKS |
| Azure CNI | Yerel VNet | Evet (NSG) | No | AKS |
kube-proxy: Eski Yaklaşım
kube-proxy, Hizmetlerin uygulanmasından sorumlu Kubernetes bileşenidir: ne zaman bir müşteri bir Hizmeti çağırır, kube-proxy trafiğin şunlardan birine ulaşmasını sağlar: Pod arka ucu. Geleneksel olarak kullanır iptables bu amaçla.
İptables'ın sorunu, karmaşıklığın kural sayısıyla doğrusal olarak ölçeklenmesidir. 10.000 Hizmet ve 100.000 uç noktaya sahip bir kümede iptables milyonlarca kuralı yönetir. Her paket önemli bir etki yaratacak şekilde bu kurallar zincirinden geçmelidir. düğümün gecikmesi ve CPU'su üzerinde.
Ağaç içi alternatif e IPV'ler (IP Sanal Sunucusu), karma tablosu kullanan iptables doğrusal tarama yerine O(1) araması için. Ancak IPVS'nin de sınırlamaları vardır: Gelişmiş politikaları desteklemez ve yine de ek iptables kurallarının yönetimini gerektirir.
iptables Ölçekleme Sorunu
10.000 Hizmet ile iptables'lı kube-proxy, yalnızca Hizmetler için yaklaşık 40.000 kural oluşturur. Bu kuralların güncellenme süresi milisaniyelerden dakikalara çıkmaktadır. Kümelenmiş büyük olduğundan bu, etkinliklerin ölçeklendirilmesi ve dağıtım güncellemeleri sırasında yüksek gecikmelere yol açar. Bu, Cilium'un kube-proxy'yi değiştirmesinin ana nedenlerinden biridir.
Cilium ve eBPF: Kubernetes Ağının Geleceği
eBPF (genişletilmiş Berkeley Paket Filtresi) bir Linux çekirdek teknolojisidir bu, sandboxed programları değiştirmeden doğrudan çekirdekte çalıştırmanıza olanak tanır. çekirdek modülleri olmadan. Cilium, ağ trafiğini engellemek ve işlemek için eBPF'yi kullanıyor çekirdek düzeyinde iptables ve kube-proxy'yi tamamen atlayarak.
eBPF ile Cilium'un Faydaları
- Performans: İptables'a kıyasla gecikme %30'a kadar azaldı, verim %60 arttı
- Ölçeklenebilirlik: iptables doğrusal tarama yerine BPF haritalarıyla O(1) araması
- Gözlemlenebilirlik: Hubble, L3/L4/L7 trafiğinin gerçek zamanlı görünürlüğünü sağlar
- Katman 7 Politikası: HTTP yolunu, yöntemi, başlığı, gRPC yöntemini, Kafka konusunu temel alan politikalar
- Sepetsiz Servis Ağı: Çekirdekte mTLS ve yük dengeleme uygulandı, sepet yükü sıfır
- Kube proxy değişimi: Silium, kube-proxy'nin yerini tamamen alabilir
Silium kurulumu
Helm'i kullanarak Cilium'u bir Kubernetes kümesine kuruyoruz ve onu değiştirilecek şekilde yapılandırıyoruz kube-proxy ve gözlemlenebilirlik için Hubble'ı etkinleştirin:
# 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
Üretimde Cilium: Gelişmiş Yapılandırma
Bir üretim kümesi için burada tam bir Helm değerleri yapılandırması verilmiştir: performansı en üst düzeye çıkarmak için yerel yönlendirme (VXLAN kapsülleme olmadan):
# 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
Kubernetes'te Ağ Politikası
Varsayılan olarak Kubernetes kümesindeki tüm Pod'lar birbirleriyle serbestçe iletişim kurabilir. Bu geliştirme için uygundur ancak üretimde bir güvenlik sorunudur. Ağ Politikası Pod'lar için giriş ve çıkış kurallarını tanımlamanıza olanak tanır.
Dikkat: CNI Eklentisi Gerekli
NetworkPolicies bir Kubernetes kaynağıdır ancak bunların uygulanması, CNI eklentileri. Flannel, NetworkPolicy'yi yerel olarak desteklemiyor. Bunları kullanmak için Cilium'a ihtiyacınız var. Calico veya bunları uygulayan başka bir CNI. Kaynak, sunucu API'si tarafından kabul edilir ancak CNI bunu desteklemiyorsa göz ardı edilir.
Temerrüt Reddi: Temel En İyi Uygulama
İş yüklerini yalıtmanın ve politikayı uygulamanın ilk adımı varsayılan reddetme her ad alanında. Bu, açıkça yetkilendirilmemiş tüm trafiği reddeder:
# 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
Tipik Bir Uygulama için NetworkPolicy
Üç katmanlı bir uygulamanın nasıl izole edileceğini görelim: ön uç, arka uç, veritabanı. Yalnızca ön uç dışarıdan gelen trafiği kabul eder, yalnızca arka uç DB'ye ulaşabilir:
# 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: Politika Katmanı 7
Standart Kubernetes NetworkPolicies, Katman 3/4'te (IP ve bağlantı noktası) çalışır. Silium uzanır bununla CiliumAğ Politikasıiçerik tabanlı politikalara izin veren iletişim: HTTP yolu, gRPC yöntemi, Kafka konusu, DNS sorgusu.
Cilium ile HTTP Politikası
Ön ucun yalnızca belirli arka uç uç noktalarını aramasına izin veriyoruz:
# 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"
Cilium ile DNS Politikası
Bir Pod'un çözebileceği DNS etki alanlarını sınırlayın (veri sızıntısını önlemek için kullanışlıdır):
# 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: Ağ Gözlemlenebilirliği
Hubble ve Cilium gözlemlenebilirlik katmanı. Gerçek zamanlı görünürlük sağlar iletişim kimliklerini temel alan tüm küme ağ trafiği IP adresleri yerine Kubernetes etiketleri.
# 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'
Ağ Politikasında Hata Ayıklama ve Sorun Giderme
NetworkPolicies'te hata ayıklama, Kubernetes'teki en yaygın zorluklardan biridir. İşte bir yaklaşım sistematik:
# 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
Çoklu Ad Alanı Yalıtımı
Çok kiracılı kümelerde ad alanlarının yalıtılması kritik öneme sahiptir. Varsayılan olarak NetworkPolicies ad alanları arası trafiği engellemezler. Tam izolasyonun nasıl uygulanacağı aşağıda açıklanmıştır:
# 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
Performans Karşılaştırması: Cilium vs kube-proxy
Karşılaştırmalar, eBPF'li Cilium ile iptables'lı kube-proxy arasında önemli farklılıklar gösteriyor Çok sayıda Hizmete sahip kümelerde:
| Metrik | kube-proxy iptables | Silium eBPF | Gelişim |
|---|---|---|---|
| P50 gecikmesi (10K svc) | 450 µs | 130 µs | -71% |
| P99 gecikmesi (10K svc) | 2,1 ms | 320 µs | -85% |
| Verim (Gbps) | 22Gbps | 36Gbps | +%64 |
| CPU güncelleme kuralları (10K svc) | 180 saniye | 2 saniye | -99% |
| Bağlantı/sn | 220 bin | 380K | +%73 |
Kubernetes Ağı İçin En İyi Uygulamalar
Üretim Ağı Kontrol Listesi
- Şimdi doğru CNI'yı seçin: Migare CNI üretimde ve komplekste. Gelişmiş ağ politikaları veya hizmet ağını planlıyorsanız Cilium'u düşünün
- Her ad alanında varsayılan reddetme: Her zaman her şeyi reddet politikasıyla başlayın, ardından istisnalar ekleyin
- Pod'larda tutarlı etiketler: Ağ Politikaları etiketlere bağlıdır; Açık kurallar kullanın (uygulama, katman, sürüm)
- Dağıtımdan önce politikaları test edin: Amerika
cilium connectivity testveya kontrol etmek için bölmeleri test edin - Hubble'ı etkinleştirin: Üretimde, trafik görünürlüğü hata ayıklama ve uyumluluk açısından kritik öneme sahiptir
- Parça düşüşleri: Beklenmeyen trafik kesintileri için Prometheus'ta uyarıları yapılandırın
- DNS'yi engellemeyin: Çıkış politikalarınızda her zaman UDP/TCP 53'ün kube-dns'e izin vermesini unutmayın
- Belge politikaları: Her NetworkPolicy'nin amacını açıklamak için Kubernetes ek açıklamalarını kullanın
Kaçınılması Gereken Anti-Desenler
NetworkPolicies ile İlgili Yaygın Hatalar
- Çok gevşek politikalar: Kullanmak
namespaceSelector: {}matchLabels olmadan, güvenliği ihlal edilmiş olanlar da dahil olmak üzere TÜM ad alanlarından gelen trafiğe izin verilir - DNS'yi unutmak: Tüm çıkışı engellerseniz ve 53 numaralı bağlantı noktasını unutursanız Pod'larınız artık hiçbir ana bilgisayar adını çözümlemez
- Etiketler güncellenmedi: Doğru etiketlere sahip olmayan yeni Kapsüller eklerseniz NetworkPolicies bunları korumaz
- Yalnızca geliştirme aşamasındaki testler: NetworkPolicies, üretimdeki beklenmeyen trafiği engelleyebilir. Aşamalandırmayı her zaman gerçekçi trafikle test edin
- Seçiciler yerine IP kullanın: Pod IP'leri değişir; her zaman podSelector ve namespaceSelector'ı kullanın, dahili trafik için asla ipBlock'u kullanmayın
Sonuçlar ve Sonraki Adımlar
Düz, Pod başına IP yaklaşımıyla Kubernetes ağ modeli zarif bir tasarıma sahiptir sadeliği ama uygulamada sofistike. CNI eklentisini seçmek şunlardan biridir: Bir üretim kümesi için en önemli mimari kararlar: performans, güvenlik ve gözlemlenebilirlik özellikleri mevcuttur.
eBPF'li Cilium bugün mevcut olan en gelişmiş CNI'dır: kube-proxy'yi şununla değiştirin: üstün performans, Katman 7 politikaları sunar, gözlemlenebilirliği Hubble ile bütünleştirir ve mTLS için geleneksel hizmet ağının yerini alabilir. Üretimdeki yeni kümeler için, ve CNCF topluluğu ve Google, Amazon ve gibi büyük oyuncular tarafından önerilen seçim Yönetilen Kubernetes hizmetlerinde bunu kullanan Microsoft.
Varsayılan reddetme yaklaşımıyla doğru şekilde uygulanan ağ politikaları, Bir Pod'un güvenliği ihlal edilirse saldırı büyük ölçüde yüzeye çıkar. ben değilim Üretimde isteğe bağlıdır: bunlar temel bir güvenlik gereksinimidir.
Kubernetes at Scale Serisinde Yaklaşan Makaleler
İlgili Seriler
- Üretimde MLOps ve Makine Öğrenimi — Kubernetes'teki GPU iş yükleri
- Platform Mühendisliği — K8'lerdeki Dahili Geliştirici Platformları
- Gözlemlenebilirlik ve Açık Telemetri — küme izleme







