İçindekiler

Kubernetes’in kelimesi Yunancadan geliyor ve anlamı dümenci (helmsman) veya pilot olarak karşımıza çıkıyor. Çoğu kaynaklarda kubernetesi k8s olarak yazıldığını görebilirsiniz. Bunun sebebi k ve s harflerinin arasında 8 tane harf olmasıdır.

Kubernetes (K8s), konteyner uygulamaların dağıtımını, ölçeklendirilmesini ve yönetimini otomatikleştirmek için açık kaynaklı bir sistemdir.

Sektörün ihtiyaçları neticesinde container yapılarının yoğun olarak kullanılmaya başlanmasıyla, yönetim ve operasyon yükünü kısıtlı personel ile kaldırabilmek adına bu sistemleri otonom haline getirmek kaçınılmaz bir hal aldı. Kubernetes’in öne çıktığı nokta tam olarak burası diyebilirim. Gerçek hayattan birkaç örnek verecek olursak;

  • Bizim makine bütünümüz var yani 1000 core luk bir makine halinde değil 8/10/12 vb gibi parçalar halinde, biz uygulamaları bunların üzerinde çalıştırırken uygulamaların nerede çalışacağına da karar vermek istemiyoruz. Bu durumlardan dolayı bütün container orchestratorlar birer cluster manager rolünde. Bunların üzerine bir agent kuruyoruz ve bize uygulamayı yönetme imkanı veriyor. Bizim 20 tane 10 core luk makinemiz varsa ben onları 200 core şeklinde bir bütün olarak görüyorum.
  • Containerları kurduk, 5 tane container çalıştıracağım, bunları aynı VM ler üzerinde değil de farklı VM lerde çalıştrımak istiyorum (best practice) gibi mantıksal tercihlerin yapılması ve aynı zamanda bir önceki maddede belirttiğim makine bütününde kullanılan/kalan core hesaplarının yapılması gibi işlemler içinde pencerenin bütününü gören bir mekanizmaya ihtiyacımız var bu noktada bir container orchestrator ihtiyacımız doğuyor.

Bu bilgiler ışığında kubernetes’in çözdüğü ve çözmeye aday olduğu noktalar ;

  • Tüm alt yapıyı tek bir bütün olarak görmemize/yönetmemize olanak sağlıyor.
  • Alt yapımızı daha iyi kullanmamıza olanak veriyor.
  • Containerlarda health check yaparak kontrollü çalışmasını sağlıyor.
  • Bir container herhangi bir sebepten fail duruma geçerse, yenisinin ayağa kaldırılmasını sağlıyor.
  • Maintenance yada failing durumlarında HA şeklinde bir node üzerindeki uygulamaları bir diğerine kesintisiz şekilde taşınmasını sağlıyor.
  • Conteinerların belirlenen kriterlerde auto-scale edilmesini sağlıyor ve aynı zamanda scale olan containerlere yük dağılımını da sağlıyor.
  • Yeni versiyonların herhangi bir kesinti olmadan deploy edilmesini sağlıyor.
  • Service discover gibi bir özellik ile ne-nerde bilmemize olanak sağlıyor.
  • Key/Value Store yani konfigürasyonları containerler dışında store edilmesini sağlıyor.
  • Containerlerin izole bir networkte haberleşmesini sağlıyor.

Google’ın GO dili kullanılarak geliştirdiği Kubernetes’i 2014 yılında açık kaynak hale getirildi ve Cloud Native Computing Foundation tarafından desteklenmektedir. Google tarafından 2004 yılından beri kullanılmakta ve hali hazırda milyarlarca konteyner için kullanılıyor.

Kubernetes konteyner içerisindeki uygulama veya servislerinizin en iyi şekilde çalışmasını sağlar.

