Kubernetes ile Uygulama Yönetimi: Deployment, Ölçeklendirme ve Stratejiler

Merhabalar,

“Kubernetes Öğreniyorum: İlk Adım – Nginx Pod ve Servis Kurulumu” başlıklı ilk serimize https://www.linkedin.com/pulse/kubernetes-%25C3%25B6%25C4%259Freniyorum-ilk-ad%25C4%25B1m-nginx-pod-ve-servis-yigit-aosxf/?trackingId=kLTi8SbGSyyxrr3ePAJBew%3D%3D adresinden ulaşabilirsiniz.

Bu ilk seride neler anlattık? Anlattıklarımızı aşağıdaki gibi özetleyebiliriz.

Kubernetes’in temellerine giriş yaparak, konteynerleştirilmiş uygulamaları yönetme, dağıtma ve ölçeklendirme konularında nasıl yardımcı olduğunu açıkladık. Kubernetes’in taşınabilirlik, otomatik ölçeklendirme, kendi kendini onarma ve kaynak verimliliği gibi avantajlarını, bir e-ticaret sitesi örneğiyle anlattık. Ardından Kubernetes’in temel bileşenleri olan pod, node, namespace, deployment, service, ConfigMap, Secret, Ingress, Persistent Volume (PV) ve Persistent Volume Claim (PVC) gibi yapıları tanıttık. Uygulamalı olarak, cluster üzerinde bir namespace oluşturduk ve nginx pod’unu çalıştırarak dış dünyaya açtık. Bunun için önce pod’u tanımladık, ardından bir LoadBalancer tipi servis ile dış IP adresi atayarak nginx web sunucusuna erişim sağladık. Bu bölümle, Kubernetes’in temellerini öğrenmek isteyenler için güçlü bir başlangıç sunarken, okuyucularımızı daha karmaşık uygulamalara hazırladık.

Evet, bu serimizde neler öğreneceğiz?

Kubernetes’in temellerini öğrendiğimiz ilk serinin ardından, bu bölümde Deployment ile pod’ları nasıl yönetebileceğimizi detaylı bir şekilde göreceğiz.

Oracle Cloud üzerinde olan sistemimizi hatırlayalım. Nelerimiz vardı?

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get nodes

NAME          STATUS   ROLES   AGE   VERSION

10.0.10.197   Ready    node    68m   v1.30.1

10.0.10.219   Ready    node    68m   v1.30.1

10.0.10.67    Ready    node    69m   v1.30.1

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods

No resources found in my-namespace namespace.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get namespaces

NAME              STATUS   AGE

default           Active   30d

kube-node-lease   Active   30d

kube-public       Active   30d

kube-system       Active   30d

my-namespace      Active   13d

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

 

Yukarıdaki komutlarla, Kubernetes cluster’ımızdaki node’ların durumunu kubectl get nodes komutuyla kontrol ederek, her bir node’un Ready (hazır) durumda olduğunu ve Kubernetes sürümünün v1.30.1 olduğunu gözlemledik. Ardından, kubectl get pods komutuyla my-namespace isimli namespace içinde çalışan herhangi bir pod bulunmadığını doğruladık. Namespace’leri listelemek için kubectl get namespaces komutunu kullandık ve varsayılan namespace’lerin yanı sıra daha önce oluşturduğumuz my-namespace adlı namespace’in hala aktif durumda olduğunu gördük. Bu kontroller, Kubernetes ortamımızın genel durumunu ve namespace içindeki mevcut kaynakların durumunu hızlıca anlamamıza olanak sağladı.

Kubernetes’te deployment kullanarak pod’larımızı daha yönetilebilir hale getirebiliriz. Pod’larımızı otomatik olarak yeniden oluşturabilir, güncelleyebilir ve ölçeklendirebiliriz. Çalışmalarımızı “my-namespace” içinde yapacağız.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl create deployment my-nginx –image=nginx

deployment.apps/my-nginx created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get deployments

NAME       READY   UP-TO-DATE   AVAILABLE   AGE

my-nginx   1/1     1            1           24s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods

NAME                        READY   STATUS    RESTARTS   AGE

my-nginx-544b86ccd5-6hvp8   1/1     Running   0          26s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl scale deployment my-nginx –replicas=3

deployment.apps/my-nginx scaled

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods

NAME                        READY   STATUS    RESTARTS   AGE

my-nginx-544b86ccd5-6hvp8   1/1     Running   0          2m34s

my-nginx-544b86ccd5-fqbgv   1/1     Running   0          46s

my-nginx-544b86ccd5-gvz4s   1/1     Running   0          46s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl exec -it my-nginx-544b86ccd5-6hvp8 — nginx -v

nginx version: nginx/1.27.2

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Bu çalışmada, Kubernetes üzerinde bir deployment oluşturarak nginx uygulamasını çalıştırmayı ve yönetmeyi öğrendik. İlk olarak, kubectl create deployment my-nginx –image=nginx komutunu kullanarak nginx’in varsayılan sürümünü çalıştıran bir deployment oluşturduk. Bu deployment, bir pod oluşturdu ve bu pod’un durumunu kubectl get deployments ve kubectl get pods komutlarıyla kontrol ederek çalışır durumda olduğunu doğruladık. Daha sonra, deployment’ı kubectl scale deployment my-nginx –replicas=3 komutuyla ölçeklendirdik ve aynı nginx uygulamasını çalıştıran toplam üç pod oluşturduk. Her bir pod’un durumunu tekrar kontrol ederek üç pod’un da başarıyla çalıştığını gördük. Son olarak, bu pod’lardan birine bağlanarak nginx’in tam sürümünü öğrenmek için kubectl exec -it my-nginx-544b86ccd5-6hvp8 — nginx -v komutunu kullandık ve nginx’in 1.27.2 sürümünü çalıştırdığını doğruladık. Bu süreç, Kubernetes üzerinde bir uygulamayı deployment aracılığıyla yönetmenin ve pod’ları ölçeklendirmenin temel adımlarını kapsadı.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl describe pod my-nginx-544b86ccd5-6hvp8

Name:             my-nginx-544b86ccd5-6hvp8

Namespace:        my-namespace

Priority:         0

Service Account:  default

Node:             10.0.10.219/10.0.10.219

Start Time:       Sun, 24 Nov 2024 13:12:33 +0000

Labels:           app=my-nginx

                  pod-template-hash=544b86ccd5

Annotations:      <none>

Status:           Running

IP:               10.0.10.100

IPs:

  IP:           10.0.10.100

Controlled By:  ReplicaSet/my-nginx-544b86ccd5

Containers:

  nginx:

    Container ID:   cri-o://53b391b6443367f86ee6477ce94375adfe6e6236094382df3fe260a081eca871

    Image:          nginx

    Image ID:       docker.io/library/nginx@sha256:5341b734e75ce46bbb8e02476434217fd771e23df9a4bfea756a6f3a4a521d3e

    Port:           <none>

    Host Port:      <none>

    State:          Running

      Started:      Sun, 24 Nov 2024 13:12:45 +0000

    Ready:          True

    Restart Count:  0

    Environment:    <none>

    Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7zrlm (ro)

Conditions:

  Type                        Status

  PodReadyToStartContainers   True

  Initialized                 True

  Ready                       True

  ContainersReady             True

  PodScheduled                True

Volumes:

  kube-api-access-7zrlm:

    Type:                    Projected (a volume that contains injected data from multiple sources)

    TokenExpirationSeconds:  3607

    ConfigMapName:           kube-root-ca.crt

    ConfigMapOptional:       <nil>

    DownwardAPI:             true

QoS Class:                   BestEffort

Node-Selectors:              <none>

Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s

                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

Events:

  Type    Reason     Age    From               Message

  —-    ——     —-   —-               ——-

  Normal  Scheduled  5m52s  default-scheduler  Successfully assigned my-namespace/my-nginx-544b86ccd5-6hvp8 to 10.0.10.219

  Normal  Pulling    5m51s  kubelet            Pulling image “nginx”

  Normal  Pulled     5m41s  kubelet            Successfully pulled image “nginx” in 9.211s (9.212s including waiting). Image size: 195818521 bytes.

  Normal  Created    5m41s  kubelet            Created container nginx

  Normal  Started    5m41s  kubelet            Started container nginx

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Bu çıktıda, my-nginx-544b86ccd5-6hvp8 adlı pod’un durumu ve Kubernetes tarafından nasıl yönetildiği detaylandırılmıştır. Pod, my-namespace adlı namespace içinde çalışmaktadır, 10.0.10.219 adlı node üzerinde planlanmış ve başlatılmıştır. Pod, nginx imajını kullanarak oluşturulmuş ve başarılı bir şekilde başlatıldığı için durumu Running olarak görülmektedir. Ayrıca, pod’un container’ı, Docker Hub’dan alınan nginx imajının hash değerine dayalı olarak doğrulanmıştır (sha256:5341b734e75ce46bbb8e02476434217fd771e23df9a4bfea756a6f3a4a521d3e).

Pod’un IP adresi 10.0.10.100 olarak atanmış, bu da ağ üzerinde iletişim kurabileceği anlamına gelmektedir. Ayrıca, pod’un Kubernetes kontrol birimi olan ReplicaSet tarafından yönetildiği bilgisi (Controlled By: ReplicaSet/my-nginx-544b86ccd5) verilmiştir. Container’ın başlangıç süreci ve durumu kubelet tarafından başarıyla izlenmiş ve hiçbir yeniden başlatma olmadan çalıştığı doğrulanmıştır (Restart Count: 0).

Pod’un Ready durumu, Kubernetes’in bu pod’u trafiğe yönlendirmeye hazır olduğunu ifade eder. Aynı zamanda, pod’un üzerindeki QoS (Quality of Service) Sınıfı BestEffort olarak belirlenmiştir; bu da pod’a özel kaynak sınırlarının tanımlanmadığını gösterir. Pod’un güvenli bir şekilde Kubernetes API’sine erişmesi için bir kube-api-access volume’u da eklenmiştir.

Son olarak, pod’un oluşturulması ve çalıştırılması sırasında meydana gelen olaylar (Events) listelenmiştir. Örneğin, imajın çekilmesi, container’ın oluşturulması ve çalıştırılması gibi süreçlerin hepsi başarılı bir şekilde tamamlanmıştır. Bu olaylar, sorun gidermek veya pod’un yaşam döngüsünü anlamak için kritik ipuçları sağlar.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl logs my-nginx-544b86ccd5-6hvp8

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration

/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/

/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh

10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf

10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf

/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh

/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh

/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh

/docker-entrypoint.sh: Configuration complete; ready for start up

2024/11/24 13:12:45 [notice] 1#1: using the “epoll” event method

2024/11/24 13:12:45 [notice] 1#1: nginx/1.27.2

2024/11/24 13:12:45 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)

2024/11/24 13:12:45 [notice] 1#1: OS: Linux 5.15.0-210.163.7.el8uek.x86_64

2024/11/24 13:12:45 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576

2024/11/24 13:12:45 [notice] 1#1: start worker processes

2024/11/24 13:12:45 [notice] 1#1: start worker process 28

2024/11/24 13:12:45 [notice] 1#1: start worker process 29

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Yukarıdaki komutla alınan log çıktısı, NGINX’in Kubernetes ortamında nasıl yapılandırıldığını ve çalıştırıldığını detaylı bir şekilde ortaya koyuyor. Başlatma sırasında docker-entrypoint.sh script’i, /docker-entrypoint.d/ dizinindeki ek yapılandırma dosyalarını yükleyerek ve gerekli değişiklikleri uygulayarak NGINX’i dinamik bir şekilde yapılandırıyor. IPv6 desteği etkinleştiriliyor, yerel çözücüler ve çevre değişkenleri ayarlanıyor, ayrıca şablon tabanlı yapılandırmalar güncelleniyor. Kullanılan NGINX sürümünün 1.27.2 olduğu belirtiliyor ve bu sürümün GCC 12.2.0 derleyicisi ile Linux 5.15.0 çekirdeğinde çalıştırıldığı görülüyor. Yüksek performanslı olay işleme için epoll mekanizmasının kullanılması, NGINX’in yoğun trafiği verimli bir şekilde yönetme kapasitesini artırıyor. Ayrıca, açılabilecek maksimum dosya tanımlayıcı sayısının 1.048.576 olarak ayarlandığı ve iki “worker” sürecinin başlatıldığı belirtiliyor. Bu süreçler, NGINX’in gelen bağlantıları paralel olarak işleyebilmesini sağlıyor. Logların sonunda, tüm yapılandırmaların başarıyla tamamlandığı ve NGINX’in çalışmaya hazır olduğu ifade ediliyor. Bu bilgiler, NGINX’in performans, kararlılık ve güvenilirlik açısından güçlü bir altyapı ile çalıştığını gösteriyor.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl label pods my-nginx-544b86ccd5-6hvp8 environment=production

pod/my-nginx-544b86ccd5-6hvp8 labeled

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods -l environment=production

 

NAME                        READY   STATUS    RESTARTS   AGE

