Yeni Başlayanlar için Kubernetes Kavramları : Service

Bir önceki makalemde ile ilk adımı attığımız Kubernetes kavramlarında sizlere pod’lardan bahsetmiştim. Pod’lar için aklınızda tutmanız gereken ilk şeylerden birisi de fani olduklarıdır. Herhangi bir problem kaynaklı olarak ya da kaynak kısıtlarından dolayı her an tahliye edilebilirler. Pod’lar tahliyeleri adından yeniden ayağa kalktıklarında ise farklı bir ip adresi ve hostname atanacaktır. Bu durumda aklınıza pod’lara Cluster dışından stabil olarak nasıl erişebileceğiniz sorusu gelecektir. İşte tam bu noktada sahneye Service kavramı çıkmakta.

Kubernetes Service kavramı pod’ların faniliği karşısında konumlandırılmıştır. Servisler bir ya da daha fazla port’un bir ya da bir grup pod’a yönlendirilmesinden sorumlu bileşenlerdir. Açılan servis portlarına sadece cluster içerisinden erişelebileceği gibi aynı zamanda node üzerinden ya da load balancer üzerinden de erişim sunulabilir. Bu özellikleri sayesinden servisler podların erişim açısından grupladıkları gibi dışarıya açılabilmelerini de sağlamaktadırlar.

Pod’larla kıyaslandıklarında oldukça ucuz kaynak olan servislerden Kubernetes Cluster’ınızda istediğiniz kadar oluşturabilmeniz mümkündür.  Pod’ların faniliğinin aksine, sabit bir ip adresine sahip olan servisler aksi istenmediği sürece kalıcıdırlar. Sahip oldukları yük dengeleme, servis bulunurluğu, sabitlik ve zero down-time özellikleri sayesinde Kubernetes mimarinin önemli taşlarından birisidir. Arkaplanda verilen etiketlere sahip pod’lara erişimi soyutlaşarak hayat herkes için daha yaşanabilir hale gelmektedir

Kubernetes-Service

Bir Kubernetes Servisi ClusterIP, NodePort, LoadBalacer ve ExternalName olmak üzere 4 farklı tür olabilir. Seçilen servis türü aynı zamanda servisin erişim ve davranışını da belirlemektedir. Bu türleri ve servis davranışlarını aşağıda bulabilirsiniz;

ClusterIP

ClusterIP türü ile tanımlanan bir Kubernetes Service’i cluster dışından erişilebilir değildir. ClusterIP türü için servise sanal bir cluster ip adresi oluşturularak atanır. Erişimler atanan bu ip adresi üzerinden gerçekleştirilir.

ClusterIp

NodePort

NodePort türü ile tanımlanan bir Kubernetes Service’i cluster dışından da erişilebilir olacaktır. Tanımlama sırasında verilen NodePort değeri ile her bir Cluster Node’u üzerinde port açılarak servise yönlendirilir. Bu haliyle, aksi belirtilmediği sürece, herhangi bir node üzerinden servise erişilebilir.

NodePort

Yukarıda yer alan şema için aşağıdaki yaml dosyası kullanılabilir;

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: enterprisecoding-app
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30006

Yukarıda sıralanan port, nodePort ve targetPort değerlerinden sadece port değeri zorunludur. targetPort değeri belirtilmemiş ise port ile aynı değere sahip olduğu varsayılmaktadır. nodePort değeri belirtilmemiş ise varsayılan olarak 30000-32767 aralığındaki boş bir değer otomatik olarak atanacaktır.

Kubernetes 1.5 itibari ile NodePort olarak tanımlanan Servislerde varsayılan olarak Source NAT uygulamaktadır. Yani talebin yapıldığı node’dan farklı bir node’da yer alan pod’a yönlendirilen hedef paket içerisindeki istemci ip’si talebin yapıldığı node ip’si ile değiştirilmektedir. Bu durumda hedef pod içerisindeki uygulama gerçek istemci ip adresini göremeyecektir.

LoadBalancer