Servisleri izler, yük dengelemesi yapar, depolama alanlarınızı yönetir, (Yerel depolama birimlerinizden, Amazon servislerine, NFS ve iSCSI protokollerinden verilmiş depolama birimlerine kadar), secret ve konfigürasyon yönetiminizi yapar, konteynerlarınız hataya düştüğünde otomatik olarak onarmaya çalışır, çok basit şekilde yatayda genişlemenizi sağlar. (CPU kullanımına göre otomatik olarak yapılabilir.)

Konteyner yönetim aracı olarak birden fazla alternatif vardır bunlardan başlıcaları docker swarm ve mesos’dur. Bu arada Kubenetes’de konteyner teknolojisi(Container runtime) olarak sadece docker’ı değil başka konteynerlarıda desteklemektedir, bunlar containerd, cri-o, rktlet konteynırlarıdır.

Kubernetes Bileşenleri

Kubernetes cluster, Kubernetes Control Plane(master) ve worker node adı verilen bir dizi çalışan sunucudan oluşur. Her cluster’da en az birer tane master ve worker node bulunmak zorundadır.

Worker nodelar uygulamanın bileşeni olan podları barındırır. The Control Plan(master) node ise clusterdaki çalışan worker nodeları ve podları yönetir.

Control Plan(Master) Bileşenleri

Master üzerindeki bileşenler aslinda clusterimizin tüm kontrol fonksiyonlarını yerine getiren birimdir. Yönetim fonksiyonlarının yanısıra operasyonel kararları alan birim de burasıdır.

Master bileşenleri cluster içerisindeki herhangi bir makinede çalışabilmesi mümkündür ama kolaylık olması için kurulumda tüm master bileşenlerini bir makinede toplanır ve kullanıcı containerları bu makinede çalıştırılmaz. Master içerisinde 5 bileşen bulunur;

  1. kube-apiserver : Cluster’ın beyni diyebiliriz. Kubernetes API Server ile REST bir servis sağlar ve client ile yapılan istekleri dinler. kubectl ile yaptığımız işlemler ile API Server’ındaki endpointleri çağırmış oluruz bir nevi. Başka bir deyiş ile, biz her kubectl komutu çalıştırdığımızda API Server’a bir REST çağrısı yapmış oluruz ve API server’dan dönen cevabı da çıktı olarak görürüz.
  2. etcd : Coreos tarafında yaratılmış open source distributed,tutarlı ve izlenebilir bir key value store (nosql database) diyebiliriz. Kubernetes üzerinde kalıcı bütün konfigürasyon ve durumları burada tutulur.
  3. kube-scheduler : Bir pod’un hangi node üzerinde çalışacağına karar verir , kubelet’i tetikler ve ilgili pod ve içindeki konteyner oluşturulur.Kısacası yeni bir pod oluşturulması isteğine karşı API server’ı izler.
  4. kube-controller-manager : Temel olarak, bir denetleyicidir, kümenin durumunu API Server izleme özelliğiyle izler ve bildirildiğinde, geçerli durumu istenen duruma doğru hareket ettirmek için gerekli değişiklikleri yapar. Kubernetes Master üzerinde Controller sınıflarını çalıştıran bileşendir. Başlıca kullanılan controllerlar aşağıda listelenmiştir.
  • Node Controller: Node’ların ayakta olup olmadığını kontrol eder.
  • Replication Controller: Pod’ların olması gereken replica sayısına gelmesini sağlar.
  • Endpoints Controller: Pod ve Services’lerin Endpoint’lerini yaratır.
  • Service Account & Token Controllers: Yeni namespaceler için default accounts ve API Access tokenları yaratır.
  1. cloud-controller-manager : Temel Cloud sağlıyacılarla etkileşime giren denetçileri çalıştırır.

Worker Node Bileşenleri

Node bileşenleri her node’da çalışır, çalışan podları korur ve Kubernetes runtime environmentı sağlar.

