Kubernetes — 1

K8s nedir?
Kubernetes, bir konteyner otomatik konuşlandırma, yönetme ve ölçeklendirme sistemidir.
- 2014 yılında Google tarafından üretildi.
- Temmuz 2015'te opensource cloud native olarak yayınlandı.
- Go diliyle yazıldı.
- İlk olarak “Project Seven” olarak isimlendirilmek istenilmiş olsa da Star Trek serisindeki “Seven of Nine” karakterini ismini almıştır. Son olarak Yunanca bir kelime olan “Helmsman” — yani gemiyi yönlendiren kişi — kelimesinden türetilip Kubernetes isimine almıştır.
- “k8s” olarak isimlendirilir. “k” ve “s” harflerinin arasında 8 karakter olmasında dolayı ortasına 8 sayısı gelmiştir.
Niye?
Konteynerlerin ve mikro-servislerin getirdiği yeni yönetim zorluklarına K8s bize kolaylıklar ve çeşitli yetenekler sağlar.
Örneğin konteynerleştirilmiş uygulamamızı herhangi K8s nesnesi (Pod, Deployment gibi) içerisinde K8s’e gönderdiğimizde arkada yapılması gerekecek tüm zor işleri bizim için halledecek. Bu zor işlere örnek vermek gerekirse Deployment nesnesi ile konuşlandırdığımız bir konteynerleştirilmiş uygulama çalışması sırasında herhangi bir sebepten dolayı durmasın sonucunda, Deployment tekrar yeni bir konuşlandırma işlemi gerçekleştirerek uygulamayı çalışır hale getirir. Bu işleme kendini iyileştirme (self-healing) denir.
Bulutta Yerel Mikro-Servisler (Cloud Native Microservices)

Monolit Mimari(Monolit Architecture) bir uygulamanın bir bütün halinde oluşturulmasına denir. Tek bir uygulama içerisinde gerekli tüm işlemlerin tek bir yapı içerisinde gerçekleşmesidir. Yani, ölçümlerin görselleştirilmesi, veri tabanı kayıtlama ve okuma, kimlik doğrulama, web sunucu çalıştırma gibi işlemlerin tek bir uygulamada gerçekleştirilmesidir.
Mikro-Servis Mimari bundan farklı olarak bu işlemlerin yani her uygulamanın bağımsız uygulamalar halinde oluşturulmasına denir. Buna Uygulama servisi (Application service) yada servis olarak da isimlendirilir. Böylece, uygulamaların bağımsız olarak geliştirilmesi mümkün olur.
Yerel Bulut (Cloud Native) kavramıyla birlikte ve API’ler sayesinde dinamik ve gevşekçe bağlanmış (loosely coupled) mimari elde ederiz.
Kubernetes Mimarisi

K8s, mikro-servislerin birlikte bir takım halinde çalışmasını sağlayan bir orkestratördür.

Kubernetes büyük resmini birazcık görebilmek için görseli inceleyelim. Bu yapıya K8s Cluster denir. Bu yapı içerisinde master ve node’lardan oluşmaktadırlar. Burada master tüm sürecin yönetilmesinde baş rolü oynayan kişidir. Ayrıca, Kontrol Düzelemi (Control Plane) olarak adlandırılı ve birden fazla master olabilir. Node ise bizim işçilerimizdir. Master tarafından atanan işlerin yapılmasından sorumludurlar. Bunun haricinde node’lar içerisinde çalışan uygulamaların durumlarını sürekli olarak master’a bildirir. Böylecek sistemin sağlık olduğunda sürekli emin olurlar.
Master
Multi-Master H/A (High Availability) Control Plane : Master’lar her zaman erişebilir olmaları gerekmektedir. Bu yüzden birden fazla master oluşturmak her zaman bizim için önemlidir. Çoklu master yapısında bir master liderlik görevini alırken diğerleri onu takip eder. Herhangi bir request meydana geldiği zaman bu işlemler lider master tarafından işlenir. Eğer lider master çalışmaz hale gelirse hemen diğer master’lardan birisi onun görevini üstlenir.
High Availability hakkında fazlası: https://kubernetes.io/docs/tasks/administer-cluster/highly-available-master/
Master’lar sadece Linux makinalar üzerinde koşturulabilirler. Fiziksel yada sanal makina olmaları önemli değildir.

