Kubernetes Notlarım I — Kubeadm ile K8S Cluster Kurulumu

Merhabalar, bu yazımda kubernetes platformundan ve bileşenlerinden bahsedeceğim, beraberinde kubectl aracını kuracak ve kubeadm ile bir kubernetes cluster’ı oluşturacağım. Bir seri olarak yazmayı planlıyorum. Serinin ilk yazısı için keyifli okumalar.. 😊

Kubernetes, CNCF (Cloud Native Computing Foundation) tarafından yönetilen (başlangıçta Google’ ın tasarladığı), açık kaynak bir container orkestrasyon aracıdır. Aslında bakarsanız işlevi düşünüldüğünde yetersiz bir tanım oluyor, içine girdikçe bu tanıma eklemeler yapıyor olacaksınız.

Peki container orkestrasyon nedir? Kısaca, çalışan çok sayıda container bulunduğu durumda onları kolayca yönetmek ve idare etmek için bir yol diyebiliriz.

Kubernetes resmi sitesinde nasıl tanımlanıyor bakalım.

K8S, hem beyan temelli yapılandırmayı hem de otomasyonu kolaylaştıran container iş yüklerini ve hizmetlerini yönetmek için oluşturulmuş, taşınabilir ve genişletilebilir açık kaynaklı bir platformdur.

Sektörde standart diyebiliriz, evet alternatifler var fakat orkestrasyona yaklaşım şekli ve mimarisi, bir kuruluşa bağlı olmadan vakıf tarafından destekleniyor olması gibi sebepler kubernetes’i standard haline getirmiş diyebiliriz.

Platform tamamen modüler bir şekilde tasarlanmış ve bu şekilde de çalışıyor. K8s adında tek bir uygulama yok, k8s platformunu oluşturan bir çok servis mevcut ve bu servislerin bir arada düzgün kurgulanması sonucu k8s platformu oluşuyor.

Mimariyi ve modüler yapıyı anlamak adına resmi sitesinde yer alan resim üzerinden komponentlere ve detayına bakalım.

Control planede master node dediğimiz yönetim nodeları yer alıyor. kube-apiserver, etcd, kube-scheduler ve kube-controller-manager komponentleri master node dediğimiz sistemler üzerinde çalışıyor. Master nodelar üzerinde iş yükü çalıştırmayız, burası yönetim altyapımızdır.

Diğer alanda ise worker nodelar çalışıyor ve her worker node üzerinde kubelet, kube-proxy ve container runtime bileşenleri yer alıyor. İş yükleri (podlar) bu nodelar üzerinde çalışır.

Control Plane Bileşenleri

kube-apiserver

Control plane’in en önemli bileşeni, k8s’in beyni diyebiliriz. Diğer tüm komponentlerin, node bileşenlerinin ve dış dünyadan k8s platformu ile iletişim kuran tüm servislerin direkt olarak iletişim kurabildiği tek komponenttir. K8S’de kaynak oluşturma isteklerinin api doğrulamasından sorumludur. Kullanıcılar kubectl istemcisi ile veya rest api çağrıları ile kube-apiserver ile iletişim kurabilirler.

etcd

Tüm cluster’ın verisi, metadata bilgileri ve K8S’ de oluşturulan tüm objelerin bilgilerinin tutulduğu anahtar-değer (key-value) veri deposudur. Kısacası k8s’in çalışması için gerekli olan veriyi üzerinde tutar.

  • Cluster’ın mevcut durumu ile ilgili veriyi üzerinde barındırır.
  • kube-apiserver hariç hiçbir bileşen direkt olarak etcd ile iletişime geçemez. İletişim gerektiğinde kube-apiserver aracılığıyla bunu yaparlar.

kube-scheduler

Yeni oluşturulan ya da bir node ataması yapılmamış podları izler ve üzerinde çalışacakları bir node seçer. Pod’un üzerinde çalışması için en uygun node’a karar verir.

kube-controller-manager

Mantıksal olarak her controller ayrı bir süreçtir, ancak karmaşıklığı azaltmak için hepsi tek bir binary olarak derlenmiştir ve tek bir process olarak çalışır. Bu controllerların bazıları şunlardır:

  • node controller
  • job controller
  • service account & token controller
  • endpoints controller

K8S cluster’ın mevcut durumuyla ondan istenen durum arasında fark olup olmadığını gözlemler. kube-apiserver aracılığıyla etcd’de saklanan cluster durumunu izler. Eğer mevcut durum ve istenen durum arasında fark varsa bu farkı oluşturan kaynakları gerektiği gibi oluşturur, günceller veya silerek bu farkı kapatır.

