Burada anlatılan kubernetes bileşenlerinin uygulamalarını buradan bulabilirsiniz.
POD
Pod kubernetes içerisindeki en küçük birimdir. Her bir pod’un benzersiz IP adresi vardır. Pod içerisinde en az bir veya birden fazla container bulunur. Bu containerlar bağlı bulundukları pod’un IP adresini ortak kullanırlar. Pod içerisindeki containerlara ulaşmak için ilgili containerlara farklı port numaraları verilerek pod üzerinden ilgili uygulamaya ait container’a bağlantı sağlanabilir. Her bir pod oluşturulurken pod’a ID ataması yapılır. Podlar silinene kadar yaşamına devam eder.
REPLICASET
Replicaset bir pod’dan birden fazla oluşturulması ve ilgili pod sayısının garanti edilmesi için kullanılır. Replicaset podların yöneticisidir. Herhangi bir nedenle ilgili pod silinirse hemen takrar oluşturmaya çalışır.
Hafif Bilgi: Cluster’ınız da daha önce oluşturulmuş bir pod var ise aynı isimde replica set oluşturulduğunda şöyle bir durum söz konusu olacaktır. Bir pod replicaset, deployment gibi yapılara bağlı olmadan oluşturulmuş ise aynı isimde replicaset oluşturulur ise bu pod replicaset’e dahil olur. Replicaset ile podlar oluşturulurken replica sayısına bu dahil edilerek oluşturulacak pod sayısı bu duruma göre belirlenir.
DEPLOYMENT
Kubernetes üzerinde deployment nesnesi replicaset’in süpervisörü olarak görev almaktadır. Uygulama güncellemelerinin yapıldığı yerdir. İlgili güncellemelerde yeni bir versiyona geçilebilir veya eski bir versiyona dönülmesi sağlanabilir. İlgili pod spect’i altında değişimler yapılıp uygulanması sağlandığın da yeni replicaset oluşturularak var olan podların yenisine taşınması sağlanır. Eğer yeni sürüm kararlı değilse eski sürüme dönülebilir. İlgili deployment’ın tüm sürümleri sistemde tutulmaktadır. Örnek verecek olursa ilgili deployment’ın image sürümünü güncelleyebilirsiniz, eğer hata yapılarak güncelleme sağlandıysa bir önceki sürüme kolaylıkla dönülebilir.
DEAMONSET
Kubernetes üzerinde daemonset nesnesi yapı olarak deployment nesnesi ile aynıdır, fakat çalışma bakımından daemon nesnesi oluşurken kendisine ait podları sistemde var olan node veya node’lar üzerine taint olmadığı sürece otomatik olarak atar. Yani bir daemon nesnesi oluşturulmaya çalışıldığında pod sayısının node sayısı kadar olacağı unutulmamalıdır. Daemonset genellikler node üzerinde log toplama, node monitoring gibi işlemlerde kullanılır. Konu ile ilgili uygulamalı örneğe buradan erişebilirsiniz.
STATEFULSET
Statefulset yapısı deployment veya deamonset nesnesi gibi çalışır, farklı olarak bir statefulset nesnesi oluşturulduktan sonra kendi podlarını sırası ile ayaga kaldırır ve podlara sırasıyla 0 dan başlayacak şekilde numara ataması yapar. Pod ataması deploymen nesnesi gibi rastgele(yani kubernetes algoritmasına göre) sistemde var olan node veya node’lar üzerine atanır. Deamonsetten farklı olarak her node üzerinde bir tane pod olacak şekilde değil, deployment nesnesi gibi rastgele atama yapacak şekilde davranır, deployment nesnesinden farklı olarak da pod isimleri numaralandırılarak sırası ile ataması yapılır. Ayrıca benzersiz olacak şekilde pod oluşturulması garanti eder. Statefulset durum tutan uygulamalarda, ve sıralı çalışması gereken uygulamalrda kullanılır. Örneğin redis cluster kurmak istediğinizde statefulset kullanabilirsiniz. İlgili örneğe buradan erişebilirsiniz. Örnek uygulama kısmına da buradan erişebilirsiniz.
SERVİS OLUŞTURULMASI
Kubernetes üzerinde bulunan podlar öldüğünde yeniden yaga kaldırılması otomatik olarak olmaz. Ve her bir pod’un unique ip adresi vardır. Eğer bir pod replicaset veya deployment’a bağlı ise o pod öldüğünde yeniden oluşturulur ve oluşturulan podların ip adresi değişir. Eğer biz pod ip adresi üzerinden ilgili pod’a erişim sağlayacak isek o pod yeniden oluşunca ip adresi değişir ve artık eski ip adresi üzerinden ilgili pod’a erişim sağlayamayız. VE bağlantı için ip adresini tekrar düzenlememiz gerekir. Bunun önüne geçmek için kubernetes üzerinde servis adında neseler vardır. Bu anlatım da bu servislere değineceğim.
Servis bir uygulamanın gelen isteklere cevap vermesini sağlayan o uygulamayı dışarıya açan kubernetes nesnesidir.
Hafifbilgi: Bir servis arkasında bağlı olan podlara gelen istekleri sırasıyla gönderir. Otomatik loadbalancer yapar. Ayrıca kubectl komutu ile kubernetes objesi oluştururken aynı zamanda –expose ile o objeye ait servis te oluşturabilirsiniz.
Bir servis ilgili uygulamaya label üzerinden eşleşme işlemi yapar. Yani servis nesnesini oluşturacak yaml dosyası içerisinde ilgili uygulamanın label kısmı belirtilerek servis oluşturulur. Artık servis ilgili uygulamanın dışarı açılması sağlanır.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Örneğin yukarıdaki yaml dosyasında selector: kısmında belirtilen app: Myapp kısmında belirtilen kısım ile oluşturduğumuz deployment,pod,replicaset vb. kunbernetes bileşenlerinin eşleşmesi durumunda artık bu servis ilgili uygulamanın dışarı açılan penceresidir. İlgili uygulamaya servis üzerinden artık erişilebilirsiniz.
Servis default olarak oluşturulduğunda clusterIP durumunda oluşturulur ve belirli bir IP adresi alır. Servis için yaygın kullanılan protokol TCP dir, uyumlu diğer protokollerde kullanılabilir.
Servisler proxy üzerinden haberleşir. Ayrıca servisler üzerinde birden çok bağlantı noktasıda belirlenebilir. Aşağıda bun örnek bir yaml dosyası verilmiştir.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
Ayrıca bir servis doyası üzerinde kendi IP adresimizide belirleyebiliriz. Bunun için .spec.clusterIP alanı ayarlanarak yapılabilir. Bu IP adresi service-cluster-ip-range aralığında olmalıdır.
Servis Tipleri: Servis tipleri servis yaml dosaysı içerisinde .spec altında type: kısmında belirtilebilir.
- ClusterIP: Servis oluşturulurken varsayılan olarak bu türde oluşturulur. Cluster içerisinden bir IP adresi verilerek oluşturulur. İlgili servise sadece cluster içerisinden erişebilirsiniz.
- NodePort: Bu ilgili node IP adresi üzerinden uygulamayı dışarı açar. Servis 30000-32767 arasından bir port numarası ile dışarı açılır. Erişim sağlanması için ilgili node’nin IP adresi ve verilen port numarası girilerek uygulamaya erişim sağlanır.
- LoadBalancer: Bulut sistemi için ilgili servise harici bir IP ataması yapar. Bulut sistemlerinde kullanılır.
- ExternalName: İlgili servis tanımında belirli bir DNS ismi girilir. Diğer servis yapıları gibi çalışır fakat uygulama küme dışındadır. İlgili uygulamanın DNS ismi servis dosyasında belirtilir, ve dışarıdaki bir uygulamaya cluster içerisinde bulunan servis aracılığı ile eşleştirilir. İlgili servis çağırıldığında dışarıdaki uygulamaya erişim sağlanır.
KUBERNETES JOB TANIMI
Kubernetes üzerinde belirli bir işin yapılması sağlamak amacıyla kullanılan yapılardır. E-posta gönderilmesi, bir NoSQL database’den veri okumak,silmek, kod dönüştürme, kod oluşturma vb. işlemler için kullanılabilir. Bir Job tanımı oluşturulduktan sonra ilgili Job nesnesine ait ilgili işin yapılmasını sağlayacak şekilde bir veya daha fazla pod oluşturulması sağlanır. Bu podlar iş tamamlandıktan sonra otomatik olarak dururlar. Fakat default olarak silinmezler. Dilersek el ile silebilir veya iş bitiminde otomatik olarak silinmesini sağlayabiliriz. Örnek olarak aşağıda pi sayısını hesaplayan bir Job nesnesine ait yaml dosyası oluşturulmuştur.
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
Çalışma bakımından 3 tür job tanımı vardır. Bunlar;
- Paralel olmayan işler(Tek bir pod olan işler)
- Sabit tamamlanma sayısı olan (Belirlenen sayıda pod ve paralel olarak çalışan podların olduğu işler)
- Çalışma kuyruğuna sahip olan işler.
- Paralel olmayan işlerde completions ve parallelism değerleri girilmeden yapılan Job türleridir. Bu değerler belirtilmediğin de default olarak değeri 1’dir. Bu job türünde işlerin tamamlanması için sadece bir pod çalışır ve işlem tamamlandığında kapanır. Yukarıda pi sayısını hesaplayan job tanımı bu duruma örnek gösterilebilir.
- Sabit tamamlanma sayısına sahip job tanımında ise .spec.comletions kısmında girilen değer kadar işin tamamlanması için belirli sayıda pod çalıştırılması sağlanır.
örnek completions=4 bu durumda işin tamamlanması için 4 adet pod çalıştırılması sağlanır. Ayrıca belirli sayıda podların paralel çalıştırılması sağlanarak işlerin tamamlanması sağlanabilir.Bu ayarı .spec.parallelism kısmında girilen değer kadar paralel pod çalıştırılması sağlanır. Örneğin completions =8 ve parallelism=2 olsun. Bu durumda her defasında iki pod paralel çalıştırılarak toplamda 8 adet pod çalıştırılır.
Bu durumla ilgili örnek kubernetes uygulamalar sayfasında verilecektir. - Çalışma kuyruğuna sahip job türünde ise podlar belirli bir kordine çerçevesinde podların sırayla çalıştırılması sağlanır.
Kubernetes üzerinde job kontrolü job kontrolör tarafından sağlanır. Verilen koşulların değerlendirlmesi ve uygulanması job kontrolör tarafından sağlanır.
Restart Policy= Pod ve içerisindeki konteynırların hata alması durumunda yapılması gereken kuralları belirtir. 3 durum vardır. “Alwyas, Never, OnFailure”. Bu koşullar “.spec.template.spec.restartPolicy =” kısmında belirtilir.
Şimdi durumlara bakalım.
- Pod çalışıyor ve içerisinde bir adet container var hata almadan sonlandı. Bu durum için restart policy her üç durum için pod çalışmasına devam eder.
- Pod çalışıyor ve içerisinde bir adet container var ve container hata alarak sonlandı . Bu durumu inceleyecek olursak;
Always: Pod içerisindeki container tekrar başlatılır.
OnFailure: Bu durumda container tekrar başlatılır.
Never: Container tekrar başlatılmaz. Hata alındığı hatası döner. - Pod çalışıyor ve içerisinde iki adet container var ve bir container hata alarak sonlandı .
Always: Pod içerisindeki container tekrar başlatılır.
OnFailure: Bu durumda container tekrar başlatılır.
Never: Container tekrar başlatılmaz. - Pod çalışıyor ve içerisinde bir adet container var ve ram tamamen doldu ise aşağıdaki durumlar söz konusudur.
Pod arızalanır. Ve kayıtlara hata geçer. Restart policy durumlarında aşağıdaki durumlar yapılır.
Always: Pod içerisindeki container tekrar başlatılır.
OnFailure: Bu durumda container tekrar başlatılır.
Never: Container tekrar başlatılmaz. Hata kayıtlara geçer.
backoffLimit= Bu durum herhangi bir sebebten ötürü podun başarılı bir şekilde oluşturulamadığı durumlarda geçerlidir. Pod başarılı bir şekilde oluşturalamadığında pod tekrar oluşturulmaya çalışılır. Ve deneme için default olarak 6 dakikadır. Ve bu 6 dakika içerisinde (10,20,40 …) gibi üztele saniye değerlerinde yeniden oluşturulmaya çalışılır. Süre sonunda pod’un tekrar oluşturulması sağlanmaz. İlgili ayar .spec.backoffLimit kısmında yapılır.
activeDeadlineSeconds= Bir iş tamamlandığında otomatik olarak silinmez. Hataları, uyarıları ve diğer bilgileri almak için job’lar silinmez.Bir job silinmek istenirse kubectl delete job job_name komutu kullanılarak job silinmesi sağlanır. Ancak job silinmesi için bir süre belirleyebiliriz. Bu süre sonunda iş tamamlanmış olsada olmasada bu komut aracılığı ile iş sonlanır. Burada verilen süre saniye cinsindedir. .spec.activeDeadlineSeconds satırında ilgili değer ayarlanır. Aşağıda bu duruma örnek olarak yaml dosyası verilmiştir.
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-timeout
spec:
backoffLimit: 5
activeDeadlineSeconds: 100
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
Bitirilen işler default olarak otomatik olarak temizlenmezler. İstenildiği taktirde el ile silinebilir. İstersek biten işleri otomatik olarak silinmesini sağlayabiliriz.
.spec.ttlSecondsAfterFinished : Bu ttl denetleyicisi olarak iş bitiminde işin silinmesini sağlayan yapıdır. Girilen değer saniye cinsindedir. İş başarılı olarak sonuçlandığında verilen saniye cinsinden değer sonrasında işi oluşturulmuş podlarıyla birlikte silinir. Aşağıda bu durumla ilgili örnek mevcuttur. Örnekte iş tamamlandıktan 100 saniye sonra işin silinmesini sağlayacak şekilde değer girilmiştir.
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-ttl
spec:
ttlSecondsAfterFinished: 100
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
NOT: Bir iş nesnesi oluşturulduğunda .spec.selector kısmı belirlenmedikçe otomatik olarak diğer job nesneleri ile çakışmayacak şekilde oluşturulur. Eğer belirtmek istersek diğer job nesneleri ile çakışmayacak şekilde yapmamız gerekir. Bu durum dikkat edilmeden yapılırsa diğer job nesnelerine ait podları kendi pod’u gibi görerek işleme alır veya diğer kontrolcülere(deployment, replicaset) ait podların yanlış çalımasına sebebiyet verebilir bu nedenle başka sonuçların oluşmasını sağlar.
CronJob
CronJob linux/unix sistemlerdeki gibi çalışır. Ayarlanan zamanlama değerinde otomatik olarak çalışan job nesnesidir. Cronjob yedekleme, e-posta gönderimi gibi periyoduk işler için eleverişli bir kullanıma sahiptir. CronJob tanımlaması bazı farklar dışında aynı job tanımlaması gibidir. Ayrıca aşağıdaki şekilde .spec altında zamanlama tanımı yapılır.
schedule: “*/1 * * * *”
Bir CronJob silinmek istediğinde kubectl delete cronjob <cronjob ismi> kullanılarak silinmesi sağlanır.
startingDeadlineSeconds: Bu tanımlama isteğe bağlıdır. Bir iş başlama zamanında herhangi bir sebebten ötürü başlayamazsa , en geç başlama zamanını bu ayar ile belirtebiliriz. Bu alan belirtilmez ise sınır yoktur. Girilecek değer saniye cinsindedir.
Örneğin bu değer 200 olarak ayarlandı. Bir iş enson başarılı çalışma zamanından sonra 200 saniye sonra işin bir daha çalışması sağlanmaz.
Ayrıca bir CronJob denetleyicisi 100 taneden fazla başarısız iş olduğunda o işin çalışmasını sağlamak için pod’un tekrar oluşturulmasını sağlamaz. Örnek verecek olursak bir iş her dakikada çalışacak olsun.Başarılı olarak en son saat 7:00 de çalışmış olsun suan da saatin 9:00 olduğunu varsayalım toplamda 120 dakika geçmiştir. Bu da arada 120 adet işin çalışmadığı anlamına gelir. CronJob denetleyicisi bu sebebten dolayı artık işin çalışmasını sağlamaz.
concurrencyPolicy: Bu tanımlama .spec altında yapılır. Bu tanımlama ile jobların birlikte çalışması gibi durumlar belirtilir. Bu durum aynı CronJob nesnesi ile oluşturulan işler için geçerlidir.
Allow: Bu kısım default olarak ayarlanmış kısımdır. Aynı anda çalışan işlere izin verilir.
Forbid: Bu kısmda eş zamanlı çalımlara izin verilmez. Yeni bir iş çalışma zamanı gelmiş ise ve eski işin çalışması hala devam ediyorsa yeni işin çalışmaya başlatılmaz.
Replace: Bu kısmda eş zamanlı çalımlara izin verilmez. Yeni bir iş çalışma zamanı gelmiş ise ve eski işin çalışması hala devam ediyorsa eski iş sonladırılır ve yeni işin çalışması sağlanır.
suspend: Bu alanda istege bağlıdır. .spec altında tanımlanır. Default olarak false değerindedir. Bu true yapıldığında bundan sonra başlatılacak işlerin bekletilmesi sağlanır.
successfulJobsHistoryLimit ve failedJobsHistoryLimit: Bu alanlarda istege bağlıdır. Tamamlanmış başarılı ve başarısız iş sayılarını tutmak için kullanılır. Default olarak bu değerler sırasıyla 3 ve 1 dir.
KUBERNETES VOLUME TANIMI
Kubernetes üzerinde oluşturulan podlar ve içerisinde bulunan containerlar içerisindeki dosyaların yaşam süresi pod’un yaşam süresi kadardır. Biz bu pod içerisine bağlanıp belirli bir içerisinde yapacağımız değişiklikler sadece o pod’un varlığı süresince geçerlidir. Biz bu pod’u sildiğimizde ilgili verilerin silinmesi kaçınılmazdır. Biz bu verilerin silinmesini istemiyorsak ilgili verilerin container dışında server üzerinde bir klasör içerisinde, ayrı bir depolama üzerinde veya NFS(Network File System) ile ağa bağlı bir disk üzerinde tutulmasını sağlayabiliriz. Bu alanlar üzerinde tutulan dosyalar üzerinde yapacağımız değişiklikler aynı anda container içerisinde de geçerli olacaktır. Ayrıca kubernetes ilgili podlar için kendisi belirlediği bir dizin içerisinde o podlar ile ilgili bir volume oluşturur ve biz pod’u sildiğimiz de o volume’nin de silinmesi sağlanır.
Ben bu konu anlatımında bu işlemlerin nasıl yapılacağına dair sizlere bilgi aktarımı yapacağım.
Volume Türleri
Kubernetes üzerinde bir çok tipte volume desteklemesi sağlanır.Bunlar;
awsElasticBlockStore,azureDisk,azureFile,cephfs,cinder,configMap,cSI,downwardAPI,EmptyDir,fc (fiber channel),FlexVolume,Flocker,gcePersistentDisk,glusterfs,hostPath,iscsi,local,nfs,persistentVolumeClaim,projected,portworxVolume,quobyte,rBD,scaleIO,secret,storageos,vsphereVolume
Yukarıdaki türde volume tipleri vardır. İlgili isme tıklayarak kubernetes sistesi üzerinde bilgi alabilirsiniz. Ben burada persistentetVolumeClaim konusuna değineceğim.
Persistent Volume
Persisten volume claim tanımlanması için öncelikle bu alanı destekleyecek bir Persisten Volume tanımlanması gerekir. Persisten Volume ile biz uygulamamızın dosyalarının bağlanacağı alan için belirli boyutta disk üzerinde yer ayrılmasını sağlarız. Biz bu alanı ayırarak bu alanın talep edilmesi durumunda ilgili ilgili persisiten volume claim talep edicisine bağlanması sağlanır. Yani biz bu kısımda disk üzerinde ilgili alanı talep eden istemciye belirli bir alan ayrılmasını sağlıyoruz. Ayrıca, ayrılacak alanının dizin bilgileri yaml dosyasında belirtilir.Bu konunun uygulamasını buradan bulabilirsiniz.Örnek persistent volume oluşturulmasına dair code aşağıdaki şekildedir.
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
Persistent Volume Claim
Persistent volume claim ile ayrılmış alan talep edilerek o kısım artık talep edicisine bağlanır. Bu yapı ile ilgili alanın talebi yapılır. Bu alan içerisinde de talep edilecek miktar belirtilir ve ilgili kısımdan o alan talep ediciye verilir. Bir talep edici sadece bir talep alanına bağlanır ve o alan için ayrılmış miktarı kullanır. Bu ayarlamalar yapıldıktan sonra ilgili alanın kullanması için pod içerindde ilgili persistent volume claim ismi yazılarak kullanıma sunulur. Örnek persistent volume claim kodu aşağıdaki gibidir.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Strorage Classes
Kubernetes ile ortamda bir pod create edildiğinde pod otomatik olarak kendi dosyalarını belirli bir dizine mount eder. Fakat bu mount alanı pod öldüğünde silinir. Dosyalarımızın kaybolmasını önlemek adına yukarıda anlattığımız gibi PV veya PVC nesnesi kullanırız. Yukarıda yaptığımız işlemler podun çalışacağı sunucu üzerinde bir dizin oluşturarak o dizine dosyalarımızın mount edilmesini sağlayarak yaptığımız işelmelerdir. Storage classes tanımında bu biraz farklıdır. Örnegin NFS türünde bir storage class kullanıldığı zaman, oluştıracağımız PVC tanımları otomatik olarak storage class üzerinde kendisine ait PV nesnesi oluşturulmasını sağlayarak bağlanır. Bu durumu dinamik provision olarak tanımlarız. Bu storage alanı network ile ulaştığımız başka bir sunucu üzerinde bulunan yada belirli bir diskin tanımlı olduğu alandır. Ve PVC tanımı ile oluşturduğumuz podlarımızı dosyalarını o alan üzerinde tutar. Bu arada araya network katmanı girdiği için sistem biraz daha yavaş çalışır yada sistemde kopmalar yaşanabilir. Bu durumda başka bir storage class kullanma gereği duyabiliriz. Kubernetes için birden fazla storage class türü vardır. Bunlar avantaj ve dezavantajlarına göre ayrılırlar. Ve bizlere seçim yapmamız için yardımcı olurlar. Storage class kurulumunda bazı alanların girilmesi zorunludur. Bu alanlar, provisioner, parameters, reclaimpolicy alanlarıdır. Kubernetesin kendi sayfasında daha çok bilgi edinilebilir. Buradan. Ayrıca örnek storage clas kurlumu ve buna bağlı PVC ve PV oluşturulması hakkında yazıma göz atabilirsiniz.
VAKİT BULDUKÇA YAZMAYA DEVAM EDECEĞİM.
No responses yet