Kubernetes’te Network Trafiği, Service ve Ingress Objeleri

Tayyip Osmanoglu
Devops Türkiye☁️ 🐧 🐳 ☸️
7 min readOct 30, 2020

Bu yazımda sizlere Kubernetes’in network altyapısından bahsetmek istiyorum. Bilindiği üzere Kubernetes, container teknolojisine sahip projeleri ve hizmetleri yönetmek için kullanılan açık kaynaklı bir konfigürasyon ve otomasyon aracıdır. Aslında Kubernetes’in temeli, bir cluster’da yer alan node’ların birbirleri arasındaki iletişime dayanmaktadır. Bu yüzden Kubernetes’in network altyapısını bilmek Kubernetes’i anlamak için çok önemlidir. Kubernetes network altyapısına geçmeden önce bazı kavramları hatırlayalım.

iptables: Unix tabanlı bir işletim sisteminde birtakım kuralları olan bir firewall sistemi olarak tanımlanabilir. Bulunduğu konumdaki tüm gelen ve giden network paketlerini kontrol eder. Default olarak hiçbir kural tanımlı değildir. Tanımlanan kurallar ile birlikte network paketleri yönetilebilir.

Network Address Translation(NAT): Bu kavram bir IP paketinin header’ında yer alan IP bilgisinin değişmesi olarak tanımlanabilir. Source IP veya Destination IP, her ikisi için de bu durum geçerli olabilir.

Source Network Address Translation(SNAT): İç networkten çıkan bir IP paketinin dış networke bağlanma durumu için geçerlidir. Private bir IP adresinden çıkan IP paketinin header’ında yer alan source IP bilgisinin Public bir IP’ye dönüşümünü sağlayan protokoldür.

Destination Network Address Translation(DNAT): DNAT’ı ise SNAT’ın tam tersi olarak düşünebiliriz. Public bir IP’den gelen isteğin public olan destination IP bilgisini private IP’ye dönüştüren bir protokoldür.

Kubernetes’te Network Trafiği

Şimdi aynı node içerisinde yer alan iki pod arasında gerçekleşen bir paket trafiğini inceleyelim. Görsel 1'de görüldüğü gibi, Pod1 Pod2’ye bir IP paketi göndermek istiyor. Her pod’un kendi içinde bir network namespace’i ve node’da da bir root network namespace bulunmaktadır. Pod1 namespace’inin ethernet device’ından(eth0) çıkan bir paket, root namespace’ine geldikten sonra “Concept of Bridge” denilen noktaya varır. “Concept of Bridge” ARP protokolü ile Layer 2 seviyesinde yönlendirme yaparak hedeflenen virtual ethernet(veth) destination’unu bulmaya yardımcı olur. Paket doğru virtual ethernet device’e ulaştıktan sonra ise Pod2 network namespace’ine varır. Aynı node içinde yer alan Pod’lar arasında bir paket trafiği bu şekilde gerçekleşmektedir.

Şekil 1

Şimdi ise iki node arasında gerçekleşen bir paket trafiğini inceleyelim. Bu örnekte source pod olarak Pod1'i, destination pod olarak ise Pod4'ü seçmiş olalım. Şekil 1 örneğinde anlattığımız gibi, paket bridge’e(cbr0) kadar gelir. Bu sefer ARP sorgusu hata alacaktır, çünkü destination olarak gelen IP’yi bu bridge tanıyamaz ve yönlendirme yapamaz. Bu yüzden paketi default olarak eth0’ya yönlendirir ve paket node1'den ayrılmış olur. Sonrasında cluster subnet’inde hedef node’a doğru yönelir. Hedef node’da yer alan bridge’da ARP sorgusu yanıtı alındıktan sonra ise paket Pod4'e varır ve trafik tamamlanmış olur.

Şekil 2

Pod’lar arasında iletişimi bu şekilde açıklamış olsak da daha stabil, daha sürekli olacak bir sisteme ihtiyacımız bulunuyor. Cluster’da yer alan Pod’lar zaman içerisinde çok fazla değişkenlik gösterebilmektedir. Scale-up durumunda yeni Pod’ların oluşması, scale-down durumunda Pod’ların ölmesi gibi durumlar olabiliyor. Ayrıca Pod’ların oluşabilecek birtakım hatalar sonucunda crash olması da söz konusu. Bu gibi birçok beklenmedik durumla karşı karşıya kalabiliriz. Ve bu durumda Pod’lar arasında iletişimi sağlayan IP adresleri sabit kalmayacaktır. İşte bu noktada Kubernetes’in bizlere sağladığı biz çözüm mevcut: Services.

Bir Kubernetes Cluster’ında oluşan network trafiğini inceleyelim. Network trafiğinin iki tipi mevcuttur: Ingress ve Egress. Bir Pod’a, Node’a veya Service’e gelen isteği Ingress, bir Pod’dan, Node’dan veya Service’ten giden isteği ise Egress olarak açıklayabiliriz. Şekil 3'te belirtildiği gibi üç node’u bulunan bir Cluster’da farklı farklı Podlar ve Service’ler yer almaktadır. Her bir Node, Pod ve Service bir IP adresine sahiptir. Default Kubernetes Networking Security tanımlarında bir cluster içerisindeki her bir Pod veya Service birbirleri ile iletişim kurabilmektedir.

Şekil 3

Ingress ve Egress trafiğini daha iyi görebileceğimiz 3 katmanlı bir mimari düşünelim.(Şekil 4) Frontend uygulamasına dışarıdan gelen bir isteği Ingress, Frontend uygulamasından Backend uygulamasına giden isteği Egress, Backend uygulamasına Frontend uygulamasından gelen isteği ise Ingress olarak tanımlıyoruz. Burada dikkat edilecek nokta, bir network trafiğinde source’tan çıkışı Egress, destination’a varışı Ingress olarak tanımlanmasıdır.

Şekil 4

Yazımın önceki kısımlarında da belirttiğim gibi default olarak, her Pod veya Service birbiriyle iletişime geçebilir durumdadır. Peki ya Frontend web uygulamamızın DB uygulamasına erişimini istemediğimiz durumlarda ne yapmalıyız? İşte bu noktada ihtiyacımız olan şey bir başka Kubernetes objesi olan Network Policy objesidir. Bu Policy, DB Pod’una yalnızca API Pod’undan erişim sağlanmasını kontrol edecektir.

Network Policy tıpkı Pod, ReplicaSet, Deployment ve Service gibi bir Kubernetes objesidir. Bir Network Policy objesini bir veya birden fazla Pod’a bağlayabilir ve kurallar tanımlayabiliriz. Örneğin Şekil 5'te görüldüğü gibi DB Pod’u için, yalnızca API Pod’undan 3306 Portuna gelen Ingress trafiğine izin verecek bir Network Policy tanımlaması yapılabilir.Bu tanımlamanan kural dışında kalan tüm diğer trafikler engellenir.

Şekil 5

Örnek bir Network Policy yaml tanımını inceleyelim. Network Policy objesini hangi Pod’lar ile eşleştireceğimizi Label ve Selector kavramları yardımı ile düzenleyebiliriz. Örnek yaml tanımında da görüldüğü gibi “role: db” key-value eşleşmesi olan Pod’lara uygulanacak bir Network Policy tanımlaması yapılmış. Alt satırlarda ise, Policy Type Ingress olarak tanımlanmış gözüküyor. Bu yaml tanım dosyası ile, 3306 portuna yalnızca “name: api-pod” label’a sahip Pod’lardan gelecek Ingress trafiğinin kabul edileceği bir Network Policy objesi oluşturulabilir.

Network Policy Yaml Dosyası

Kubernetes Services

Ingress, Egress ve Network Policy’den bahsettikten sonra Kubernetes Services başlığına geri dönelim.

Service, Pod’ların oluşturduğu bir logical set olarak tanımlanabilir. Service, bizlere cluster içinde uygulamalar arasında iletişim kurmamızı veya cluster dışından gelen istekleri karşılayarak Pod’lara yönlendirme imkanı sağlar. . Örneğin; Frontend, Backend ve DB olmak üzere 3 ayrı katmandan oluşan bir uygulamamız olduğunu düşünelim. Bu uygulamayı 3 deployment objesi ile katmanlara bölelim. Bu katmanlardan, son kullanıcıların Frontend’e, Frontend katmanının Backend katmanına, Backend katmanının ise DB ile iletişimlerini Service’ler ile sağlayabiliriz.

Oluşturulan bu servicelerin hangi Pod’lar için hizmet vereceği yine Label-Selector yardımı ile sağlanmaktadır. İlgili Pod’lara atanan Label değerleri ve ilgili service tanımında Selector kullanılarak tanımlama yapılır.

Service’ler 3 farklı tipte tanımlanabilmektedir: ClusterIP, NodePort ve LoadBalancer.

ClusterIP: Cluster içerisinde yer alan servislerin birbirleri arasında iletişim kurabilmesi için kullanılan servis tipidir. Örneğin, Frontend ve Backend servislerinin aralarında konuşabilmesi için bu servis tipi tercih edilir.

ClusterIP Service

NodePort: Bu tip Service ile node üzerinde dışarıdan erişilebilir bir Port erişime açılır. Bu port numarası 30.000’den büyük bir port numarası olur. İlgili VM(Node)’in IP’si ve bu port numarası ile birlikte bu Service’e erişim sağlanır.

NodePort Service

LoadBalancer: Service’e bir Public IP atanması sağlanır, bu sayede Service’in dış dünyaya açılmasını sağlanır. Ve dış networkten gelen istekleri karşılayarak ilgili Node’lar dağıtma hizmetini sağlar.

LoadBalancer Service

LoadBalancer service tipi daha çok Cloud Provider’ların sağlamış olduğu Managed Kubernetes Cluster’larda tercih edilmektedir. Örnek vermek gerekirse, Azure Kubernetes Service(AKS) hizmetinde çalışan uygulamalara dış networkten erişim sağlayabilmek için Azure Load Balancer oluşturulabilir. Bu Load Balancer internal veya external olarak konumlandırılır. Internal Load Balancer seçeneği, Kubernetes Cluster’ı ile yalnızca aynı network içerisinde yer alan client’lar için erişilebilir hale gelecektir. Fakat External Load Balancer seçeneği ile, bir public IP adresi ile tüm internet ortamından Kubernetes Cluster’a erişim sağlanabilir.

Internal — External Load Balancer

Kubernetes Ingress

Şimdi ise Kubernetes mimarisinde yer alan bir başka obje olan Ingress yapısından bahsedelim. Ingress, son kullanıcıya tek bir Load Balancer üzerinden birden çok uygulamaya erişim imkanı sağlamaktadır. Ingress OSI Layer 7’da çalışarak HTTP seviyesinde yönlendirme imkanı sunar. Hem hostname’e göre hem de URL pathine göre tanımlama yapılabilir. URL üzerinden yapılan yönlendirme ile birlikte cluster içerisinde yer alan birden çok uygulamaya erişim sağlayabiliriz.

Cluster içerisinde oluşturulan bu Ingress Controller yapısını LoadBalancer tipinde bir service aracılığıyla hizmete açarız. Ingress, cluster içerisinde yer alan birden çok uygulama için birden fazla Load Balancer kullanmaktansa tek bir Load Balancer konfigürasyonu ile hizmet vermemize olanak sağlar. Ingress aynı zamanda TLS ile şifrelenmiş bir HTTP trafiği oluşturmamıza da imkan sağlıyor.

Şekil 6'da Ingress yapısı olmayan, her bir uygulama için ayrı bir Load Balancer kullanımı olan bir mimari görüyoruz. Bu çözüm, daha büyük yapılarda ekstra maliyetlere yol açar ve yönetilebilirliği zor bir yapı haline gelir.

Şekil 6

Ingress yapısı kurulan bir mimaride ise görüldüğü gibi tek bir Load Balancer arkasında birden çok endpointe yönlendirme yapabilme imkanı bulunuyor. (Şekil 7)

Şekil 7

Ingress bize ayrıca Canary Deployment yöntemi ile güncelleştirilen uygulamalara gelen trafik yükünü dağıtma kolaylığı da sağlıyor. Şekil 8'de görüleceği gibi son kullanıcıdan gelen isteklerin belirlenen yüzdelik kadarını Canary Release Service’lere yönlendirme yapılabilir.

Şekil 8

Kubernetes Cluster’da Ingress kaynağını kullanmak için birçok çözüm bulunmaktadır. Bunlardan bazılarını Nginx, HAProxy, Contour, Traefik ve Azure Application Gateway Ingress Controller olarak söyleyebiliriz.

BONUS

Kubernetes Network Çözümleri

Container Network Interface(CNI), Kubernetes network altyapısının konfigürasyonlarının yapılmasına kolaylık sağlayan bir standarttır. Kubernetes Network mimarisinde birden çok CNI plugini mevcuttur. Bunlardan bazıları: Calico, Flannel, Weave. Bu eklentiler, Kubernetes’in network gereksinimlerini sağlamak ve Cluster adminlerine network desteği sağlamak amacıyla kullanılmaktadır.

Calico

Kubernetes dünyasında en popüler CNI Networking plugini olarak performans, esneklik bakımından Calico’yu söyleyebiliriz. Calico, node’lar veya pod’lar arasında network bağlantısını sağlamanın dışında network security ve yönetimi konusunda destek sağlamaktadır. Network policy ve performans ihtiyaçlarının önemli olduğu, bir network planına ihtiyacımız olduğu ortamlarda Calico iyi bir seçenek olarak karşımıza çıkmaktadır. Buna ek olarak, Microsoft’un Cloud platformu olan Azure’un AKS hizmetinin kurulumu sırasında Calico eklentisi ile Kubernetes Cluster’ı kurma imkanı sağlamaktadır.

Değerli zamanınızı ayırdığınız için teşekkür ederim.

--

--