Yukarıda değindiğimiz bu 4 komponent ( kube-apiserver, etcd, kube-scheduler, kube-control-manager) K8S’in yönetim ksımında yer alır. Control plane olarak adlandırılan bu yönetim alanı master node dediğimiz sistemler üzerinde çalışır. Tüm bu komponentler tek bir linux sistem üzerine de kurulabilir veya high availability (HA) bir yapı sağlamak isteniyorsa ayrı sistemler üzerine de kurulabilir. Biraz sonra kendi localimizde nasıl K8S cluster’ı dağıtabiliriz bundan bahsediyor olacağım.

Worker Node Bileşenleri

İş yüklerimiz worker node dediğimiz sistemler üzerinde koşar. İş yükü dediğimiz şey burada podlarımız yani containerlarımız oluyor. Üzerlerinde bir container rumtime (containerd, cri-o veya docker gibi) barındırırlar. Her worker node aşağıdaki 3 temel komonenti barındırır.

  • kubelet
  • k-proxy
  • container runtime (Varsayılan dockerdı bazı nedenlerden dolayı desteğini bırakıp containerd’ye geçti.)

Bu bileşenleri inceleyelim.

kubelet

kube-apiserver aracılığıyla etcd’yi kontrol eder ve kube-scheduler tarafından bulunduğu node üzerinde çalışması gereken pod belirtildiyse kubelet bu podu o node üzerinde oluşturur. Bunu yaparken containerd’ ye haber gönderir ve belirtilen özelliklerde bir container’ ın o sistemde çalışmasını sağlar.

kube-proxy

Oluşturulan podların ağ kurallarını yönetir. Bu ağ kuralları cluster’ ın içindeki veya dışındaki ağ oturumlarından podlarınızla ağ iletişimine izin verir. Kısacası network proxy görevi görür.

container runtime

Containerları çalıştırmaktan sorumlu olan yazılımdır. Kubernetes; containerd, CRI-O gibi contaner runtimeları ve Kubernetes CRI’nın (Container Runtme Interface) diğer tüm uygulamalarını destekler.

İşin sistem tarafında yer alıyor uzun vadede bir K8S ortamı yönetiyorsanız bu yapıyı iyi anlamak ve çalışma mantığını bilmek önemlidir.

Yukarıda kube-apiserver isimli bir komponentten bahsetmiştik. Tüm cluster kopmonentleri ve dış dünyadan bizler bu apiserver ile iletişime geçiyorduk. K8S cluster üzerinde bir işlem yapmak istiyorsak yani k8s’e bir komut vermek istiyorsak bunu kube-apiserver üzerinde yapıyoruz. Bunu gerçekleştirebilmenin ise 3 yöntemi var:

  • Rest API çağrıları üzerinden iletişime geçebiliriz. Fakat her işlemi bu şekilde gerçekleştirmek oldukça zor.
  • GUI istemcileri (apiserver ile iletişim kurmak için tasarlanmış çeşitli arayüzler) ile iletişime geçebiliriz.
  • Kubectl resmi CLI aracı ile kubernetes cluster’ına komutlar gönderebiliriz.

Örnek olarak bir Kubernetes Cluster’ı oluşturmak istiyorum. Fakat öncesinde kubectl aracını sistemimize kurmamız ve daha sonra kubernetes cluster’ı kurmamız sonrasında ikisi arasındaki bağlantıyı yapmak doğru olacaktır.

Kubectl aracını kurmak için bu bağlantıdan sisteminize uygun yönergeleri takip edebilirsiniz.

Ubuntu dağıtımını kullandığımdan Debian-based sistem üzerine native paket yönetimi metodunu kullanarak kuruluma yapacağım. Siz dilerseniz homebrew paket yöneticisi ile daha kolay kurulum yapabilirsiniz veya curl ile kubectl binary dosyasını yükleyerek kubectl kurulumunu yapabilirisiniz. Adım adım gidelim.

$ sudo apt update & sudo apt-get install -y ca-certificates curl

Debian 9 veya önceki bir sürümünü kullanıyorsanız apt-transport-https’yi de yüklemeniz gerekiyormuş. Benim öyle olduğundan bunu da yükledim :)

$ sudo apt-get install -y apt-transport-https

Google Cloud public signing key’ini de yükleyelim.

$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

Daha sonra Kubernetes repository’sini ekleyelim.

$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" /
| sudo tee /etc/apt/sources.list.d/kubernetes.list

Son adımda apt paket dizinini yeni depoyla güncelleyelim ve kubectl’i kuralım.

$ sudo apt-get update & sudo apt-get install -y kubectl
$ sudo apt-get install -y kubectl

Şimdi kontol edelim kubectl aracını kurabilmiş miyiz ve versiyonu ne?

$ kubectl version --client --output=yaml