Master bileşenleri:
kube-apiserver:
- Kontrol düzlemi için bir ön uçtur (frontend).
- Kubernetes API’yi açığa çıkarır. Böylece, uzaktan erişim için bizim kapı görevlimiz olarak görev yapar.
- JSON/YAML dosyalarıyla tanımladığımız K8s nesneleri(Pod, Deployment gibi) API Server ile Master’a ulaştırırız.
Cluster Store:
- Tüm cluster’ın durum, config ve çalışan uygulamaların bilgileri burada depolanır.
- etcd üzerine kurulmuştur. “etcd” dağıtılmış sistemler için dağıtılmış anahtar-değer deposu olarak tanımlanır.
kube-controller-manager:
- Kendilerine özgü sorumluluklara sahip kontrolcüler buradadır. (Node Kontrolcü, Deployment Kontolcü, Namespace Kontrolcü vs.)
- Her biri uzlaşma döngüleri (reconciliation loop) olarak çalışır. Sorumlu olduğu parçaların değişiklerini takip eder ve istenildiği durumlarda çalıştıklarından emin olurlar.
kube-scheduler:
- Yeni gelecek işler için sürekli API Server’ı takip eder.
- İşlerin, cluster node’lara atamalarını gerçekleştirir.
Basitçe çalışmasını özetlemek gerekirse kubectl komutu ile apiserver’a erişim sağlanır. Örneğin bir uygulama deploy etmek istiyoruz. Öncelike, uygulama için istenen durum (uygulamanın sürekli olarak 5 tane kopyasının çalışır halde olması gibi) Cluster Store’da depolanır. Sonra, kube-scheduler uygulama için iş görevini oluşturur. Ardından, çeşitli kontrolcüler bizim için Cluster’ı takip ederek bizim istediğimiz durumda çalıştıklarından emin olurlar.
K8s elemanları hakkında fazlası: https://kubernetes.io/docs/concepts/overview/components/
Node
Konteynerleştirilmiş uygulama Node içerisinde Pod nesneleri ile sarılmış halde çalışabilirler.
Linux ve Windows makineler üzerinde çalıştırılabilirler. Yine aynı şekilde fiziksel yada sanal makine olmaları önemli değildir.

Node bileşenleri:
kubelet:
- Konteynerin bir Pod içerisinde istenildiği durumda çalıştığında emin olur. Sağlıklı olup olmadığının kontrolünü gerçekleştirir.
- apiserver’i yeni gelecek işler için takip eder.
- Çalışan uygulamanın durumlarını Master’a rapor eder.
container runtime:
- Konteynerların koşturulmasından sorumludur.
- Container Runtime Interface (CRI). Herhangi konteyner teknolojisi faydalanabiliriz(Docker, containerd ve CRI-O).
kube-proxy:
- Node’lardaki ağ kurallarını yönetir. Bu ağ kuralları Cluster içinden veya dışından Node’lara erişimlerini yönetir.
- Her Pod için bir IP adresi atamasını gerçekleştirir. IP adresi statik veya dinamik olabilir.
- Basit Load-Balancing işlevi vardır.
Declarative Model Imperative Model
Impretaive Model: Yapılması istediğimiz işlemleri bir komut satırında belirtiriz. Mesela,
kubectl apply -f pod.yml
komutu ile yapacağı işi söylemiş böylece kubectl gidip “pod.yml” dosyasını bizim için apiserver’a iletilmesini ve işlenmesini sağlamış olduk.
Declarative Model: Bir <yaml> dosyasında yapılması istediğimiz işlemleri detaylıca tanımlarız. Ardından K8s bu dosya içerisindeki işlemleri gerçekleştirir. Yeni bir eve taşınmak istediğimizi düşünelim. İstediğimiz evi bir emlakçıya tanımlarsak, emlakçı istediğimiz özelliklerde bu evi bize bulup kirayacaktır.

Declarative ve Imperative Modeller hakkında fazlası: https://medium.com/@dominik.tornow/imperative-vs-declarative-8abc7dcae82e#:~:text=Kubernetes-,Kubernetes%20is%20a%20declarative%20system.,ReplicaSet%20or%20Deployment%2C%20for%20example.
Pod
Docker dünyasında konteynere karşılık gelir.
- Pod, konteynerlerin hayat bulduğu nesne ve konteynerin bilgilerini tutar.
- Bir Pod içerisinde birden fazla konteyner yapısı oluşturulabilir. Ancak bir Pod içerisindeki konteynerler bütün çevreyi paylaşırlar.