1.Kubelet : Her bir kubernetes node’unda çalışan agent’tır. İlk işi bulunduğu node’u API Server’a Node resource olarak kayıt ederek Kubernetes tarafından görülmesini sağlamaktır. Bu işlemden sonra sürekli olarak API server’i dinleyerek bulunduğu node’a herhangi bir Pod schedule edip edilmediğini kontrol eder. Schedule eden bir Pod varsa bulunduğu node üzerinde Pod’un içerisindeki tanımlanan containerları çalıştırır. Kubernetes haricinde yaratılan containerları yönetemez.

Buna ek olarak sürekli olarak node’da çalışan containerların ayakta olup olmadığını kontrol ederek erişilebilir olmalarını sağlar.

2.kube-proxy : Kubernetes Service ve Endpoint objelerinin erişebilirliğini sağlamak için node üzerindeki network kurallarını ayarlar ve connection forwarding işlemini gerçekleştirir. Görevlerinden biride Kubernetes Service’lere virtual IP atamasıdır. Userspace, iptables ve IPVS (IP Virtual Server) olarak üç modu vardır. kube-proxy’nin default modu iptables modudur. netlink interface’ini kullanır ve Service clusterIP ve Port’una gelen istekleri ilgili podlara yönlendirmek için iptables kuralları ekler.

3.Container Runtime : Containerları ayağa kaldıracak container runtime’ı belirtir. Kubernetes Docker, containerd, cri-o, rktlet container runtime’larını destekler

Kubernetes Objeleri

Kubernetes objeleri, Kubernetes sisteminde kalıcı varlıklardır. Kubernetes bu varlıkları clusterın durumunu göstermek için kullanır. Özellikle, aşağıdakileri tanımlayabilirler:

  • Hangi containerized uygulamalar çalışıyor hangi nodelarda
  • Bu uygulamalar için kullanılabilir kaynaklar
  • Yeniden başlatma ilkeleri, yükseltmeler ve fault-tolerance gibi bu uygulamaların nasıl davrandığına ilişkin ilkeler

Kubernetes nesneleriyle (ister oluşturma, değiştirme veya silme) çalışmak için Kubernetes API’sini kullanmanız gerekir. Örneğin kubectl komut satırı arabirimini kullandığınızda, CLI sizin için gerekli Kubernetes API çağrılarını yapar. Kubernetes API’sını Client Librarie lerden birini kullanarak doğrudan kendi programlarınızda da kullanabilirsiniz.

Her Kubernetes objesi, objenin yapılandırmasını yöneten iki iç içe obje alanı içerir: obje özellikleri ve obje durumu. Sağlamanız gereken özellik, obje için istediğiniz durumu, objenin sahip olmasını istediğiniz özellikleri açıklar. Durum, obje nin gerçek durumunu tanımlar ve Kubernetes sistemi tarafından sağlanır ve güncellenir.  Örneğin, Kubernetes Deployment, clusterınızda çalışan bir uygulamayı temsil edebilen bir objedir. Deploymentı oluşturduğunuzda, Deployment spesifikasyonunu uygulamanın üç kopyasının çalışmasını istediğinizi belirleyecek şekilde ayarlayabilirsiniz. Kubernetes sistemi Deployment spesifikasyonunu okur ve istediğiniz uygulamanın üç örneğini başlatır – durumu spesifikasyonunuza uyacak şekilde günceller. Bu örneklerden herhangi birinin başarısız olması durumunda (durum değişikliği), Kubernetes sistemi spesifikasyon ve durum arasındaki farka bir düzeltme yaparak (bu durumda yeni bir örnek başlatarak) yanıt verir.

Kubernetes’te bir obje oluşturduğunuzda, istenen durumunu açıklayan obje spesifikasyonunu ve obje hakkında bazı temel bilgileri (name gibi) sağlamanız gerekir. Objeyi oluşturmak için Kubernetes API’sini kullandığınızda (doğrudan veya kubectl aracılığıyla), bu API isteği bu bilgileri istek gövdesinde JSON olarak içermelidir. Çoğu zaman, bir .yaml dosyasında kubectl’e bilgi sağlarsınız. kubectl, API isteği yaparken bilgileri JSON’a dönüştürür. Kubernetes deployment için gerekli alanları ve nesne spesifikasyonlarını gösteren örnek bir .yaml dosyası:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Yukarıdaki gibi bir .yaml dosyası kullanarak bir deployment oluşturmanın yolu, .yaml dosyasını bir argüman olarak ileterek kubectl komut satırı arabiriminde kubectl uygula komutunu kullanmaktır. İşte bir örnek;

kubectl apply -f https://k8s.io/examples/application/deployment.yaml --record

Oluşturmak istediğiniz Kubernetes objesinin .yaml dosyasında, aşağıdaki alanlar için değerler ayarlamanız gerekir;

  • apiVersion – Nesneyi oluşturmak için Kubernetes API’sının hangi sürümünü kullanıyorsunuz?
  • kind – Ne tür bir nesne oluşturmak istiyorsunuz?
  • metadata – Bir ad dizesi, UID ve isteğe bağlı ad alanı dahil olmak üzere nesneyi benzersiz şekilde tanımlamaya yardımcı olan veriler
  • spec – Nesne için istediğiniz durumu

Kubectl komut satırı aracı, Kubernetes objelerini oluşturmak ve yönetmek için birkaç farklı yolu destekler.

Imperative Mode : Bu modda kullanıcı doğrudan clusterdaki canlı objeler üzerinde çalışır. Kullanıcı kubectl komutuna argümanlar göndererek işlemler sağlar. Clusterdaki tek seferlik bir görevi başlatmanın veya çalıştırmanın en basit yoludur. Örneğin;

kubectl run nginx --image nginx
veya 
kubectl create deployment nginx --image nginx
  • Komutlar basit, öğrenmesi ve hatırlaması kolaydır.
  • Komutlar, kümede değişiklik yapmak için yalnızca tek bir adım gerektirir.

Declarative Mode : Yapılacak işi bir veya daha fazla script içinde tanımlayıp çalıştırmaya yönelikdir. Belirtilen dosya nesnenin tam tanımını YAML veya JSON biçiminde içermelidir.

kubectl create -f nginx.yaml
kubectl delete -f nginx.yaml -f redis.yaml
kubectl replace -f nginx.yaml
  • Obje yapılandırması Git gibi bir kaynak kontrol sisteminde saklanabilir.
  • Obje yapılandırması, push ve denetim izlerinden önce değişiklikleri gözden geçirme gibi süreçlerle entegre olabilir.
  • Obje yapılandırması, yeni nesneler oluşturmak için bir şablon sağlar.

Terminoloji

Pod

Pod için kubernetes’in en küçük bileşenidir demek yanlış olmayacaktır. Kubernetes Cluster’ınızda çalışan process’leri temsil etmektedir. Pod’lar Kubernetes Cluster’ınızın deploy edilebilir birimlerdir.  Fiziksel makinelerin üzerinde VM kurmuştuk, bu VM lerin üzerine de Container konumlandırmıştık, şimdi bu 2 sinin arasına bir katman daha koyuyoruz buna da pod diyoruz. Kelime anlamı olarakta koza anlamına geliyor biraz daha anlaşılır.

  • Container yada Containerlerden oluşur.
  • Kubernetes içindeki en küçük yapı taşıdır.
  • İçindeki containerler tek bir network namespace kullanırlar.
  • Podlar ölümlüdür, ölür ve bir başka pod ayağa kalkar ve işi devr alır.
  • Podların IP leri unique dir.

Not : Containerlar birbirleri ile çok ilişikli çalışmıyor ise aynı pod içerisinde konumlandırmak çokta mantıklı değil. Best practice olarak ayrı podlarda olması gerekiyor.

Aşağıda en basit haliyle bir pod tanım dosyasını görebilirsiniz;

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

Bu örnekte 9-11. satırlar arasında container tanımı yer almaktadır. 8. satırda yer alan containers elementi bir array’dir. Dolayısıyla istenirse bu başlık altında birden fazla container tanımı yer alabilir. 3. satırda başlayan meta veri’de pod’umuzun adını belirtmemiz gerekmekte. Seçimli olarak, 5 ve 6. satırlarda olduğu gibi pod’umuza etiket ataması yapabiliriz. Opsiyonel olan bu etiket tanımları Kubernetes’te pek çok yönetim kolaylığı getirmesi nedeniyle hızlıca alışacağınızı ve kullanacağınızı düşündüm bir özelliktir.

Replica Set

Benim bir pod’um var, bundan ‘X’ kadar istiyorum durumunu sağlayan birimdir. Pod’un birisi öldüğünde bakıyor ve yeniden bir pod ayağa kaldırıyor ve IP atıyor.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3

 

  1. satırda yer alan replicas replica seti tanımlar.

Deployment

Uygulama dediğimiz şeye denk gelen yer deployment. Deployment ReplicaSet’in yanında rolling update yapma imkanı veren ilgili podu ve replica sayılarını belirttiğimiz bir Kubernetes objesidir. Deployment, arka tarafta ReplicaSet kullanmaktadır. Birden fazla ReplicaSet kullanabildiği için de rolling update yapma şansına sahiptir. Aynı şekilde bir önceki versiyona rollback yapma imkanı da verir. Bir nevi Blue/Green deployment yeteneği kazandırır.

Örneğin; yeni bir versiyona geçerken bütün pod’ları öldürüp downtime yaratarak yeni versiyona sahip podları ayağa kaldırmaz. Ayarlanabilen rolling update oranı ile yeni versiyon’a sahip podları ayağa kaldırır ve eski versiyona sahip olan podları öldürür. 3 replica’lı bir deploymenti 5 replicaya da çıkartabiliriz yada 2 replicaya da düşürebiliriz. Hatta çeşitli metrikler dinleyerek auto-scaling yeteneği de kazandırabiliriz.

Örnek bir deployment;

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Services

Herşeyin ve herkesin birbirinden haberdar olmasını sağlayan birimdir.

  • Trafiğin sağlıklı podlara aktarılmasını sağlarlar.
  • Clientlardaki IP lerin kalıcı ve stabil olmasını sağlar.

Biraz daha açacak olursak; 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.

Bir Kubernetes Servisi ClusterIP, NodePort, LoadBalacer ve ExternalName olmak üzere 4 farklı tür olabilir.

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.

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.

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.

LoadBalacer

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.

apiVersion: v1
kind: Service
metadata:
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer

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: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

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

Namespaces

Containerlar arasındaki isolation’ı sağlamak için kullanılır.

DaemonSet

DaemonSet objesi ile bütün Kubernetes workerlarında bir pod olarak çalışacak uygulama ayağa kaldırılabilir. Buradaki kritik nokta her bir Kubernetes workerında sadece bir podun çalıştırılmasıdır. ReplicaSet’de böyle bir kıstas yoktur. ReplicaSet’de oluşturulacak podlar herhangi bir node’a da schedule edilebilir.

DaemonSet’e örnek vermek gerekirse, Kubernetes Clusterımızda çalışan bütün servislerin loglarını toplamak istediğimizi farzedelim. Bunun için EFK (ElasticSearch-Fluentd-Kibana) stackini kullanmaya karar verdik. Bu stackde Fluentd logları toplayıp ElasticSearch’e ileten agent rolünü üstlenir. Bütün sistem üzerindeki containerları dinlemek için fluentd’yi DaemonSet olarak tanımlarız ve bütün kubernetes workerlar da otomatik olarak ayağa kalkmasını sağlarız. Monitoring gibi durumlar için gerçekten çok kullanışlı bir objedir.

Volume

Container disk’leri en basit tanımı ile “fani”dir. Herhangi bir sebepten dolayı pod’un yaşam döngüsü bitmesi ardından diskte bulunan her şey kaybolur. İşte bu noktada sahneye volume’ler çıkıyor. Kubernetes volume’leri için pod tarafından erişilebilen ve yeniden başlatmalarda verisini kaybetmeyen klasörler diyebiliriz. Kubernetes volumes tanımını biraz açtığımızda ise kabaca 5 gruba ayrıldığını görebiliriz;

  1. Yerel erişilebilir türler (örneğin; emtyDir, hostPath, local)
  2. Dosya paylaşım türleri (örneğin; nfs)
  3. Dağıtık dosya sistemi türleri (örneğin; cephfs, glusterfs)
  4. Bulut-sağlayıcı özelinde türler (örneğin; azureDisk, azureFile, awsElasticBlockStore, gcePersistentDisk)
  5. Amaca özel türler (örneğin; configMap, secret, gitRepo)

Birden fazla pod’un aynı volume’ü paylaşması da mümkün.

Persistent Volume

Containerlar üzerinde olan dosyalar (ephemeral data) bir yere persist edilmediği için containerin açıp kapanması sonrasında veri kaybedilir. Bu sebepten dolayı containera yazılan verilerin bir yere persist edilmesi gerekir. Örneğin; Bir Pod crash olursa, yeni bir Pod kubelet tarafından tekrar ayağa kaldırılır ama container içerisine yazılan veriyi kaybetmiş oluruz. Bu soruna çözüm olarak Kubernetes PersistentVolume (PV) objesini kullanmaktadır. PersistentVolume’lar ise PersistentVolumeClaim (PVC)’ler aracılığı ile kullanılabilmektedir. Persistent Volume’ların tıp ki podlar gibi bir hayat döngüsü vardır.

PersistentVolume cluster içerisinde kurulan herhangi bir storage’ı kullanacak şekilde yaratılabilir. Örnek: NFS, iSCSI, host-path. Oluşturduğumuz PersistentVolume ilgili Pod veya Deploymentlara PersistentVolumeClaim ile mount edilir. Cloud’da kullanılan Kubernetes Clusterlarda PersistentVolumeClaim ile mount edilen storage direk olarak provision edilir. Dolayısıyla Cloud’da sıradışı bir durum olmadıkça herhangi bir PersistentVolume yaratmaya gerek yoktur.

StatefulSet

DB gibi state tutma ihtiyacı duyan uygulamalar için Kubernetes’de StatefulSet kullanılması önerilir. Biliyoruz ki Kubernetes’de persist etmek istediğimiz veriyi PersistentVolume şeklinde tutuyoruz. Persist ettiğimiz veri ile Pod ayrı node’a schedule olursa veri pod tarafından erişilemez duruma gelir. Clustered olarak çalışan bir uygulama göz önüne alındığında ise bu çok olası bir durumdur. Bu durumun engellenmesi için de StatefulSet kullanırız.

StatefulSet, scaling-up ve scaling-down işlemlerinde podları sıralı olarak ayağa kaldırır ve sıralı olarak siler. Ayrıca oluşturulan podların tekilliğini garanti eder. 3 replicalı bir StatefulSet yarattığımızı düşünelim. Deployment’ in aksine StatefulSette podlar X-1, X-2, X-3 gibi belirli bir identity ile isimlendirilir.Podlar ayağa kalkarken ilk X-1, sonra X-2 sonra X-3 ayağa kalkacağını biliriz. Aynı şekilde StatefulSeti silerken de ilk olarak X-3 kill edilir, sonra X-2 en son da X-1 kill edilir. Bu isimlendirmeyi yapabilmek için de StatefulSet bir Headless Serviceden faydalanılır.

Data integrity’sini sağlamak içinde yaratılan StatefulSet’ler silindiği zaman kullandıkları PersistentVolumelar silinmez.

Referanslar;
https://kubernetes.io/docs/concepts/overview/components/
https://www.fatihsolen.com/kubernetes-nedir/
https://medium.com/devopsturkiye/kubernetes-nedir-eb5c5d149e69
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/
https://medium.com/devopsturkiye/kubernetes-nedir-f4a6f326d036
https://enterprisecoding.com/
https://medium.com/codable/kubernetes-d090867428ca

Loading