Kubectl aracını kurduk şimdi ise K8S cluster’ ı nasıl kurabileceğimize bakalım. Burada karşımıza bir çok seçenek çıkıyor. Test ve geliştirme gibi işlemler için kendi localimize ufak bir k8s kurmak istiyorsak, minikube veya docker desktop en uygun araçlar olabilir. Eğer bir kaç sanal makine oluşturarak production sistemler gibi tam bir k8s cluster’ı oluşturmak istiyorsanız kubeadm, kubespray, RKE ve k0s gibi bir çok aracı deneyimleyebilirsiniz. Aynı zamanda public cloud firmalarının sunduğu (Azure Kubernetes Service, Amazon EKS, Google Kubernetes Engine) yönetilen k8s hizmetlerini de kullanabilirsiniz.

Ben kubeadm kullanarak kurulumu yapmak istiyorum, o sebeple bu yazımda bunu ele alacağım.

Öncesinde kendi sanallaştırma ortamımda iki adet vm ayağa kaldıracağım ve üzerine bir linux distrosu yükleyeceğim. Bu iki makineden birisi control plane olarak yapılandırılacak diğeri ise worker nodeları üzerinde barındıracak. Fakat burda tek tek vm oluşturup işletim sistemi kurmayla vs uğraşmadan komut satırından kolayca sanal makine oluşturmamızı sağlayan multipass aracını kullanacağım. Bu adresten aracı inceleyebilirisiniz.

Multipass aracını kullanarak parametreler ile belirlediğimiz kaynaklara göre iki tane sanal makine oluşturalım.

$ multipass launch --name masters -c 2 -m 2G -d 10G
$ multipass launch --name worker -c 2 -m 2G -d 10G

İki makineyede bağlanıp shell alalım.

$ multipass shell masters
$ multipass shell worker

İki makine için de iptables bridge traffic ayarlarını da aşağıdaki gibi yapalım.

$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sudo sysctl --system

İkinci yapmamız gereken ise bu sistemlere bir container engine kurmak, ben containerd kuracağım. Bunun için aşağıdaki adımları izleyelim.

$ cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
$ cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
$ sudo sysctl --system$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get install containerd -y
$ sudo mkdir -p /etc/containerd
$ sudo su -
$ containerd config default | tee /etc/containerd/config.toml
$ exit
$ sudo systemctl restart containerd

Şimdi K8S cluster kurulumu için bizim kullanacağımız kubeadm aracını kuralım.

$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl
$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl

Sonunda geldik kubernetes kurulumuna.. kur kur bitiremedik, şimdi hazırız. 😃

Aşağıdaki işlemleri master node üzerinde yapmalı ve worker node’ u daha sonra cluster’a dahil etmelisiniz.

İlk olarak k8s kurulumu için gerekli olan imajları çekelim.

$ sudo kubeadm config images pull

Aşağıdaki init komutuyla bir k8s cluster oluşturuyoruz. Bu komutu çalıştırdığınız yer master node olacak, kubeadm bu makineyi master node haline getirecek. apiserver-advertise-address ve control-plane-endpoint master node makinesinin IP adresi, cidr kısmına bir sonraki yazımda ayrıntılı değineceğim, şimdilik kurulumu tamamlayalım.

$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=<IP> --control-plane-endpoint=<IP>

kubectl ile bu makineye bağlanabilmek ve onu yönetebilmek gerekiyor. Bunun için gerekli yapılandırmaları yapalım.

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

Artık kubectl aracını kullanarak k8s cluster’ı ile iletişim kurabiliyorum.

$ kubectl get nodes

Şimdi ise bu cluster’a master veya worker rolüne sahip yeni node’lar ekleyebilirim. Aşağıda komutun çıktısında da bahsettiği gibi master veya worker node eklemek istersem bir dizi komut kullanarak bunu yapabilirim.

Ben bir worker node dahil ediyorum. Bunun için worker node üzerinde bana verdiği aşağıdaki komutu çalıştırıyorum.

$ kubeadm join 10.122.52.30:6443 --token 3ggru0.q59zb4knopl4rcm8 --discovery-token-ca-cert-hash/ sha256:a55bbc268e3a116dc9a32a2c5ffd98c5b5132ab7cad4d511d61c2e72a47a94e3

Bakalım dahil edebilmiş miyiz?

Farkettiyseniz cluster ayakta ama node’lar henüz Ready duruma geçmemiş. Bunun nedeni kurduğumuz cluster varsayılan olarak bir network altyapısı ile gelmez. Bunun için bir plugin kurmak gerekiyor. Aşağıdaki komutları kullanarak bunu da kurabiliriz.

$ kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml$ kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml

Bir süre sonra node statülerinin Ready duruma geçtiğini göreceksiniz. Artık kurulumu tamamlamış bulunuyoruz.

Bir sonraki yazımda pod, namespace, label ve selector, deployment, service, replicaset gibi bir çok kavrama değinmeyi düşünüyorum. Şimdilik görüşmek üzere diyorum :)

May The Kubernetes Be With You 🌟 😉

Originally published at https://zeyneprumeysayorulmaz.github.io on August 6, 2022.

--

--