- K8s’de scale-up ve scale-down Pod ekleyip, çıkarmak ile gerçekleştirilir, container ekleyip, çıkarmak ile değil. Bir Pod yaşam döngüsü Docker’da konteynera benzerdir. Doğar, yaşar ve ölürler. Self-healing, scaling-up gibi işlemler için Deployment kontrolcüsüyle ihtiyacımız vardır.
- Her Pod bir Node’a atanır. Böylece, Master Cluster içerisindeki her node eşit oranda yük dağılımını gerçekleştirir. Tabi istediğiniz node içerisindede Pod’ları konuşlandırılması mümkündür.
- Çoklu konteyner yapısında bir Pod içerisindeki bazı konteynerler çalışır hale gelse bile tüm konteynerler çalışır hale gelmedikçe Pod “running” durumuna gelmez.
Neden Pod’a ihtiyacımız vardır?
Ek açıkmalar(Annotation), etiketleme(labeling) yapılmasına olanak sağlar. Ayrıca poliçe, kaynak ve konteynerin yönetimi ve daha fazlasını yapmamıza imkan sağlar.
Service
Bir Pod oluşturduğumuzda bir IP ile birlikte gelir. Eğer scale-up işlemi gerçekleştirirsek yeni oluşacak bir Pod bize yeni bir IP ile gelecek. Belli bir noktadan sonra port IP’leriyle işlemlerimizi gerçekleştirmekte zorluk yaşayabiliriz.
Service doğabilecek bu probleme çözüm olmakla birlikte farklı yeteneklerde sağlar.
Günlük yoğunluğa göre çoklu web sunucularımızın olduğunu düşünelim. Herhangi bir web sitesin erişmek istediğimiz zaman bizim sadece bildiğimiz tek bir adresi olur ve bu adres üzerinden aktif olan web sunucularından birinden hizmet alırız. Bu olayı tamamiyle Service bizim için yönetir. Gün içerisinde yoğunluğun artmasıyla birlikte yeni bir web sunucusu ayaklandığında otomatik olarak Service bu sunucuyu listesine alır ve aktif olarak hizmet vermesini sağlar.

Etiket Seçici(label selector): Yukarıdaki görseli incelersek, Service’te tanımlanan etiketlerle eşleşen Pod’lar sadece hizmete alınırlar. Yani yukarıdaki örnekte “prod”,”be” ve “1.4” etiketleriyle eşleşen Pod’lar sadece Service’e dahil edilirler. “1.3” etiketine sahip olan Pod’ları “1.4”’te hata oluşma ihtimaline karşı tutabilirsiniz.
- Sadece sağlıklı Pod’lara trafiğe dahil olabilirler.
- Cluster dışarısıyla trafik oluşturabilir.
- TCP yada UDP protokollerini desteğide bulunur.
Deployment
Deployment, Pod’un gelişmiş özelliklere sahip versiyonu diyebiliriz.
- Pod’lar Deployment’lar tarafından yönetilir
- Kendini iyileştirm(self-healing), çoğalmak (scale-up), güncelleme (rolling updates) gibi yetenekleri sağlar.
- Deployment durum bilgisi olmayan uygulamalar (stateless apps) için kullanırız. Durum bilgisi olan uygulamalar için StatefulSets, her bir node’da bir pod için DeamonSet gibi K8s kontrolcüler vardır.
Kontrolücü hakkında fazlası: https://kubernetes.io/docs/concepts/workloads/controllers/
Kendini iyileştirme örneği verecek olursak, konuşlandırılmış bir Deployment kontrolcüsü sürekli olarak Node içerisindeki Pod’ları izler ve istenen durum(desired state) ve izlenen durumun(observed state) korunmasını sağlayarak gerçekleştirmiş olur.

Şuana kadar geldiğimiz noktaya bakarsak çok fazla içe içe geçmiş bir yapı oluşmuş durumda olduğu görürüz. Aşağıdaki görseli incelersek en içeride konteyner haline getirilmiş uygulamamız, onun üstünde Pod, onun üstünde ReplicaSet ve son olarak Deployment şeklindedir.

K8s API ve API Server
Buraya kadar bahsettiğim Deploy, Pod ve Service aslında K8s API içerisinde kendine has özellikleri ve yetenekleri olan birer nesneleridir. K8s API’yı nesnelerin her birinin nasıl çalıştığının tanımlandığı bir katalog olarak düşünebilirsiniz.

API, nesnelerin hepsinin bilgisine sahiptir. Bir nesneyi <yaml> dosyasıyla tanımlayıp API Server’a gönderdiğimiz zaman API gelen nesnenin içerisinde doldurulan alanların ne olduğunu bilir ve ihtiyaçlarımıza göre koyteynerleştirme işlemini gerçekleştirir.
API Server bizim API’ya erişim aracımızdır. Bu iş için ise “kubectl” komutuyla erişim sağlarız. “kubectl” config ile erişim sağlamak sağlanacak K8s Cluster bilgilerini tanımlarız.
- API Server’a HTTPS üzerinden erişim sağlanır
- Bir RETFUL API’dir.

Diğer Notlarım: