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
Leave A Comment