Kubernetes Deployment Nedir?
Kubernetes Deployment, uygulamaların hızlı ve güvenli bir şekilde dağıtılmasını, güncellenmesini ve yönetilmesini sağlayan bir Kubernetes nesnesidir.
Deployment, uygulamanın Pod'larını oluşturur ve izler. Otomatik olarak yeni Pod'lar oluşturur ve çökmeler durumunda otomatik olarak yeniden başlatır. Ayrıca güncelleme ve geri alma işlemlerini kolaylaştırır, uygulamanın kesintisiz olarak güncellenmesine veya eski sürüme geri dönülmesine olanak tanır. Ölçeklendirme için de esneklik sağlar, isteğe bağlı olarak daha fazla veya daha az Pod çalıştırılmasını sağlar. Deployment'lar, Kubernetes üzerinde uygulama dağıtımı ve yönetimi için güçlü bir araçtır.
Bir önceki yazımızda Kubernetes deployment stratejilerini incelemiştik. Yazıdan hatırlayacağınız üzere deployment'ları manual yapmak zahmetli ve kubectl rolling-update
komutuyla yapmakta güvenilmez ve tercih edilmeyen yöntemdi. Bu yazımızda Kubernetes deployment işlemlerini Deployments nesnesi ile nasıl daha güvenilir ve efektif bir şekilde yapacağınızı göstereceğiz.
1. Deployment Nesnesi Oluşturmak
Bir Deployment nesnesi oluşturduğunuzda otomatik olarak bir de ReplicaSet nesnesi oluşturulur. ReplicaSet, ReplicationController'un yerini alan yeni nesil bir Kubernetes nesnesidir.
Kubernetes Deployment nesnesini kullanıdığınızda, aslında pod'lar Bu oluşturulan ReplicaSet tarafından oluşturulur ve yönetilir.
Bir Deployment nesnesi oluşturmak, ReplicationController veya ReplicaSet oluşturmaktan farklı değildir. Deployment nesnesi oluşturmak için aşağıdaki manifesti örnek alabilirsiniz.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: web
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Manifest dosyası hazır olduktan sonra kubectl create
veya kubectl apply
komutlarından birisi ile Deployment'ı oluşturabilirsiniz.
kubectl create -f file-deployment.yaml --record
--record
parametresi, yapılan değişiklikleri Deployment kayıtlarına eklemek için kullanılır. Bu parametre, Deployment nesnesinin revision (düzeltme) tarihçesini tutar ve yapılan değişiklikleri kaydeder.Ardından kubectl get deployment
komutu ile oluşturduğunuz Deployment nesnesini görebilirsiniz. Ayrıca kubectl rollout status deployment
komutuyla da Deployment durumunu görebilirsiniz.
$ kubectl rollout status deployment nginx-deployment
deployment nginx-deployment successfully rolled out
Deployment nesnesinin oluşturduğu ReplicaSet nesnesi de rollout yani deployment işlemi sonucu belirtilen replica sayısı kadar Pod oluşturur.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-1506449474-otnnh 1/1 Running 0 14s
web-1506449474-vmn7s 1/1 Running 0 14s
web-1506449474-xis6m 1/1 Running 0 14s
2. Deployment İle Kullanılabilecek Stratejiler
Deployment, varsayılan olarak Rolling Update stratejisini kullanır. Rolling update ile mevcut pod'larınız sonlandırılırken eş zamanlı olarak yeni pod'lar oluşturulur.
Diğer bir strateji ise Recreate'dir. Eğer uygulamanız multi-version çalışmayı desteklemiyorsa önce mevcut tüm pod'ların aynı anda silinip ardından yenilerinin oluşturulmasını sağlayan Recreate stratejisini kullanabilirsiniz.
3. Deployment Rolling Update ile Güncelleme Başlatmak
Bir deployment başlatabilmek için temel kural ReplicaSet'in template'inin veya replica saysının değişiyor olmasıdır. Yani bir deployment'ın manifestinde spec
altındaki replicas
veya template
alanlarını değiştirdiğinizde Deployment tetiklenir.
Bir Deployment nesnesini tetikleyerek güncelleme başlatmanın en yaygın senaryosu, Pod içindeki container'ların versiyonunu değiştirmektir. Bunu kubectl set image
komutuyla kolaylıkla yapabilirsiniz.
$ kubectl set image deployment nginx-deployment nginx=nginx:1.2
deployment "nginx-deployment" image updated
kubectl set image
komutu ayrıca ReplicationController ve ReplicaSet nesnelerinin de image'lerinin değiştirilmesine olanak sağlar.Deployment template değişikliği ile tetiklenip güncellemeyi başlattığında rolling update işlemi gerçekleştirilir ve eski ReplicaSet yeni ReplicaSet ile değiştirilir.
Yeni ReplicaSet ismi, yeni template'in hash değerini içerir. Eski ReplicaSet ise birazdan göreceğimiz rolling back işlemleri için silinmeden muhafaza edilir.
ReplicaSet'leri listelediğinizde eski ve yeni RS'yi listede görebilirsiniz.
$ kubectl get rs
NAME DESIRED CURRENT AGE
nginx-deployment-1506449474 0 0 24m
nginx-deployment-1581357123 3 3 23m
4. Deployment Güncelleme Geçmişini Listelemek
Deployment, rolling back işlemini mümkün kılmak için yaptığınız güncellemelerin tarihçesini saklar. Bu tarihçeyi kubectl rollout history deployment
komutu ile görebilirsiniz.
$ kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment":
REVISION CHANGE-CAUSE
2 kubectl set image deployment nginx-deployment nginx=nginx:1.2
3 kubectl set image deployment nginx-deployment nginx=nginx:1.3
--record
komutunu kullandığımız için CHANGE-CAUSE
sütununda Deployment güncellemesini tetikleyen komutu görebiliyoruz.
Varsayılan olarak saklanan güncelleme geçmişi sayısı 10'dur. Fakat Deployment nesnesinin revisionHistoryLimit
parametresini değiştirerek bu sayıyı istediğiniz gibi ayarlayabilirsiniz.
5. Deployment Rolling Back ile Güncellemeyi Geri Almak
Bir Deployment güncelleme işlemi sonrası eğer işler yolunda gitmezse ve yaptığınız güncellemeyi geri almak isterseniz kubectl rollout undo deployment
komutunu kullanabilirsiniz.
Direkt ReplicationController veya ReplicaSet kullanmak yerine bir Deployment nesnesi kullanmanın en önemli avantajı güncellemeleri geri alabilmenizdir.
Bir önceki başlıkta yaptığımız güncelleme işlemini geri alalım.
$ kubectl rollout undo deployment nginx-deployment
deployment "nginx-deployment" rolled back
undo
komutu, güncellemeniz halen devam ediyorken bile kullanılabilir. Bu, önce güncellemeyi durdurur ve o ana kadar oluşturulmuş yeni pod'ları silerek eski versiyonun pod'larını tekrar oluşturur.Eğer bir önceki yerine tarihçedeki belirli bir ana geri dönmek istiyorsanız, history
komutunun çıktısındaki REVISION
numaralarını --to-revision
parametresiyle kullanabilirsiniz.
kubectl rollout undo deployment nginx-deployment --to-revision=1
6. Deployment Güncellemeyi Duraklatmak
Bazı durumlarda güncellemeyi tek seferde tamamlamak yerine belirli bir noktada durdurarak yeni versiyonu test etmek isteyebilirsiniz. Deployment, pause komutu ile bunu mümkün kılar. Buna canary release adı da verillir.
Canary release, bir yazılımın yeni bir sürümünü kullanıcılara aşamalı ve kontrollü bir şekilde sunmayı sağlayan bir dağıtım stratejisidir. Bu strateji, yeni bir sürümün tamamını kullanıcılara hemen sunmak yerine, yeni sürümün bir alt kümesini küçük bir kullanıcı grubuna veya trafik akışına yönlendirerek performansını ve istikrarını değerlendirmeyi amaçlar.
Bir güncellemeyi başlattıktan sonra kubectl rollout pause deployment
komutu ile güncellemeyi devam ederken durdurabilirsiniz.
$ kubectl rollout pause deployment nginx-deployment
deployment "nginx-deployment" paused
undo
işlevi geçersiz kalır. Güncellemeyi geri alabilmek için önce duraklatılmış güncelleme devam ettirilmelidir.7. Deployment Duraklatılan Güncellemeyi Devam Ettirmek
Güncellemenizi durdurup yeni pod'ları test ettikten ve bir sorun yoksa devam ettirebilmek için resume koutunu kullanabilirsiniz.
$ kubectl rollout resume deployment nginx-deployment
deployment "nginx-deployment" paused
Böylece güncelleme kaldığı yerden devam edecektir.
8. Deployment Güncelleme Limitlerini Kontrol Etmek
Bir Deployment rollout işlemi başlatıp status komutu ile işlemi izlediğinizde tüm pod'ların birer birer silinip oluşturulduğunu görürsünüz. Tek tek yapmak yerine Deployment maxSurge ve maxUnavailable değerlerini değiştirerek güncellemeyi hızlandırabilir veya yavaşlatabilirsiniz.
Kubernetes Deployment nesnesinin spec.strategy.rollingUpdate
bölümünde bulunan maxSurge
ve maxUnavailable
parametreleri, rolling update işlemini yönetmek için kullanılır. Bu parametreler, Kubernetes'e güncelleme sırasında kaç yeni Pod'un başlatılacağını ve aynı anda kaç Pod'un kullanılamaz olabileceğini belirtmek için kullanılır.
maxSurge
: güncelleme sırasında izin verilen en fazla yeni Pod sayısını belirtir. Örneğin,maxSurge: 25%
değeri verildiyse, mevcut Pod sayısının %25'inden fazla yeni Pod başlatılabilir. Varsayılan değeri %25'dir. Bu, toplam Pod sayısını geçici olarak artırabilir ve yük dengesini sağlamak için kullanılabilir.maxUnavailable
: güncelleme sırasında izin verilen en fazla kullanılamayan (hizmet dışı) Pod sayısını belirtir. Örneğin,maxUnavailable: 1
değeri verildiyse, güncelleme sırasında en fazla 1 Pod hizmet dışı kalabilir. Varsayılan değeri %25'dir. Bu, yüksek kullanılabilirlik sağlamak için kullanılan Pod'ların sayısını kontrol etmeye yardımcı olur.
Bu iki parametre, güncelleme işlemini daha kontrollü hale getirir ve ağır bir etki veya kullanıcı kesintisi olmadan yeni sürüme geçişi sağlar. Örneğin, maxSurge
ve maxUnavailable
değerlerini dikkatli bir şekilde ayarlayarak, kullanıcı trafiği üzerinde minimal etkiyle sürdürülebilir bir güncelleme süreci sağlanabilir.
Örnek bir senaryoya bakalım:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Replica sayısının 3 olduğu bir Deployment'ta, her daim çalışan 3 pod olacak ve aynı anda ortamda en fazla 4 pod bulunacak şekilde güncelleme devam etti.
Şimdi başka bir senaryoya bakalım:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
Replica sayısının 3 olduğu bir Deployment'ta, her daim çalışan 2 pod (repica sayısı - maxUnavailable) olacak ve aynı anda ortamda en fazla 4 pod bulunacak şekilde güncelleme devam etti. Ve farkettiğiniz gibi ilk senaryodan daha kısa sürede güncelleme tamamlandı.
Bu iki değeri kendi senaryonuza göre güncelleyerek rollout işlemlerinizin stratejisini değiştirebilirsiniz.
9. Deployment Sorunlu Güncellemeleri Engellemek
Başlattığımız bir rollout işlemindeki versiyon eğer sorunluysa, komple çalışmayan bir versiyona geçiş yapmamak için ekstra bir güvenlik katmanı ekleyebiliriz. Deployment nesnesi, minReadySeconds
parametresi ile sorunlu güncellemeleri engellememizi sağlar.
minReadySeconds
parametresi, sıradaki Pod'u oluşturmaya başlamadan önce son oluşturulan Pod'un Ready durumunda ne kadar süre çalışması gerektiğini belirtir.
minReadySeconds
parametresi, saniye cinsinden bir değer alır. Örneğin, minReadySeconds: 30
değeri verildiyse, yeni başlatılan bir Pod'un en az 30 saniye boyunca Ready halde olması beklenir.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: my-app-image:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
# minReadySeconds parametresi burada tanımlanır
minReadySeconds: 30
minReadySeconds
kullanmadan yalnızca readiness probe tanımlarsanız, readiness probe ilk kez çalışıp başarılı olduğunda yeni bölmeler hemen kullanılabilir olarak kabul edilir ve sıradaki Pod'lar oluşturulmaya devam edilir. Fakat readiness probe kısa bir süre sonra başarısız olmaya başlarsa, hatalı sürüm tüm Pod'lara dağıtılmış olur. Bu nedenle, minReadySeconds
'u uygun şekilde ayarlamalısınız.Eğer bir pod minReadySeconds
süresi kadar Ready kalamazsa güncelleme devam edemeyecektir. Çünkü sıradaki Pod'lar oluşturulmayacaktır. Böyle bir durumda kubectl rollout undo deployment
komutu ile güncellemeyi rollback edebilirsiniz.
Son olarak ise rollout işlemi bu ve benzeri sorunlar sebebiyle eğer askıda kalırsa, ProgressDeadlineExceeded (.spec.progressDeadlineSeconds
) parametresi ile belirli bir süre sonra Failed durumuna geçmesi sağlanabilir. Varsayılan değeri ise 600sn yani 10dk dır.
$ kubectl describe deploy nginx-deployment
Name: nginx-deployment
...
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing False ProgressDeadlineExceeded
Sıradaki yazı ile eğitim serisine devam edebilirsiniz.