my-nginx-544b86ccd5-6hvp8   1/1     Running   0          35m

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Yukarıda çalıştırdığımız komutlarla, Kubernetes’te bir pod’a etiket (label) ekleyerek ve bu etikete göre pod’ları filtrelemeyi öğrendik. İlk olarak, kubectl label pods my-nginx-544b86ccd5-6hvp8 environment=production komutunu kullanarak my-nginx-544b86ccd5-6hvp8 adlı pod’a environment=production etiketini ekledik. Bu işlem, pod’un hangi ortamda (örneğin, geliştirme, test veya üretim) çalıştığını belirtmek için kullanılır ve Kubernetes kaynaklarını organize etmede önemli bir rol oynar. Etiket ekleme işlemi başarıyla tamamlandıktan sonra, kubectl get pods -l environment=production komutunu çalıştırarak yalnızca environment=production etiketine sahip pod’ları listeledik. Çıktıda, bu etikete sahip olan my-nginx-544b86ccd5-6hvp8 pod’unun Running durumunda ve sağlıklı bir şekilde çalıştığını gördük. Bu yöntem, özellikle büyük Kubernetes ortamlarında pod’ları belirli kriterlere göre organize etmek ve yönetmek için oldukça faydalıdır.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl autoscale deployment my-nginx –cpu-percent=50 –min=1 –max=5

horizontalpodautoscaler.autoscaling/my-nginx autoscaled

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get hpa

NAME       REFERENCE             TARGETS              MINPODS   MAXPODS   REPLICAS   AGE

my-nginx   Deployment/my-nginx   cpu: <unknown>/50%   1         5         0          8s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Yukarıdaki komutlarla, Kubernetes üzerinde bir Horizontal Pod Autoscaler (HPA) tanımlayarak, my-nginx deployment’ının CPU kullanımına göre otomatik olarak ölçeklenmesini sağladık. İlk olarak, kubectl autoscale deployment my-nginx –cpu-percent=50 –min=1 –max=5 komutunu kullanarak my-nginx deployment’ı için bir HPA oluşturduk. Bu yapılandırma, pod’ların CPU kullanımının %50’yi aşması durumunda ölçeklenmesini sağlayacak şekilde ayarlandı ve pod sayısı 1 ile 5 arasında otomatik olarak ayarlanacak şekilde tanımlandı. Daha sonra, kubectl get hpa komutuyla HPA’nın durumunu kontrol ettik ve hedef CPU kullanımının şu anda belirsiz (<unknown>) olduğunu gördük, çünkü henüz bir metrik kaydı alınmamıştı. Bu mekanizma, sistem yüküne bağlı olarak pod’ların otomatik ölçeklenmesini sağlayarak kaynak kullanımını optimize eder ve Kubernetes ortamlarının daha verimli yönetilmesine olanak tanır.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl set resources deployment my-nginx –limits=cpu=500m,memory=128Mi

deployment.apps/my-nginx resource requirements updated

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods

NAME                       READY   STATUS    RESTARTS   AGE

my-nginx-fd9c44b9c-7ddwv   1/1     Running   0          76s

my-nginx-fd9c44b9c-drcjx   1/1     Running   0          72s

my-nginx-fd9c44b9c-gj2d2   1/1     Running   0          68s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl describe pod my-nginx-fd9c44b9c-7ddwv

Name:             my-nginx-fd9c44b9c-7ddwv

Namespace:        my-namespace

Priority:         0

Service Account:  default

nginx:

    Container ID:   cri-o://432a5d0c1f87b8c25b312c8cbc6f00a8a5a83b861dd3a10852c0341f45548841

    Image:          nginx

    Image ID:       docker.io/library/nginx@sha256:5341b734e75ce46bbb8e02476434217fd771e23df9a4bfea756a6f3a4a521d3e

    Port:           <none>

    Host Port:      <none>

    State:          Running

      Started:      Sun, 24 Nov 2024 13:55:52 +0000

    Ready:          True

    Restart Count:  0

    Limits:

      cpu:     500m

      memory:  128Mi

    Requests:

      cpu:        500m

      memory:     128Mi

    Environment:  <none>

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

kubectl set resources komutunu kullanarak my-nginx deployment’ına CPU ve bellek sınırları tanımladık. kubectl set resources deployment my-nginx –limits=cpu=500m,memory=128Mi komutunu çalıştırarak her pod’un maksimum CPU kullanımını 500 millicore ve bellek kullanımını 128 MiB olarak sınırladık. Bu işlem deployment için kaynak gereksinimlerini başarıyla güncelledi. Daha sonra, kubectl get pods komutuyla pod’ların yeniden başlatıldığını ve yeni yapılandırmalarla çalıştığını doğruladık. Belirli bir pod’un detaylarını görmek için kubectl describe pod my-nginx-fd9c44b9c-7ddwv komutunu çalıştırdığımızda, Limits ve Requests alanlarında belirtilen CPU ve bellek sınırlarının (cpu: 500m, memory: 128Mi) pod seviyesinde doğru bir şekilde uygulandığını gözlemledik. Bu yapılandırma, Kubernetes’in kaynak kullanımını daha verimli yönetmesini sağlarken, sistemin aşırı yüklenmesini de önleyecek şekilde planlanmıştır. Pod’un durumu Running ve Ready olarak gözükerek, tanımlı limitler dahilinde sorunsuz çalıştığını doğruladık. Bu adımlar, Kubernetes ortamında kaynak yönetiminin nasıl optimize edilebileceğini gösteren önemli bir örnek oluşturdu.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get deployment my-nginx -o yaml > my-nginx-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ ls -ltr

total 4

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:07 my-nginx-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ more my-nginx-deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

  annotations:

    deployment.kubernetes.io/revision: “2”

  creationTimestamp: “2024-11-24T13:12:33Z”

  generation: 3

  labels:

    app: my-nginx

  name: my-nginx

  namespace: my-namespace

  resourceVersion: “10682147”

  uid: 979dc4f2-af69-4ec1-8d21-d2d07daf0b2e

spec:

  progressDeadlineSeconds: 600

  replicas: 3

  revisionHistoryLimit: 10

  selector:

    matchLabels:

      app: my-nginx

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Yukarıdaki komutlarla Kubernetes üzerinde oluşturduğumuz my-nginx deployment’ının YAML formatındaki tanımını alarak detaylı bir inceleme gerçekleştirdik. İlk olarak, kubectl get deployment my-nginx -o yaml > my-nginx-deployment.yaml komutunu kullanarak deployment’ın tanımını bir dosyaya kaydettik. Daha sonra, ls -ltr komutuyla dosyanın bulunduğunu ve more my-nginx-deployment.yaml komutuyla içerik detaylarını görüntüledik. Bu YAML dosyası, deployment’ın tüm yapılandırma detaylarını içeriyor. Örneğin, deployment’ın adı my-nginx, namespace’i my-namespace, replika sayısı 3, ve revision geçmişi için sınırın 10 olarak tanımlandığı görülüyor. Ayrıca, deployment’ın Kubernetes tarafından hangi etikete (app: my-nginx) göre seçileceği ve oluşturulma zaman bilgisi gibi metaveriler de bu dosyada yer alıyor. Bu işlem, deployment yapılandırmasını yedeklemek, düzenlemek veya farklı bir ortamda yeniden uygulamak için güçlü bir yöntemdir. YAML dosyası, Kubernetes kaynaklarını tanımlamak ve yönetmek için en yaygın kullanılan yöntemdir.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl create namespace my-namespace-cln

namespace/my-namespace-cln created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ cp my-nginx-deployment.yaml my-nginx-clone-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ ls -l

total 8

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:16 my-nginx-clone-deployment.yaml

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:07 my-nginx-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-nginx/my-nginx-clone/g’ my-nginx-clone-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-namespace/my-namespace-cln/g’ my-nginx-clone-deployment.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl apply -f my-nginx-clone-deployment.yaml

 

deployment.apps/my-nginx-clone created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get deployments -n my-namespace-cln

 

NAME             READY   UP-TO-DATE   AVAILABLE   AGE

my-nginx-clone   3/3     3            3           11s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods -n my-namespace-cln

NAME                              READY   STATUS    RESTARTS   AGE

my-nginx-clone-5f8fbd785c-l88mz   1/1     Running   0          12s

my-nginx-clone-5f8fbd785c-pq25w   1/1     Running   0          12s

my-nginx-clone-5f8fbd785c-v8hm4   1/1     Running   0          12s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Bu çalışmada, mevcut bir deployment’ın YAML dosyasını düzenleyerek, farklı bir namespace içinde ve farklı bir isimle yeni bir deployment oluşturduk. İlk olarak, kubectl create namespace my-namespace-cln komutuyla my-namespace-cln adında yeni bir namespace oluşturduk. Ardından, mevcut my-nginx-deployment.yaml dosyasını cp komutuyla kopyalayarak my-nginx-clone-deployment.yaml adında yeni bir dosya oluşturduk. Bu dosyada sed komutlarını kullanarak tüm my-nginx ifadelerini my-nginx-clone ile, tüm my-namespace ifadelerini ise my-namespace-cln ile değiştirdik. Düzenlediğimiz YAML dosyasını kubectl apply -f my-nginx-clone-deployment.yaml komutuyla uygulayarak yeni deployment’ı oluşturduk. Sonrasında, kubectl get deployments -n my-namespace-cln komutuyla deployment’ın başarıyla oluşturulduğunu ve üç pod’un da sağlıklı bir şekilde çalıştığını doğruladık. Bu adımlar, Kubernetes üzerinde mevcut yapılandırmaları farklı bir isim ve namespace ile tekrar kullanarak yeni kaynaklar oluşturmanın pratik bir yolunu göstermektedir.

Son olarak “deployment” stratejilerinden bahsetmek istiyorum.

Kubernetes’te bir deployment oluştururken veya güncellerken uygulama pod’larının nasıl güncelleneceği, deployment stratejileri ile belirlenir. İki temel strateji bulunur:

RollingUpdate Stratejisi (Varsayılan)

Bu stratejide, pod’lar kademeli olarak güncellenir. Eski pod’lar birer birer silinirken, yeni pod’lar aynı anda oluşturulur. Bu yaklaşım, uygulama kesintisizliğini garanti altına alır ve kullanıcı deneyimini olumsuz etkilemez.

 

Recreate Stratejisi

Bu stratejide, eski pod’lar tamamen silinir ve ardından yeni pod’lar oluşturulur. Kısa süreli bir kesintiye neden olabilir, ancak sistemin tamamen sıfırdan başlamasını gerektiren senaryolarda tercih edilebilir.

 

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl create namespace deployment-strategies

namespace/deployment-strategies created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ cp my-nginx-deployment.yaml nginx-rolling-update-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ cp my-nginx-deployment.yaml nginx-recreate-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ ls -l

total 16

-rw-r–r–. 1 asiye_yigi oci 1684 Nov 24 14:25 my-nginx-clone-deployment.yaml

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:07 my-nginx-deployment.yaml

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:52 nginx-recreate-example.yaml

-rw-r–r–. 1 asiye_yigi oci 1650 Nov 24 14:52 nginx-rolling-update-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Yukarıdaki komutlarla, Kubernetes üzerinde farklı deployment stratejilerini test etmek için hazırlık yapıyoruz. İlk olarak, kubectl create namespace deployment-strategies komutuyla deployment-strategies adlı yeni bir namespace oluşturduk. Bu namespace, stratejilerimizi izole bir ortamda test etmemize olanak tanıyacak. Ardından, mevcut my-nginx-deployment.yaml dosyasını iki ayrı dosya olarak kopyaladık: nginx-rolling-update-example.yaml ve nginx-recreate-example.yaml. Bu dosyalar, sırasıyla RollingUpdate ve Recreate stratejilerini test etmek için kullanılacak. ls -l komutuyla, bu dosyaların başarıyla oluşturulduğunu ve sistemde mevcut olduklarını doğruladık. Bu hazırlık süreci, her bir deployment stratejisini bağımsız bir şekilde yapılandırmamıza ve test etmemize zemin hazırlıyor.

 

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-nginx/nginx-rolling-update-example/g’ nginx-rolling-update-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-namespace/deployment-strategies/g’ nginx-rolling-update-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl apply -f nginx-rolling-update-example.yaml

deployment.apps/nginx-rolling-update-example created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl describe deployment nginx-rolling-update-example -n deployment-strategies

 

Name:                   nginx-rolling-update-example

Namespace:              deployment-strategies

CreationTimestamp:      Sun, 24 Nov 2024 15:15:45 +0000

Labels:                 app=nginx-rolling-update-example

Annotations:            deployment.kubernetes.io/revision: 1

Selector:               app=nginx-rolling-update-example

Replicas:               3 desired | 3 updated | 3 total | 2 available | 1 unavailable

StrategyType:           RollingUpdate

MinReadySeconds:        0

RollingUpdateStrategy:  25% max unavailable, 25% max surge

Pod Template:

  Labels:  app=nginx-rolling-update-example

  Containers:

   nginx:

    Image:      nginx

    Port:       <none>

    Host Port:  <none>

    Limits:

      cpu:        250m

      memory:     64Mi

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type           Status  Reason

  —-           ——  ——

  Available      False   MinimumReplicasUnavailable

  Progressing    True    ReplicaSetUpdated

OldReplicaSets:  <none>

NewReplicaSet:   nginx-rolling-update-example-56d669f69f (3/3 replicas created)

Events:

  Type    Reason             Age   From                   Message

  —-    ——             —-  —-                   ——-

  Normal  ScalingReplicaSet  21s   deployment-controller  Scaled up replica set nginx-rolling-update-example-56d669f69f to 3

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods -n deployment-strategies

NAME                                            READY   STATUS    RESTARTS   AGE

nginx-rolling-update-example-847b7f49c4-g4ps4   1/1     Running   0          6s

nginx-rolling-update-example-847b7f49c4-s9mt2   1/1     Running   0          13s

nginx-rolling-update-example-847b7f49c4-xhfs4   1/1     Running   0          9s

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl rollout status deployment/nginx-rolling-update-example -n deployment-strategies

deployment “nginx-rolling-update-example” successfully rolled out

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Bu adımlarda, RollingUpdate stratejisiyle bir deployment oluşturup Kubernetes üzerindeki işleyişini test ettik. İlk olarak, sed komutlarını kullanarak mevcut nginx-rolling-update-example.yaml dosyasındaki deployment adını ve namespace’ini değiştirdik. my-nginx ifadelerini nginx-rolling-update-example ile, my-namespace ifadelerini ise deployment-strategies ile değiştirdik. Ardından, kubectl apply -f nginx-rolling-update-example.yaml komutuyla bu YAML dosyasını uyguladık ve deployment’ı oluşturduk. kubectl describe deployment komutuyla, deployment’ın detaylarını inceledik. Bu detaylarda, RollingUpdate stratejisinin devrede olduğunu ve deployment’ın yeni ReplicaSet için toplam üç pod oluşturduğunu gözlemledik. Her pod, belirlenen CPU ve bellek sınırlarıyla çalışmak üzere yapılandırılmıştı.

Sonrasında, kubectl get pods komutuyla, oluşturulan pod’ların durumunu doğruladık. Tüm pod’ların Running durumda olduğunu ve her birinin sağlıklı bir şekilde çalıştığını gördük. Son olarak, kubectl rollout status komutunu kullanarak deployment’ın rollout işleminin başarıyla tamamlandığını onayladık.

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-nginx/nginx-recreate-example/g’ nginx-recreate-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ sed -i ‘s/my-namespace/deployment-strategies/g’ nginx-recreate-example.yaml

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ more nginx-recreate-example.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

  annotations:

    deployment.kubernetes.io/revision: “2”

  creationTimestamp: “2024-11-24T13:12:33Z”

  generation: 3

  labels:

    app: nginx-recreate-example

  name: nginx-recreate-example

  namespace: deployment-strategies

  resourceVersion: “10682147”

  uid: 979dc4f2-af69-4ec1-8d21-d2d07daf0b2e

spec:

  progressDeadlineSeconds: 600

  replicas: 3

  revisionHistoryLimit: 10

  selector:

    matchLabels:

      app: nginx-recreate-example

  strategy:

    type: Recreate

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl apply -f nginx-recreate-example.yaml

 

deployment.apps/nginx-recreate-example created

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl describe deployment nginx-recreate-example -n deployment-strategies

Name:               nginx-recreate-example

Namespace:          deployment-strategies

CreationTimestamp:  Sun, 24 Nov 2024 15:47:09 +0000

Labels:             app=nginx-recreate-example

Annotations:        deployment.kubernetes.io/revision: 1

Selector:           app=nginx-recreate-example

Replicas:           3 desired | 3 updated | 3 total | 3 available | 0 unavailable

StrategyType:       Recreate

MinReadySeconds:    0

Pod Template:

  Labels:  app=nginx-recreate-example

  Containers:

   nginx:

    Image:      nginx

    Port:       <none>

    Host Port:  <none>

    Limits:

      cpu:        250m

      memory:     64Mi

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type           Status  Reason

  —-           ——  ——

  Available      True    MinimumReplicasAvailable

  Progressing    True    NewReplicaSetAvailable

OldReplicaSets:  <none>

NewReplicaSet:   nginx-recreate-example-76db86fccd (3/3 replicas created)

Events:

  Type    Reason             Age   From                   Message

  —-    ——             —-  —-                   ——-

  Normal  ScalingReplicaSet  67s   deployment-controller  Scaled up replica set nginx-recreate-example-76db86fccd to 3

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ 

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get deployments -n deployment-strategies

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE

nginx-recreate-example         3/3     3            3           17s

nginx-rolling-update-example   3/3     3            3           31m

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$ kubectl get pods -n deployment-strategies

 

NAME                                            READY   STATUS    RESTARTS   AGE

nginx-recreate-example-76db86fccd-72ws6         1/1     Running   0          41s

nginx-recreate-example-76db86fccd-n467r         1/1     Running   0          41s

nginx-recreate-example-76db86fccd-p7twt         1/1     Running   0          41s

nginx-rolling-update-example-847b7f49c4-g4ps4   1/1     Running   0          24m

nginx-rolling-update-example-847b7f49c4-s9mt2   1/1     Running   0          24m

nginx-rolling-update-example-847b7f49c4-xhfs4   1/1     Running   0          24m

asiye_yigi@cloudshell:~ (eu-frankfurt-1)$

 

Bu bölümde, Kubernetes üzerinde Recreate stratejisini uygulayarak deployment sürecini başarıyla test ettik. İlk olarak, nginx-recreate-example.yaml adlı bir YAML dosyası oluşturduk ve deployment stratejisini type: Recreate olarak ayarladık. Kaynak sınırlarını (CPU ve bellek) optimize ettikten sonra deployment’ı, kubectl apply -f nginx-recreate-example.yaml komutuyla uyguladık. Ardından, kubectl describe deployment nginx-recreate-example -n deployment-strategies komutuyla deployment durumunu inceledik ve üç replikanın da başarıyla oluşturulduğunu, pod’ların sağlıklı bir şekilde çalıştığını doğruladık. Recreate stratejisi, eski pod’ları tamamen kaldırarak yeni pod’ları başlattığı için deployment sırasında eski pod’ların hemen sonlandırıldığını ve ardından yeni pod’ların oluşturulduğunu gördük.

Pod durumlarını kontrol etmek için kubectl get pods -n deployment-strategies komutunu kullandığımızda, üç yeni pod’un Running durumunda olduğunu ve bu pod’ların başarıyla çalıştığını gözlemledik. Recreate stratejisinin en belirgin farkı, eski pod’lar kaldırılmadan yeni pod’ların başlatılmamasıdır. Örneğin, daha önce kullandığımız RollingUpdate stratejisinde eski pod’lar kademeli olarak güncellenir. Ancak Recreate stratejisinde tüm eski pod’lar aynı anda sonlandırılır ve yeni pod’lar toplu olarak başlatılır. Bu fark, kubectl describe deployment ve kubectl get pods komutlarının çıktılarında da net bir şekilde görülmektedir. RollingUpdate stratejisinde pod’ların bir kısmı kademeli olarak Pending veya Ready duruma geçerken, Recreate stratejisinde önce tüm eski pod’lar sonlandırıldığı için yeni pod’lar topluca aynı anda Pending ve ardından Running durumuna geçti.

Bu test sayesinde deployment stratejilerinin uygulama ve güncelleme süreçlerini daha iyi anlamış olduk. RollingUpdate stratejisi kesinti süresini en aza indirirken, Recreate stratejisi tüm pod’ların aynı anda yenilenmesi gerektiği durumlar için idealdir. Komut çıktılarıyla bu farkları gözlemlemek, teoriyi pratiğe dökmemiz açısından oldukça önemli.

Bu yazımızda Kubernetes üzerinde bir deployment oluşturma, yönetme, ölçeklendirme ve kaynak kullanımını optimize etme süreçlerini detaylı bir şekilde ele aldık. Ayrıca, mevcut bir deployment’ın YAML tanımını yedekleyip düzenleyerek farklı bir namespace içinde ve farklı bir isimle nasıl yeniden kullanılabileceğini uygulamalı olarak öğrendik. Son olarak, Kubernetes’in deployment stratejileri ile uygulamaların kesintisiz ve güvenilir bir şekilde güncellenebileceğini gördük. Özellikle varsayılan RollingUpdate stratejisinin sağladığı esneklik, canlı sistemlerde güncelleme yaparken kullanıcı deneyimini koruma açısından kritik öneme sahiptir, çünkü bu strateji hizmet kesintisini minimumda tutar. Tüm bu örnekler, Kubernetes’in uygulama yönetimini nasıl kolaylaştırdığına dair güçlü bir altyapı sunmaktadır. Bu seride öğrendiğimiz bilgiler, yalnızca temel Kubernetes kavramlarını değil, aynı zamanda daha karmaşık senaryolara geçiş için de sağlam bir temel oluşturmaktadır. Bir sonraki bölümümüzde, ConfigMap ve Secret gibi yapıların kullanımıyla uygulama yapılandırmalarını nasıl dışarıdan sağlayabileceğimizi ve Persistent Volume ile veri bütünlüğünü nasıl koruyabileceğimizi göreceğiz.  Bu sayede uygulamaların yönetimini nasıl daha etkili hale getirebileceğimizi göreceğiz.

Sarav Asiye Yiğit – 24 Kasım 2024

#Kubernetes #Deployment #Containerization #CloudComputing #DevOps #Automation #Scaling #TechLearning #ConfigurationManagement #ITOptimization