LoadBalancer türü ile tanımlanan bir Kubernetes Service’i aynı NodePort türünde olduğu gibi dışarıdan erişilebilir olacaktır. NodePort’tan farklı olarak LoadBalancer türünde Kubernetes Node’larının önünde önceden konumlanmış yük dengeleyiciler bulunmaktadır. Dışarıdan load balancer’a gelen trafik arkaplandaki pod’lara yönledirilecektir. LoadBalancer türü daha çok bulut tabanlı hizmet sağlayıcılarında görülmekle birlikte MetalLB gibi çözümler sayesinde on-premise sistemlerde de kullanılabilmektedir.

ExternalName

ExternalName türü ile tanımlanan bir Kubernetes Service’i önceki türlerde olduğu gibi selector kullanmak yerine DNS adını kullanacaktır. Bu türde, önceki türlerde olan proxy ya da forward işlemleri kullanılmamaktadır. Yönlendirme işlemi DNS seviyesinde gerçekleşmektedir. Konuyu daha net anlamak için aşağıdaki örneği inceleyelim;

apiVersion: v1
kind: Service
metadata:
  name: test-service
namespace: prod
spec:
  type: ExternalName
  externalName: database.fatihboy.com

Örnekteki service test-service.prod.svc.cluster.local adresi üzerinden yapılan isteklerde DNS servisi CNAME düzeyinde yer alan database.fatihboy.com değerini dönecektir. Bu yanıtı alan istemciler taleplerini bu adrese yapacaklardır.

2 Comments

  1. Merhaba Fatih Bey,
    Öncelikle teşekkür ederim kubernetesi yeni öğrenmeye başlayan birisi olarak sitenizden çok faydalanıyorum. Sade ve anlaşılır anlatıyorsunuz, kubernetesin kendi dökümantasyonu dahi bu kadar anlaşılır gelmedi bana.
    Benim 2 sorum olacaktı bu sorularımıda daha iyi anlatabilmek adına gerçek hayat üzerinden vermek istedim.

    1. Benim master node dışında 2 tane slave nodum var diyelim, tek containerı olan bir nginx deployment ayağa kaldırdım ve bu container birinci node’da ayağa kalktı, sonrasında node port ile dışarıya servis verdim. Daha sonrasında herhangi bir load balancer çözümü ile node1’ın belirttiğim nodeport portuna gitmeye başladım diyelim, fakat zaman içerisinde benim node1’de sıkıntım çıktı ve conatiner node2’ye geçti ama benim load balancer’ım node1’i görüyor hala. Bu problem için yaklaşım/önerileriniz neler olur?

    2.İkinci sorum biraz daha karmaşık 🙂
    Benim master node dışında 2 tane slave nodum var ama bu sefer 3 tane containerı olan bir nginx deployment ayağa kaldırdım ve 2 tanesi birinci node’da 1 tanesi de ikinci node’da çalışıyor. Bu 3 sunucu arasında yük dağılım işlemini nasıl yapabilirim öneriniz ne olur?
    (Nodeport yapmak bana mantıklı gelmedi gibi, anladığım kadarıyla bu senaryoda clusterip service oluşturup sonrasında Ingress mi kullanmalıyız emin olamadım infrastructure nasıl olmalı? )

    Cevabınız için şimdiden teşekkürler

    1. Merhaba Emre,
      Sorularına dair yanıtları aşağıda iletiyoruz. Faydalı olacağını umuyorum.

      1. Bir servis nodeport olarak açıldığında tanımlı olduğu pod ya da podların nerede olduğundan bağımsız olarak port tüm node’larda açılır. Makalede NodePort başlığı altında belirtildiği gibi, tüm node’lar üzerinden aynı port adresi ile erişilebilir. Ek bir efora gerek kalmadan cluster içinde paketin doğru pod’a iletilmesini sağlanacaktır. Bahsettiğiniz senaryo için Cluster dışındaki Load Balancer talebi herhangi node’a (ya da tümüne) yönlendirebilir. Bu açıdan load balancer gerçekten yükü dengeleme görevini yapmasa dahi yüksek erişilebilirliğin garantisi olacaktır.

      2. Dışarıdan gelen talepleri nginx ya da benzeri şekilde bir reverse proxy/load balancer v.b. ile yönetmek ve yönlendirmek ise pek çok alternatife sahip bir senaryo. Giriş olarak ingress controller (https://fatihboy.com/tag/ingress-controller/) kavramını incelemeni tavsiye ederiz.

Leave a Comment

en_USEnglish