shop namespace'indeki bir pod http://api adresini çağırıyor ve istek zaman aşımına uğruyor. Pod çalışıyor, Service mevcut ve EndpointSlice'ı hazır durumda iki backend listeliyor. Sorun DNS'te, kube-proxy'nin düğüme yazdığı kurallarda, düğümler arasındaki overlay'de ya da birinin geçen hafta uyguladığı bir NetworkPolicy'de olabilir. Her biri, ayrı bir bileşenin işlettiği ayrı bir katmandır.
Bu yazı bu katmanları bir diyagram üzerinden ele alıyor: ağ modeli, pod'dan pod'a trafik, CNI eklentileri, Service'ler, DNS, NetworkPolicy ve kümeye giren ve kümeden çıkan trafik.
Kubernetes ağ modeli
Kubernetes ağ modelinin üç kuralı vardır. Her pod, container'larının paylaştığı ve küme genelinde geçerli olan kendi IP adresini alır. Her pod, hangi düğümde olursa olsun, proxy ya da NAT olmadan diğer tüm pod'lara ulaşabilir. Kubelet gibi düğüm ajanları da kendi düğümlerindeki tüm pod'lara ulaşabilir.
API'leri Kubernetes tanımlar; işi ise sizin kurduğunuz bileşenler yapar:
| Katman | Size ne sağlar | Kim uygular |
|---|---|---|
| Pod ağı | Pod başına bir IP, pod'dan pod'a erişilebilirlik | Bir CNI eklentisi |
| Service'ler | Bir grup pod için sabit bir sanal IP ve ad | kube-proxy ya da onun yerini alan bir eBPF çözümü |
| DNS | api.shop.svc.cluster.local gibi adlar |
CoreDNS |
| NetworkPolicy | Pod trafiği için izin kuralları | CNI eklentisi |
| Ingress, Gateway API | Küme dışından gelen trafiğin yönlendirilmesi | Sizin kurduğunuz bir controller |
Bu iş bölümü pek çok sürprizi açıklar; örneğin API sunucusunun kabul ettiği ama eklentinizin sessizce yok saydığı bir NetworkPolicy.
Aynı düğümde pod'dan pod'a
Container runtime bir pod'u başlattığında CNI eklentisini ADD komutuyla çağırır. Çoğu eklenti bir veth çifti, yani bir ucu pod'un içinde eth0 olan, diğer ucu host'ta duran sanal bir kablo oluşturur ve IP'yi atar. Flannel host tarafındaki ucu cni0 adlı bir Linux bridge'ine bağlar; Calico bridge kullanmaz: Her pod bir /32 rotası alır ve host, pod'un yönlendiricisi olarak çalışır. Her iki durumda da aynı düğümdeki trafik ne kapsülleme ne de NAT gerektirir.
Düğümler arasında pod'dan pod'a: overlay ya da doğrudan yönlendirme
Her düğüm genellikle pod aralığının bir dilimine sahiptir. Varsayılan ayarlarda, yani kube-controller-manager'ın --node-cidr-mask-size değeri 24 iken, 10.244.0.0/16 aralığı 256 düğümün her birine bir /24 verir; bu da kubelet'in varsayılan 110 pod sınırı için 256 adres demektir. Düğümler arasında eklentinin iki seçeneği vardır:
| Overlay (VXLAN, Geneve, IP-in-IP) | Doğrudan yönlendirme (BGP, bulut rotaları, VPC IP'leri) | |
|---|---|---|
| Düğümler arasındaki ağın gördüğü | Yalnızca düğüm IP'leri | Pod IP'leri |
| Gerektirdiği | Düğümler arasında IP erişimi | Pod aralıklarını yönlendiren bir ağ ya da pod'lar için VPC adresleri |
| Paket başına ek yük | IPv4 VXLAN için 50 bayt, IP-in-IP için 20 | Yok |
| Örnekler | Flannel ve Cilium varsayılanları, Calico VXLAN | BGP ile Calico, AWS VPC CNI, Azure CNI |
Bu ek yük bir MTU sorunudur: Calico'nun MTU kılavuzuna göre 1.500 baytlık bir ağda IPv4 VXLAN arkasındaki pod'ların MTU'su 1.450 olmalıdır. Bunu yanlış ayarlarsanız büyük paketler kaybolur ve bu durum rastgele takılmalar gibi görünür.
CNI eklentilerinin karşılaştırması
| Eklenti | Düğümler arası trafik | NetworkPolicy | Notlar |
|---|---|---|---|
| Flannel | Varsayılan olarak VXLAN (UDP 8472); ortak bir katman 2 ağında host-gw |
Flannel uygulamaz; kube-network-policies ya da Calico ekleyin | Küçük ve basit |
| Calico | BGP ya da VXLAN (UDP 4789) veya IP-in-IP overlay | Tam destek; ayrıca Calico'nun namespace'e bağlı ve global politikaları | iptables, nftables, eBPF, VPP ve Windows veri düzlemleri |
| Cilium | Varsayılan olarak VXLAN (UDP 8472), Geneve ya da doğrudan yönlendirme | Tam destek; ayrıca katman 7 ve DNS tabanlı kurallar | eBPF veri yolu |
| AWS VPC CNI | Overlay yok; pod'lar VPC adresleri alır | v1.14'ten beri, enableNetworkPolicy ile |
Düğüm başına pod sayısı instance tipine göre sınırlıdır |
AWS sınırı erken can yakar: Varsayılan üst sınır ENI sayısı × (ENI başına IP sayısı − 1) + 2'dir; yani her biri 10 adresli 3 arayüze sahip bir m5.large 3 × 9 + 2 = 29 pod çalıştırır. Prefix delegation bu sınırı yükseltir.
Service'ler: değişen pod'ların önünde sabit bir IP
Pod IP'leri, pod her değiştirildiğinde değişir. Service, bir grup pod'a tek bir sabit sanal IP (ClusterIP) ve bir DNS adı verir; arkasındaki pod'ları EndpointSlice'lar takip eder.
| Tür | Ne elde edersiniz |
|---|---|
| ClusterIP (varsayılan) | Küme içinde bir sanal IP |
| NodePort | Ek olarak her düğümde bir port, varsayılan olarak 30000–32767 aralığında |
| LoadBalancer | Ek olarak bir bulut ya da eklenti yük dengeleyicisi |
| ExternalName | Bir DNS takma adı (CNAME), proxy yapılmaz |
Headless (clusterIP: None) |
Sanal IP yok; DNS pod IP'lerini döndürür |
Bir ClusterIP'nin sahibi olan tek bir makine yoktur. Her düğümde kube-proxy, kernel'i öyle programlar ki 10.96.48.20:80 adresine giden bir paket, istemcinin düğümünden çıkmadan önce 10.244.2.22:8080 gibi bir pod adresine yeniden yazılır (hedef NAT). Service bir sunucu değil, mantıksal bir adımdır. Kurallar proxy moduna bağlıdır:
| Mod | Kubernetes 1.37'deki durumu | Nasıl çalışır |
|---|---|---|
| iptables | Linux'ta varsayılan | Service ve endpoint başına kurallar; rastgele backend |
| nftables | 1.33'ten beri GA; gelecekte varsayılan olması planlanıyor | Büyük ölçekte daha hızlı güncellemeler; kernel 5.13 ya da üstü gerekir |
| ipvs | 1.35'ten beri deprecated; 1.40'ta varsayılan olarak kapanıyor, 1.43'te kaldırılıyor | Kernel IPVS tabloları, daha fazla dengeleme algoritması |
| eBPF (Cilium, Calico) | kube-proxy'nin yerini alır | eBPF programlarında yük dengeleme |
Bir sürüm yükseltmesi değiştiremesin diye modu açıkça ayarlayın ve IPVS'ten çıkışı planlayın. NodePort'lar, nftables modunda varsayılan olarak yalnızca düğümün birincil adreslerinde dinler.
CoreDNS ile DNS
CoreDNS varsayılan küme DNS'idir ve kubeadm onu hâlâ kube-dns adını taşıyan bir Service'in arkasında çalıştırır. Her Service, <service>.<namespace>.svc.cluster.local biçiminde bir ad alır; bu ad Service'in ClusterIP'sine, headless bir Service'te ise pod IP'lerine çözümlenir. Kubelet her pod'un /etc/resolv.conf dosyasını yazar; kubeadm ile kurulmuş bir kümede shop namespace'indeki bir pod için bu dosya genellikle şöyledir:
nameserver 10.96.0.10
search shop.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
Asıl tuzak ndots:5: api.stripe.com gibi beşten az nokta içeren bir ad, önce tüm search domain'ler eklenerek denenir; bu yüzden tek bir harici sorgu üç başarısız sorguya mal olabilir. Sık sorgulanan adların sonuna nokta ekleyin, pod'un dnsConfig ayarında ndots değerini düşürün ya da NodeLocal DNSCache çalıştırın. Harici adlar daha sonra DNS'in nasıl çalıştığını anlatan yazıdaki yolu izler.
NetworkPolicy: varsayılan izinden en az ayrıcalığa
Varsayılan olarak her pod her yerden gelen trafiği kabul eder. Herhangi bir NetworkPolicy bir pod'u ingress (ya da egress) için seçtiği anda yalnızca bir politikanın izin verdiği trafik geçer; yanıtlara otomatik olarak izin verilir. Politikalar yalnızca izin kuralı ekler, bu yüzden sıralama hiçbir zaman önemli değildir. Her namespace'e bir varsayılan reddetme politikasıyla başlayın:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: shop
spec:
podSelector: {}
policyTypes:
- Ingress
Ardından ihtiyacınız olanı açın; burada web'den api'ye TCP 8080:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-web
namespace: shop
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 8080
Dört ayrıntı insanları sık sık hazırlıksız yakalar:
- Port, pod'un portudur; yani Service portu 80 değil, 8080.
- Varsayılan reddetme web pod'larını da yalıtır, bu yüzden Gateway'in onlara ulaşmak için kendi kuralına ihtiyacı vardır.
- Tek bir tire anlamı değiştirir. Tek bir
fromgirdisindekinamespaceSelectorilepodSelector'ın ikisi de eşleşmelidir; iki ayrı girdi olarak yazılırlarsa biri yeterlidir. - Egress için varsayılan reddetme DNS'i de engeller, bu yüzden önce
kube-dns'e giden 53 numaralı porta izin verin.
NetworkPolicy'de reddetme kuralı, küme genelinde bir kapsam ya da TLS'e dair herhangi bir şey yoktur; iş yükleri arasında karşılıklı TLS için service mesh mimari diyagramına bakın.
Giren ve çıkan trafik: Ingress, Gateway API ve egress
Ingress kararlıdır ama dondurulmuştur; Kubernetes projesi onun yerine Gateway API'yi önerir. Topluluğun Ingress NGINX controller'ı Mart 2026'da emekliye ayrıldı ve artık güvenlik düzeltmesi almıyor; yine de mevcut kurulumlar fark edilmeden çalışmaya devam ediyor.
Gateway API işi rollere göre böler: Platform sahipleri Gateway'i listener'ları ve sertifikalarıyla birlikte işletir, uygulama ekipleri de kendi namespace'lerinden HTTPRoute'lar bağlar. Gateway API Ekim 2023'te GA oldu; 2026 sürümleri de TLSRoute, TCPRoute ve UDPRoute'u standart hâle getirdi. Kubernetes ingress diyagramı bu yolu adım adım izliyor.
Egress unutulan yöndür. Kümeden çıkan trafik genellikle düğümün IP'sine çevrilir; AWS VPC CNI de VPC dışındaki hedefler için bunu yapar. Bu trafiği, dış hedefleri yalnızca IP aralıkları olarak görebilen egress kurallarıyla, Cilium'un toFQDNs kuralları gibi DNS'i anlayan kurallarla ya da bir iş ortağı sabit bir kaynak IP istediğinde bir egress gateway ile sınırlayın.
Kubernetes ağ diyagramı
Diyagram içeriği
- worker-1 · pods 10.244.1.0/24
- worker-2 · pods 10.244.2.0/24
- Users
- public-gw
- web · 10.244.1.12
- coredns · 10.244.1.5
- api · 10.244.2.21
- api · 10.244.2.22
- api · 10.96.48.20
- api-allow-web
- HTTPS 443
- HTTPRoute
- DNS: api.shop.svc.cluster.local via kube-dns 10.96.0.10
- TCP 10.96.48.20:80
- DNAT 10.244.2.21:8080
- DNAT 10.244.2.22:8080
- VXLAN overlay over UDP · node IP to node IP
Nasıl okunur:
- İki worker düğümü; her biri kendi /24 pod aralığıyla etiketlenmiştir.
- Mavi, kuzey-güney trafiğidir: Kullanıcılar HTTPS 443 üzerinden
public-gw'ye ulaşır ve bir HTTPRoute onları web pod'una gönderir. - Kehribar rengi DNS'tir: Web pod'u, 10.96.0.10 adresindeki
kube-dnsüzerinden CoreDNS'eapi.shop.svc.cluster.localadını sorar ve 10.96.48.20 yanıtını alır. - Turkuaz, Service yoludur: Web pod'u 10.96.48.20:80'e bağlanır; worker-1'deki kube-proxy kuralları bunu 8080 portundaki bir api pod'una yeniden yazar.
- Gri, overlay'dir: Paket, düğüm IP'leri arasında VXLAN içinde worker-2'ye geçer.
- Kırmızı, politikadır:
api-allow-web, api pod'larına yalnızcaapp=webpod'larının ulaşmasına izin verir. - Markdown bloğu sayıların arkasındaki varsayılanları listeler.
Kubernetes ağ diyagramlarını net çizmek
- Düğümleri pod aralıklarıyla, pod'ları IP'leriyle etiketleyin; log'larda aradığınız ayrıntılar bunlardır.
- Service'i mantıksal bir adım olarak çizin ve yeniden yazmanın nerede gerçekleştiğini not edin.
- Kenarları adres, port ve protokolle etiketleyin; Service'ten sonra pod portuna geçin.
- Kuzey-güney ve doğu-batı trafiğini farklı renklerle çizin; overlay'i düğümler arasında yalnızca bir kez gösterin.
- Her politikayı seçtiği pod'lara bağlayın ve izin verilen kaynağı belirtin.
- Kubelet'i, API sunucusunu ve fazladan replikaları dışarıda bırakın; kontrol düzlemini Kubernetes mimari diyagramı ele alıyor.
- Sık yapılan hatalar: paket yolunda kube-proxy (o kuralları yazar, paketleri kernel iletir), DNS'in hiç olmaması ve politikayı yok sayan bir eklentinin üzerine çizilmiş bir politika.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun. Ücretsiz Kubernetes YAML’dan diyagrama aracı, mevcut manifestleri ilk taslağa dönüştürür.
- Temel paketinden worker-1 ve worker-2 için iki Çerçeve düğümü ekleyin ve onları pod aralıklarıyla etiketleyin.
- Kubernetes paketinden IP'leriyle birlikte dört Pod düğümü ekleyin: worker-1'e web ve coredns, worker-2'ye iki api pod'u.
- Çerçevelerin arasına bir Service (ClusterIP, port 80'den 8080'e) ekleyin; web'den gelen ve iki api pod'una giden kenarları etiketleyin.
app=apiseçen bir NetworkPolicy ekleyin ve onu api pod'larına noktalı kenarlarla bağlayın.- Ağ paketinden bir İnternet düğümü ve HTTPS 443 listener'ı olan bir Gateway ekleyin, ardından bunları zincir hâlinde web pod'una bağlayın.
- Web pod'undan coredns'e kesikli bir DNS kenarı, çerçeveler arasına da kalın ve çift yönlü bir VXLAN kenarı çizin.
- Temel paketinden varsayılanları içeren bir Markdown bloğu ve kısa Metin notları ekleyin.
Kubernetes kullanım alanı sayfası daha fazla nesneyi listeliyor. Örnek 11 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor.
SSS
Kubernetes'te pod'lar düğümler arasında nasıl iletişim kurar? CNI eklentisi aracılığıyla: Ya bir overlay pod paketlerini düğüm IP'leri arasında sarmalar ya da doğrudan yönlendirme pod adreslerini olduğu gibi taşır. Her iki durumda da pod'lar birbirlerinin gerçek IP'lerini görür.
Pod IP'si ile ClusterIP arasındaki fark nedir? Pod IP'si tek bir pod'a aittir ve pod değiştirildiğinde değişir. ClusterIP ise bir Service'in sabit sanal IP'sidir; kube-proxy ya da onun yerini alan bir eBPF çözümü bu IP'yi güncel bir pod IP'sine yeniden yazar.
Hangi kube-proxy modunu kullanmalıyım? Kubernetes 1.37'de varsayılan mod iptables'tır; nftables 1.33'ten beri GA'dır ve varsayılan hâle gelecektir; IPVS ise deprecated durumdadır. Kernel 5.13 ya da üstünde uzun vadede daha iyi seçim nftables'tır.
NetworkPolicy'ler her CNI eklentisiyle çalışır mı? Hayır. API onları her yerde kabul eder, ama yalnızca NetworkPolicy'yi destekleyen eklentiler onları uygular: Calico, Cilium ve network policy desteği açık olan AWS VPC CNI uygular; tek başına Flannel uygulamaz.
Ingress mi kullanmalıyım, Gateway API mi? Yeni işler için Gateway API: Kubernetes onu öneriyor ve Ingress dondurulmuş durumda. Mevcut Ingress kaynakları çalışmaya devam eder, ancak artık güvenlik düzeltmesi almayan Ingress NGINX'ten geçişi planlayın.