Pratik Bilgiler ve Komutlar: Kubernetes
Merhabalar. Pratik bilgiler ve komutlar serimizin bu yazısında Kubernetes ile ilgili işinize yarayacağını düşündüğüm pratik komut ve bilgilere yer vereceğim. Kubernetes bir container orchestration aracıdır. Hatta mevcutların en popülerlerindendir. 2015 yılında ortaya çıkmasına rağmen geniş bir kullanıma kavuştu. Tabi bunun arkasında Google’dan neşet etmesi ve Google tarafından kullanıyor olmasının payı büyük.
- Kubernetes cluster bilgisini nasıl öğreniriz?
- Kubernetes Cluster Node Listeleme
- Kubernetes Cluster Pods Listeleme
- Kubernetes create a deployment with yaml file
- Kubernetes cluster içindeki uygulamayı dışarıdan erişime açmak(NodePort servisi eklemek)
- Kubernetes NodePort ve Pod nesneleri nasıl eşleşir?
- Kubernetes servisleri listeleme
- Kubernetes cluster üzerinde çalışan uygulamaya erişim
- Kubernetes deployment silme
- Kubernetes deployment of image (yaml dosyası olmadan)
- Kubernetes scale a deployment (mevcut olanı daha fazla replica ile çalıştırmak, ölçeklemek)
- Kubernetes mevcut tüm deployment, serviceve replicas listeleme (kubectl get all)
- Kubernetes LoadBalancer servisi eklemek
- Kubernetes birden fazla obje silmek (servis örneği)
- Kubernetes generator kullanarak deployment yaml dosyası oluşturmak
- Kubernetes deployment yöntemleri nelerdir?
- Kubernetes cluster içinde bir nesneyi (object) benzersiz kılan özellikler nedir?
- BASE64 ile Secret Oluşturma
- Set-context ile varsayılan namespace değiştirme
- Namespace içindeki tüm podları silme
Kubernetes cluster bilgisini nasıl öğreniriz?
[root@master-node simplek8s]# kubectl cluster-info Çıktı: Kubernetes master is running at https://192.168.206.31:6443 KubeDNS is running at https://192.168.206.31:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Kubernetes Cluster Node Listeleme
Kubernetes cluster dahilinde bulunan node’ları listeleme
[root@master-node ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master-node Ready master 22h v1.18.2 worker-node1 Ready <none> 22h v1.18.2 worker-node2 Ready <none> 22h v1.18.2
Kubernetes Cluster Pods Listeleme
Pod bir amaca yönelik gruplanmış ilgili bir veya daha fazla (ama genellikle bir) konteynerlerden oluşan bir kavramdır. Kabaca docker konteynerin Kubernetes karşılığıdır. Kuburnetes içinde konteyner çıplak olarak çalışamaz. Pod’ları listelemek için:
[root@master-node ~]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-75d56dfc47-zkz8m 0/1 CrashLoopBackOff 30 7h41m kube-system calico-node-9nzl9 1/1 Running 1 7h41m kube-system calico-node-mfzzq 1/1 Running 1 7h41m kube-system calico-node-xfc8m 1/1 Running 1 7h41m kube-system coredns-66bff467f8-82gmg 0/1 Running 1 22h kube-system coredns-66bff467f8-nlbfw 0/1 Running 1 22h kube-system etcd-master-node 1/1 Running 2 22h kube-system kube-apiserver-master-node 1/1 Running 2 22h kube-system kube-controller-manager-master-node 1/1 Running 2 22h kube-system kube-proxy-6lcb8 1/1 Running 2 22h kube-system kube-proxy-rscqb 1/1 Running 2 22h kube-system kube-proxy-zp9bz 1/1 Running 2 22h kube-system kube-scheduler-master-node 1/1 Running 2 22h
Daha geniş bilgilerle özellikle hangi pod hangi node üzerinde görmek için komuta -o wide eklemek yeterlidir.
[root@master-node ~]# kubectl get pods --all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-75d56dfc47-zkz8m 0/1 CrashLoopBackOff 31 7h45m 192.168.180.196 worker-node1 <none> <none> kube-system calico-node-9nzl9 1/1 Running 1 7h45m 192.168.206.32 worker-node1 <none> <none> kube-system calico-node-mfzzq 1/1 Running 1 7h45m 192.168.206.33 worker-node2 <none> <none> kube-system calico-node-xfc8m 1/1 Running 1 7h45m 192.168.206.31 master-node <none> <none> kube-system coredns-66bff467f8-82gmg 0/1 Running 1 22h 192.168.180.195 worker-node1 <none> <none> kube-system coredns-66bff467f8-nlbfw 0/1 Running 1 22h 192.168.203.130 worker-node2 <none> <none> kube-system etcd-master-node 1/1 Running 2 22h 192.168.206.31 master-node <none> <none> kube-system kube-apiserver-master-node 1/1 Running 2 22h 192.168.206.31 master-node <none> <none> kube-system kube-controller-manager-master-node 1/1 Running 2 22h 192.168.206.31 master-node <none> <none> kube-system kube-proxy-6lcb8 1/1 Running 2 22h 192.168.206.31 master-node <none> <none> kube-system kube-proxy-rscqb 1/1 Running 2 22h 192.168.206.32 worker-node1 <none> <none> kube-system kube-proxy-zp9bz 1/1 Running 2 22h 192.168.206.33 worker-node2 <none> <none> kube-system kube-scheduler-master-node 1/1 Running 2 22h 192.168.206.31 master-node <none> <none>
Buradaki IP adresleri sadece Kubernetes cluster içinde geçerlidir.
Kubernetes create a deployment with yaml file
Aşağıda bir nginx sunucusu için deployment yapacağız. Nasıl docker imajları için yaml dosyaları oluyorsa kuburnetes objeleri için de öyle. Bir yaml dosyasında tanımlayacağımız Deployment objesini deploy edeceğiz. Diğer yaygın object türleri Pod ve Service’dir. Obje türü yaml dosyasında kind etiketiyle belirtilir. deploy_nginx.yaml dosyası içeriği:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
Deployment komutu:
[root@master-node ~]# kubectl create -f deploy_nginx.yaml Bilgi çıktısı: deployment.apps/nginx created
Deployment’ı görelim:
[root@master-node ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-5bf87f5f59-5m4xv 1/1 Running 0 12s nginx-5bf87f5f59-c422q 1/1 Running 0 12s nginx-5bf87f5f59-vbrb8 1/1 Running 0 12s
Daha fazla bilgi alalım ve uygulama çalışıyor mu kontrol edelim.
[root@master-node ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-5bf87f5f59-5m4xv 1/1 Running 0 21s 192.168.180.198 worker-node1 <none> <none> nginx-5bf87f5f59-c422q 1/1 Running 0 21s 192.168.203.133 worker-node2 <none> <none> nginx-5bf87f5f59-vbrb8 1/1 Running 0 21s 192.168.203.134 worker-node2 <none> <none>
Curl ile worker-node1’de bulunan iç ip adresinden nginx sunucusuna erişelim. IP adresinin sonuna port numarası yazmadık. Çünkü nginx varsayılan olarak 80 portundan çalışıyor.
[root@master-node ~]# curl 192.168.180.198 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
Kubernetes cluster içindeki uygulamayı dışarıdan erişime açmak (NodePort servisi eklemek)
Kubernetes cluster içindeki ip adresleri sadece cluster içinden erişilir durumdadır. Az önce yukarıda oluşturduğumuz ve curl ile test ettiğimiz nginx web sunucusuna erişebilmemizin nedeni buydu. Ancak biz genelde bu uygulamaları dışarıdan başkaları erişsin diye yaparız. Dolayısıyla bunun için ayrıca bir servis tanımlayıp port yönlendirmesi yapmalıyız.
[root@master-node ~]# kubectl create service nodeport nginx --tcp=80:80 service/nginx created
Yukarıda dikkat etmemiz gereken önemli husus deployment esnasında verdiğimiz isim ile yukarıda nodeport(servis türü) sonrasında kullandığımız isim (nginx) aynı olmalıdır, nodeport burada servis türüdür.
Servis eklemenin farklı bir yolu:
[root@master-node ~]# kubectl expose deployment/httpenv --port 8888 --name httpenv-np --type NodePort
Burada hem deployment adı hem de servis adını ayrı ayrı belirttik.
- deployment/httpenv: Servis eklenecek deployment
- name httpenv-np: Servise verdiğimiz ad
Aslında NodePort servisini eklerken örtük olarak ClusterIP ve Loadbalancer da eklemiş oluyoruz.
Kubernetes NodePort ve Pod nesneleri nasıl eşleşir?
NodePort dış dünyadan ile Kubernetes cluster içinde çalışan uygulamamıza erişmemizi sağlayan bir servistir. Pod ise bir veya daha fazla konteynerdan oluşan bir nesnedir. Pod içinde çalışan uygulama NodePort servisi üzerinden dış dünya ile irtibat kurar. Peki yukarıda komut satırında bu iş biz farketmeden olmuş olabilir ancak konfigürasyon dosyası kullansaydık bu eşleşme nasıl olacaktı? Cevap: Pod yaml config dosyasındaki metadata -> labels -><anahtar>: <değer> ile NodePort yaml cofig dosyasındaki selector -> <anahtar>: <değer>
Kubernetes servisleri listeleme
Yukarıda nginx ismiyle oluşturulan servisi ve onun gibilerini nasıl listeleriz?
[root@master-node ~]# kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpenv ClusterIP 10.107.182.214 <none> 8888/TCP 50m httpenv-np NodePort 10.106.223.249 <none> 8888:32377/TCP 27m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h nginx NodePort 10.103.104.205 <none> 80:31317/TCP 4m37s
Kubernetes cluster üzerinde çalışan uygulamaya erişim
Yukarıda bir nginx web sunucusu deploy ettik ve buna erişim için bir servis tanımladık. Şimdi dışarıdan browser üzerinden bu uygulamaya erişeceğiz. Benim master sunucum bende k81 ismiyle kayıtlı ve ip adresi 192.168.206.31. Peki port numarası ne olacak ve nereden öğreneceğiz. Onu zaten gördük. Servisleri listelediğimizde o servisin hangi porttan açıldığını da görmüş oluyoruz. Yukarıdaki örnekte: nginx NodePort 10.103.104.205 80:31317/TCP 4m37s. Şimdi browserımı açıyorum ve k81:31317 veya 192.168.206.31:31317 yazıyorum. Karşıma aşağıdakigibi bir arayüz çıkmalı.
Kendinizi tebrik edebilirsiniz. Buraya kadar olan maddelerde Kubernetes cluster üzerinde bir web sunucusu çalıştırdınız ve hizmete sundunuz. Ve işin en güzel tarafı ne biliyor musunuz? Bu servise 3 node üzerinden de erişebiliyorsunuz yani yukarıda k81:31317 yerine k82:31317 ve k83:31317 yazsanız da servise erişeceksiniz. Daha ideal yönlendirme ve erişim için ingress kavramını inceleyiniz.
Kubernetes deployment silme
Yukarıda oluşturduğumuz deployment’ı silelim:
[root@master-node ~]# kubectl delete deployment nginx
Kontrol edelim:
[root@master-node ~]# kubectl get pods Bilgi çıktısı: No resources found in default namespace.
Kubernetes deployment of an image (yaml dosyası olmadan)
Deployment bir yaml dosyası ile yapılabildiği gibi doğrudan hazır bir imaj ile de yapılabilir.
[root@master-node ~]# kubectl create deployment deployment_adi --image=imaj_adi
Kubernetes scale a deployment (mevcut olanı daha fazla replica ile çalıştırmak, ölçeklemek)
Hazır bir imaj ile yaptığımız deployment esnasında scale belirtmemeiş olabiliriz. Sonradan bunu değiştirebiliriz.
[root@master-node ~]# kubectl scale deployment/deployment_adi --replicas=3 Bilgi çıktısı: deployment.apps/deployment_adi scaled
Kubernetes mevcut tüm deployment, serviceve replicas listeleme (kubectl get all)
[root@master-node ~]# kubectl get all NAME READY STATUS RESTARTS AGE pod/httpenv-bd844d85f-5c6lg 1/1 Running 0 18m pod/httpenv-bd844d85f-6gdbh 1/1 Running 0 14m pod/httpenv-bd844d85f-h5rsh 1/1 Running 0 14m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/httpenv ClusterIP 10.107.182.214 <none> 8888/TCP 5m20s service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25h service/nginx NodePort 10.103.104.205 <none> 80:31317/TCP 108m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/httpenv 3/3 3 3 18m NAME DESIRED CURRENT READY AGE replicaset.apps/httpenv-bd844d85f 3 3 3 18m
Kubernetes LoadBalancer servisi eklemek
LoadBalancer aslında bulut sürümlerine has bir servis. Eğer kubeadm (benim kullandığım), minikube veya microk8s kullanıyorsanız aşağıdaki komut gerçekten bir Loadbalancer eklemeyecektir. Ancak hata da vermeyecektir. Servisleri listelerken -o wide ile listelerseniz httpenv-lb LoadBalancer 10.105.156.39 <pending> 8888:30817/TCP 8m59s app=httpenv pending durumunda olacağını göreceksiniz.
[root@master-node ~]# kubectl expose deployment/httpenv --port 8888 --name httpenv-lb --type LoadBalancer Bilgi çıktısı: service/httpenv-lb exposed
- deployment/httpenv: Eklenecek deployment adı
- name httpenv-lb: LoadBalancer servisine verdiğimiz ad
Kubernetes birden fazla obje silmek (servis örneği)
Yukarıda oluşturduğumuz servis objelerini silelim:
[root@master-node ~]# kubectl delete service/httpenv service/httpenv-np service/httpenv-lb Bilgi çıktısı: service "httpenv" deleted service "httpenv-np" deleted service "httpenv-lb" deleted
Kubernetes generator kullanarak deployment yaml dosyası oluşturmak
[root@master-node ~]# kubectl create deployment test --image nginx --dry-run=client -o yaml Çıktı: apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: test name: test spec: replicas: 1 selector: matchLabels: app: test strategy: {} template: metadata: creationTimestamp: null labels: app: test spec: containers: - image: nginx name: nginx resources: {} status: {}
Yukarıdaki dry-run opsiyonu yapıyormuş gibi yapıyor.
Kubernetes deployment yöntemleri nelerdir?
Kubernetes iki farklı deployment yöntemine sahiptir: Imperative ve Declerative. Imperative, Kubernetes’e ne yapacağını söylerken nasılını da söyler. Declerative ise ne yapılacağını, istenen şeyi söyler nasılına karışmaz. Kullanımı kolay olan ve genelde tercih edilen declerative yaklaşımdır. Çünkü bu yaklaşımda config (yaml) dosyasını günceller ve bunu kubectl ile master’a bildirirsiniz. Gerisini master halleder.
Kubernetes cluster içinde bir nesneyi (object) benzersiz kılan özellikler nedir?
Nesnenin adı (Name) ve türüdür (Kind). Bu bilgiler config dosyasında bulunur ve nesnelerin karışmasını önler.
BASE64 ile Secret Oluşturma
Kubernetes cluster içinde veritabanı bağlantı bilgileri gibi hassas bilgiler K8 Secrets ile tutulur. Secrets bunu tutarken açık metin olarak değil de kodlayarak tutar. Bu bilgileri de biz girerken BASE64 ile kodlayarak gireriz. Aşağıdaki örnekte basit bir şifreyi kodlamayı (encoding) ve geri çözmeyi (decoding) göreceğiz.
Encoding:
echo -n "MyPassword" | base64 TXlQYXNzd29yZA==
Decoding
echo -n "TXlQYXNzd29yZA==" | base64 --decode MyPassword
Persistent Volumes (PV)
Kubernetes dünyası Hadoop’tan farklı olarak hesaplama ile depolamayı tamamen birbirinden yalıtmıştır. Bunu PersistenVolume (PV) ve PersistentVolumeClaim (PVC) ile sağlar. PV cluster yöneticileri tarafından elle veya StorageClass tarafından otomatik olarak oluşturulabilir. Oluşan bu PV’ler PVC ile talep edilir. Yani nasıl hesaplama için bir pod talep ediyorsak depolama için de PVC talep ediyoruz. Pod isterken CPU ve bellek, PVC istekende tip, hacim ve erişim modunu belirtiriz.
StorageClass
PersistenVolume (PV) PersistentVolumeClaim (PVC) göre dinamik olarak oluşturma imkanı sağlayan objedir.
Listeleme
kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) driver.longhorn.io Delete Immediate true 143d
Set-context ile varsayılan namespace değiştirme
kubectl config set-context --current --namespace=vbo
unset etmek için
kubectl config unset contexts.minikube.namespace
Namespace içindeki tüm podları silme
kubectl delete pod --all -n default pod "busybox-pod" deleted pod "nginx-pod" deleted pod "redis-pod" deleted pod "webserver-pod" deleted