Kubernetes’te Bir Uygulamanın Yolculuğu: Deployment’tan Service’e
Hikayenin Başlangıcı
Kubernetes dünyasına hoş geldiniz! Elimizde, tüm bağımlılıklarıyla birlikte bir konteyner haline getirilmiş bir uygulamamız olduğunu hayal edelim. Amacımız basit: Bu uygulamayı Kubernetes üzerinde çalıştırmak ve ona hem küme içinden hem de dış dünyadan erişebilmek. Bu belge, bu yolculuğu bir hikaye formatında, adım adım anlatacak. Konteynerimizin, bir Deployment ile nasıl hayata geçtiğini, Pod‘lar içinde nasıl yaşadığını ve son olarak bir Service ile nasıl kalıcı bir adrese kavuşarak erişilebilir hale geldiğini birlikte keşfedeceğiz.
1. Adım: Uygulamayı Hayata Geçirmek (Deployment ve Pod)
Uygulamamızı Kubernetes’te çalıştırmak için ona talimatlar vermemiz gerekir. Bu talimatları, bir “yönetici” gibi davranan Deployment kaynağı ile veririz. Deployment, bizim “istenilen durumu” belirttiğimiz bir manifestodur. Kubernetes’in temel felsefesi olan bildirimsel (declarative) yaklaşımla çalışır; yani sisteme neyi nasıl yapacağını değil, ne istediğimizi söyleriz. Örneğin, Deployment dosyamıza “Bu uygulamadan 3 kopya istiyorum” yazarız ve Kubernetes gerisini halleder.
Deployment, Pod’lar ve ReplicaSet’ler için bildirimsel güncellemeler (declarative updates) sağlar.
Peki uygulamamız tam olarak nerede çalışır? Cevap Pod‘dur.
Bir Pod, Kubernetes nesne modelindeki oluşturduğunuz veya dağıttığınız en küçük ve en basit birimdir.
Pod, uygulamamızın konteynerini barındıran bir “yuva” gibidir. Kubernetes’teki en temel çalışma birimidir. Deployment ise bu yuvaların yöneticisidir: belirttiğimiz Pod şablonunu—yani Pod’ların nasıl görünmesi gerektiğine dair planı—kullanarak istediğimiz sayıda Pod kopyası oluşturur ve onların sağlıklı çalıştığından emin olur.
Uygulamamız artık Pod’lar içinde başarıyla çalışıyor. Ancak bu, hikayenin sadece ilk kısmı. Şimdi, bu çalışan Pod’lara ulaşmaya çalıştığımızda karşımıza çıkan ilk büyük zorluğu inceleyelim.
2. Adım: İlk Zorluk: Kaybolan Adresler (Geçici Pod IP’leri)
Pod’ların kritik bir özelliği vardır: onlar “geçici, tek kullanımlık varlıklar” (ephemeral, disposable entities) olarak tasarlanmışlardır. Bu, bir Pod’un herhangi bir nedenle (örneğin üzerinde çalıştığı Düğümün çökmesi) yok olup yeniden yaratıldığında, kendine ait yeni bir IP adresi alması anlamına gelir.
Bu durum, ağ üzerinde iletişim kurması gereken uygulamalar için ciddi bir sorun yaratır. Bu temel sorunu şu şekilde ifade edebiliriz:
Eğer Pod IP’leri sürekli değişiyorsa, uygulamalar (örneğin bir frontend Pod’u) birbirlerini (örneğin bir backend Pod’unu) ağ üzerinde nasıl güvenilir bir şekilde bulabilir?
Bu “kaybolan adresler” sorunu, Kubernetes’in en zarif çözümlerinden birini ortaya çıkarır: Service.
3. Adım: Çözüm: Kalıcı Bir Adres Tabelası (Service)
Service (Servis), Pod’ların geçici IP adresi sorununu çözmek için tasarlanmış bir soyutlamadır.
Service, bir grup Pod üzerinde çalışan bir uygulamayı ağ servisi olarak ortaya çıkaran bir soyutlamadır.
Bir Service temel olarak iki kritik işlevi yerine getirir:
- Kararlı Adres Sağlama Bir
Serviceoluşturulduğunda, Kubernetes ona asla değişmeyen sanal bir IP adresi (ClusterIP) ve küme içinde geçerli bir DNS adı atar. Artık kümedeki diğer uygulamalar, sürekli değişen Pod IP’lerini takip etmek yerine, bu kalıcı ve güvenilir adresi kullanarak iletişim kurarlar. - Yük Dengeleme (Load Balancing)
Service, bir “seçici” (selector) kullanarak arkasında hangi Pod’ların olduğunu bilir. Gelen ağ trafiğini, bu seçiciye uyan sağlıklı Pod’lar arasında akıllıca dağıtarak yük dengelemesi yapar. Bu sayede hem trafik dengelenir hem de isteklerin yalnızca çalışan Pod’lara gitmesi sağlanır.
Artık uygulamamızın küme içinde sabit bir adresi var. Peki, bu adrese dış dünyadan veya farklı senaryolarda nasıl ulaşacağız? İşte burada Service‘in farklı “tipleri” devreye giriyor.
4. Adım: Dış Dünyaya Açılan Kapılar (Service Tipleri Hiyerarşisi)
Bir Service oluştururken, onun “tipini” belirterek nasıl erişilebilir olacağını tanımlarız. ClusterIP, NodePort ve LoadBalancer tipleri, birbirleri üzerine inşa edilen hiyerarşik katmanlar gibidir.
| Servis Tipi | Erişilebilirlik | Temel Amaç ve Kullanım Senaryosu |
| ClusterIP | Yalnızca Küme İçi | Temel Katman: Servis’e küme içinden erişilebilen, kararlı bir sanal IP atar. Küme içindeki servislerin birbiriyle konuşması için (örneğin, bir web sunucusunun veritabanına bağlanması) standart yöntemdir. Bu varsayılan tiptir. |
| NodePort | Küme Dışı (Düğüm IP’si üzerinden) | İkinci Katman: ClusterIP‘in üzerine inşa edilir. Her bir sunucunun (Düğümün) kendi IP adresi üzerinde sabit bir port açarak servise dışarıdan erişim sağlar. Genellikle geliştirme ve test ortamları için kullanılır. |
| LoadBalancer | Küme Dışı (Harici IP üzerinden) | En Üst Katman: NodePort‘un üzerine inşa edilir. Yalnızca bulut sağlayıcılarda çalışır ve uygulamaya özel, kararlı bir dış IP adresine sahip harici bir yük dengeleyici oluşturur. Uygulamaları internete açmanın üretim ortamındaki standart yoludur. |
Bu tablo, tipler arasındaki hiyerarşiyi de ortaya koyar: LoadBalancer en üst katmandır ve çalışmak için bir NodePort servisine ihtiyaç duyar; NodePort ise temel ClusterIP üzerine bir katman ekler. Bu nedenle, bir LoadBalancer oluşturduğunuzda aslında her üç servis türünün de yeteneklerini bir arada kullanmış olursunuz. Bu yapı, LoadBalancer -> NodePort -> ClusterIP şeklinde özetlenebilir.
Yolculuğun Sonu
Uygulamamızın Kubernetes’teki yolculuğunu başarıyla tamamladık. Bu hikayenin adımlarını kısaca özetleyelim:
- Uygulamamızı çalıştırmak için bir
Deploymentoluşturarak “ne istediğimizi” bildirdik. Deployment, bu isteği gerçeğe dönüştürerek uygulamamızı barındıranPod‘ları yarattı ve yönetti.Pod‘ların IP adreslerinin sürekli değişmesi bir iletişim sorunu yarattı.Service, bu sorunu çözmek içinPodgrubuna kalıcı bir sanal IP (ClusterIP) ve DNS adı atayarak sabit bir adres tabelası oluşturdu.- Son olarak, uygulamayı dış dünyaya açmak için
NodePortveyaLoadBalancergibiServicetiplerini kullanarak bu kalıcı adresi erişilebilir hale getirdik.
Bu süreç, Kubernetes’in temel yapı taşlarının bir uygulamayı çalıştırmak ve erişilebilir kılmak için nasıl uyum içinde çalıştığını göstermektedir.
