KUBERNETES POD OLUŞTURULMASI
Burada kubernetes üzerindeki en küçük birim olan pod oluşturulması anlatılmaktadır. İstenilirse pod komut satırı ile de oluşturulabilir. Fakat burada yaml dosyası oluşturularak pod oluşturulması anlatılacaktır. Örneğimizde web-server uygulaması olan nginx podu oluşturulacaktır.
vim nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-deneme
labels:
name: nginx-deneme
spec:
containers:
- name: nginx-deneme
image: nginx
ports:
- containerPort: 80
kubectl create -f nginx.yaml
Aşağıda ki komut ile oluşturulan pod’un görüntülenmesi ağlanır.
kubectl get pods
Hafif Bilgi: Oluşturulan podlara kube-proxy tarafından ip tables üzerinden benzersiz ip ataması yapılır. Bu network iletişimini CNI yönetir.
Aşğıdaki komu ile var olan podların ip adresleri ile birlikte gözlemlenebilir. İlgili podun ip adresine istek gönderildiğinde nginx defaul web sayfasının açılacağı gözlemlenecektir.
kubectl get pods -o wide
İlgili pod ip adresine curl komutu ile istek gönderelim ve sonuca bakalım.
curl 10.244.0.7
Aşağıda ki komut ile ilgili pod’un silinmesini sağlayabilirsiniz.
kubectl delete pod nginx-deneme
KUBERNETES REPLICASET OLUŞTURULMASI
Bu konu başlığı altında replicaset tanımlaması yapılacaktır. Replicaset ile ilgili podlar belirli bir sayıda oluşturulacaktır.
vim replica-set.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
kubectl create -f replica-set.yaml
Şimdi oluşan podlara bakalım.
kubectl get pods
Yukarıda görüleceği üzere replicas kısmında 3 olarak belirttiğimiz durumdan ötürü 3 adet pod oluşturulması sağlanmıştır.
KUBERNETES DEPLOYMENT OLUŞTURULMASI
Bu konu başlığı altında DEPLOYMENT nesnesinin oluşturulması ile ilgili uygulamalar yapılacaktır.
Örnek olarak aşağıda bir deployment oluşturalım ve gerekli adımları uygulayalım.
vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
İlgili yaml dosyası üzerinden deployment nesnesini oluşturalım.
kubectl create -f nginx-deployment.yaml
Şimdi var olan deployment’ın listelenmesini sağlayalım.
kubectl get deployment
Şimdi ilgili deployment’ın son versiyon durumuna bakalım.
kubectl rollout status deployment nginx-deployment
Şimdi ilgili deployment’ın image versiyonunu güncelleyelim. Bu güncelleme işlemi sonunda yeni podlar oluşturulur ve eski podlar’ın silinmesi sağlanır.
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record=true
Şimdi durumuna bakalım.
kubectl rollout status deployment nginx-deployment
Hafif Bilgi: Bir deployment üzerinde güncelleme yapıldığın da varsayılan ayar olarak ilgili pod sayısının %25 i kapatılır ve yeni pod oluşturulur ve bu işlem böyle takrar eder.
Şimdi replica sayısını değiştirelim ve duruma bakalım.
kubectl scale deployment nginx-deployment --replicas=5
kubectl rollout status deployment nginx-deployment
Şimdi deployment incelemesi yaparak deployment üzerinde yaptığımız değişikliklere bakalım.
kubectl describe deployment nginx-deployment
Ayrıca deployment güncelleme geçmişine aşağıdaki komut ile bakabiliriz.
kubectl rollout history deployment nginx-deployment
Eski bir güncellemeye dönmek için aşağıdaki komut kullanılır.
kubectl rollout undo deployment nginx-deployment
Ayrıca aşağıdaki şekilde belirlediğimiz bir versiyona geri dönebiliriz.
kubectl rollout undo deployment nginx-deployment --to-revision=2
KUBERNETES SERVİS OLUŞTURULMASI
Aşağıdaki anlatımda kubernetes üzerinde servis oluşturulması anlatılacaktır. Servis ile ilgili bilgilere buradan erişebilirsiniz.
Örnek olarak bir deployment oluşturalım ve daha sonra servis oluşturarak bu deployment’ın erşime açılmasını sağlayalım.
vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
Şimdi deployment nesnesinin oluşmasını sağlayalım.
kubectl create -f nginx-deployment.yaml
Şimdi servis için yaml dosyası oluşturalım ve aşağıdaki komutları içerisine atalım.
vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
Şimdi servis nesnesini oluşturalım.
kubectl create -f nginx-service.yaml
Şimdi ilgili servisin listelenmesini sağlayalım.
kubectl get svc
İlgili servisin IP adresi alınarak curl komutu yardımı ile istek gönderilir ve nginx web sayfasıının açılıp açılmadığına bakılır.
curl 10.107.20.149
Görselde görüldüğü üzere uygulamaya servis üzerinden erişilmiştir.
Şimdi servis tipleri ile ilgili örnekler çözelim. Bir servis tipi belirlenmeden servis oluşturulursa default olarak ClusterIP tipinde oluşturulur. NodePort tipinde servis yapmak istersek aşağıdaki şekilde servis dosyamız düzenlememiz ve kubectl apply -f komutunu çalıştrmamız gerekir. Ayrıca ilgili servis kubectl edit komutu kullanılarak da düzenlenebilir.
vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
type: NodePort
kubectl apply -f nginx-service.yaml
Şimdi ilgili node’nin IP adresini ve port numarasını girerek nginx sayfasının açılmasını sağlayalım.
kubectl get svc
Şimdi ExternalName türünde servis tanımlama durumuna bakalım. Var olan nginx-service.yaml dosyası düzenlenmek üzere açılır. Gerekli değişiklikler yapılarak kubectl apply komutu kullanarak servis düzenlenmiş hali ile oluşturulur. Bu servis durumunda cluster dışındaki bir uygulamaya erişim için kullanılır. Biz burada www.hafifbilgiler.com‘a ulaşmak için kullanacağız.
vim nginx-service-external.yaml
apiVersion: v1
kind: Service
metadata:
name: deneme-external
spec:
type: ExternalName
externalName: www.hafifbilgiler.com
kubectl create -f nginx-service-external.yaml
Şimdi gecici bir şkeilde busybox pod’u oluşturularak curl işlemi gereçekleştireceğiz. Bu pod kapandıktan sonra otomatik olarak silinecektir.
kubectl run --rm --generator=run-pod/v1 curl --image=radial/busyboxplus:curl -i --tt
Şimdi servis isimine curl ile istek atmayı deneyelim.
curl http://deneme-external
KUBERNETES JOB OLUŞTURULMASI
Aşağıdaki anlatımda kubernetes tanımlar sayfasında Job ile ilgili anlattığım durumları uygulayacağız.
Öncelikle ekrana bildirim yazan job tanımı yapalım.
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-deneme
spec:
template:
spec:
containers:
- name: job-deneme
image: alpine
command: ['sh', '-c', 'echo JOB BASARILI BIR SEKILDE CALISTI ; sleep 10']
restartPolicy: Never
Yukarıdaki dosyadan bir job oluşturup ilgili komutların çalııp çalışmadığını gözlemleyelim.
Şimdi var olan job’ı listeleyelim.
kubectl get jobs
Şimdi podları listeleyelim. İlgili job tanımı için oluşturulmuş podların listede görünmesi sağlanacaktır. Job için oluşturulmuş bir pod başarılı bir şekilde tamamlanmış ise durumunda completed olarak görülmüştür.
Şimdi yazdırmak istediğimiz mesajın yazılıp yazılmadığına bakalım.
kubectl logs job-deneme-js5qq
Job’a tanımlı pod silinebilir, deployment veya replicaset gibi Job tekrar pod oluşturmaz. Pod silinse bile job tanımı hala durur. Eğer job silinirse ona ait podun da silinmesi sağlanır.
Aynı şekilde bir job’u describe ederekte onunla ilgili durumları görebilirsiniz.
kubectl describe job job-deneme
Şimdi pod’un silinmesini sağlayalım.
kubectl delete pod job-deneme-js5qq
Daha sonra Job’un silinmesini sağlayalım.
kubectl delete job job-deneme
Şimdi backoffLimit durumuna bakalım. Bu durumu denemek için aşağıdaki şekilde yaml dosyası oluşturulur ve bu dosyadan Job nesnesi oluşturulur. Hata alınmasını sağlamak için exitcode=1 olması sağlanmıştır.
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-deneme
spec:
template:
spec:
containers:
- name: job-deneme
image: alpine
command: ['sh', '-c', 'echo JOB BASARILI BIR SEKILDE CALISTI ; exit 1']
restartPolicy: Never
backoffLimit: 2
kubectl create -f job.yaml
Şimdi podları listeleyelim ve duruma bakalım.Backofflimit 2 olarak ayarlandığı için 3. pod oluşturulmaya başlandıktan sonra bir daha oluşturulmaya çalışılmaz.
kubectl get pods
Şimdi ilgili job’un ayrıntılarına bakalım.
kubectl describe job job-deneme
Şimdi Job’ın silinmesini sağlayalım.
kubectl delete -f job.yam
Şimdi completions ve parallelism durumlarına bakalım.
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-deneme
spec:
template:
spec:
containers:
- name: job-deneme
image: alpine
command: ['sh', '-c', 'echo JOB BASARILI BIR SEKILDE CALISTI ; sleep 5']
restartPolicy: Never
backoffLimit: 2
completions: 4
parallelism: 2
Yukarıdaki durumda öncelikle 2 pod çalışıp tamamlanır, daha sonra diğer iki pod’da çalışarak toplamda aynı iş için 4 pod 2 parelellik ile çalışarak tamamlanır. Podları listeleyecek olursak durum gözlenecektir.
kubectl get pods
spec.ttlSecondsAfterFinished durumuna bakalım. Bu tanımlama işlerin silinmesini otomatik sağlanacaktır. Örnekte 10 sn sonra silinmesi sağlanacak şekilde ayarlanmıştır. İş tamamlanır tamamlanmaz kubernetes verdiğimiz süre sonunda job’u silinecekler arasına koyar ve belirlediği kiriterler değerlendirmesinden sonra işin silinmesi sağlanır.
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-deneme
spec:
template:
spec:
containers:
- name: job-deneme
image: alpine
command: ['sh', '-c', 'echo JOB BASARILI BIR SEKILDE CALISTI ; sleep 5']
restartPolicy: Never
backoffLimit: 2
completions: 4
parallelism: 2
ttlSecondsAfterFinished: 10
kubectl create -f job.yaml
Biz silinmesini beklemeden işi silelim ve diğer otomatik silme parametresi olan activeDeadlineSeconds denemesine geçelim.
NOT: Bu parmetre ile bir önceki parametre arasında şöyle bir fark vardır. Bir önceki parametre iş başarılı ve başarısız tamamlanmak koşulu ile işin tamamlanmasından sonra işi silinecekler arasına koyar ve siler. Kullanacağımız bu parametre ise iş çalışıyorken bile bu süre dolduğunda işin silinmesini sağlar. Ve başarısız olarak işaretler.
vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-deneme
spec:
template:
spec:
containers:
- name: job-deneme
image: alpine
command: ['sh', '-c', 'echo JOB BASARILI BIR SEKILDE CALISTI ; sleep 50 ']
restartPolicy: Never
activeDeadlineSeconds: 45
Yukarıdaki örnekte pod çalışarak 50 saniye (sleep 50 sebebiyle) running durumunda kalacaktır. 45 saniye sonra pod hala çalışıyor durumunda olacağı için artık o podun silinmesi sağlanacak ve başarısız olarak işaretlenecektir
kubectl create -f job.yaml
kubectl get pods
Şimdi çalışma kuyruğuna sahip job durumuna değinelim. Öncelikle aşağıdaki şekilde klasör oluşturulur.
mkdir /opt/job-queue
Çalışma kuyruğu için yukarıdaki klasör içerisine girilerek aşağıdaki şekilde bir dosya oluşturulur.
cd /opt/job-queue
vim workqueue
1
2
3
4
5
6
7
8
9
10
11
12
Job çalıştırıldığında oluşturulmuş bir script ile bu dosya içerisindeki satırların silinmesini sağlar. Bir önceki satır silinmeden diğer satırın silinmesine geçilmez, bu şekilde çalışma kuyruğuna sahip Job tanımını kavramaya çalışacağız.
Ayrıca yukarıdaki dosyanın bir kopyası da alınır. İş bittiğinde durum kontrolü yapılması sağlanır.
cp workqueue workqueue1
Şimdi oluşturduğumuz dosya içerisinden silme işlemi yapacak script yazılır.
vim job-script.sh
#!/bin/bash
for counter in 1 2 3 4 5 6 7 8 9 10 11 12
do
if [ -s /opt/job-queue/workqueue ]
then
echo " Is sirasindan is yapildi "
sed -i '1d' /usr/share/jobdemo/workqueue
sleep 1
else
echo " Is yapilmadi. "
exit 0
fi
done
exit 0
Yukarıdaki komut ile 12 ye kadar döngü oluşturulmuştur. Daha sonra oluşturduğumuz dosya içerisinde satır var ise o satırın silinmesi sağlanır ve 1 saniye bekler daha sonra exit 0 kodu ile çıkış yapılması sağlanır. Eğer satır yok ise iş yapılamadı çıktısı ile birlikte döngüden exit 0 başarılı kodu ile çıkış yapılması sağlanır. Şimdi podların bu script ve dosyayı kullanması için daha anlatmadığım persistent volume işlemi ile kalıcı birim oluşturulması sağlanır. Persistent volume konusuna daha sonra kubernetes tanımlar yazımda değineceğim.
vim persistent-volume.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: persistent-volume
labels:
birim: yerlesik
spec:
capacity:
storage: 10Mi
accessModes:
- ReadWriteOnce
hostPath:
path: "/opt/job-queue"
Şimdi persistent volume nesnesinin oluşturulması sağlanır.
kubectl create -f persistent-volume.yaml
Oluşturulan PV nesnesi aşağıdaki şekilde gözlemlenebilir.
kubectl get pv
Şimdi oluşturduğumuz bu alanı talep etmek için persistent volume claim nesnesi oluşturalım.
vim persistent-volume-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-persistent-volumeclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
kubectl create -f persistent-volume-claim.yaml
Şimdi oluşturulan bu yapıları kullanarak Job nesnemizi oluşturalım. Bu iş nesnesi oluşturduğumuz belgeden nesne silen scriptin çalıştırılmasını sağlar. Burada 12 satır olduğu için her bir satırı silip 1 saniye bekleyecektir. Bu bekleme Job nesnesinin çalıştırdığı scriptten kaynaklanmaktadır.
vim workqueue.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-workqueue
spec:
template:
spec:
volumes:
- name: my-persistent-volumeclaim
persistentVolumeClaim:
claimName: my-persistent-volumeclaim
containers:
- name: job-deneme
image: alpine
command: ['sh', '/opt/job-queue/job-script.sh']
volumeMounts:
- mountPath: "/opt/job-queue"
name: my-persistent-volumeclaim
restartPolicy: Never
parallelism: 1
kubectl create -f workqueue.yaml
Şimdi podları listeleyelim.
kubectl get pods
Şimdi podların loglarına bakalım ve işlerin yapılıp yapılmadığına bakalım.
kubectl logs job-workqueue-jwzg5
Şimdi ise işlem yapılan belgenin içeriği kontrol edilir. Verilerin silinip silinmediğine bakılır.
vim workqueue
Şimdi aynı işi parellelism kımını 2 yaparak duruma bakalım bu durumda her iki pod silme işlemi yapar.Bu işlemden önce var olan işin silinmesi sağlanır. Ayrıca içeriği silinen dosyanın içeriği tekrar eski haline getirilir.
kubectl delete -f workqueue.yaml
Daha sonra var olan yaml dosyası düzenlenmek üzere açılır.
vim workqueue.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-workqueue
spec:
template:
spec:
volumes:
- name: my-persistent-volumeclaim
persistentVolumeClaim:
claimName: my-persistent-volumeclaim
containers:
- name: job-deneme
image: alpine
command: ['sh', '/opt/job-queue/job-script.sh']
volumeMounts:
- mountPath: "/opt/job-queue"
name: my-persistent-volumeclaim
restartPolicy: Never
parallelism: 2
kubectl create -f workqueue.yaml
kubectl get pods
Şimdi podların loglarına bakalım.
kubectl logs job-workqueue-bhl94
kubectl logs job-workqueue-bxl66
KUBERNETES CRONJOB İLE İLGİLİ UYGULAMALAR
Aşağıdaki anlatımda kubernetes tanımlar sayfasında CronJob ile ilgili anlattığım durumları uygulayacağız.
Öncelikle CronJob tanımı ile ilgili yaml dosyası oluşturalım. Oluşturacağımız CronJob her dakikada bir echo komutu ile ekrana mesaj yazdıracaktır.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 5']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
concurrencyPolicy: Allow
Şimdi ilgili yaml dosyasından CronJob nesnesi oluşturalım.
kubectl create -f cronjob.yaml
Şimdi CronJob nesnesinin oluşturduğu podlara bakalım.
kubectl get cronjob
Yukarıda podları listelediğimizde çalışıp tamamlanan podlar listelenmektedir.
Şimdi CronJob nesnesinin içeriğine bakalım.
kubectl describe cronjob cron-job-example
Yukarıda görüldüğü üzere CronJob nesnesi çalıştığından itibaren dakikada bir ilgili podu oluşturarak ayaga kaldırır ve çalışmasını sağlar daha sonra ilgili pod çalıştıktan sonra completed veya error olarak kapanır.
Şimdi ilgili pod’un loglarına bakalım. İlgili mesajın yazılıp yazılmadığına bakaılm.
kubectl get pods
kubectl logs cron-job-example-1586719860-8bk5v
Şimdi CronJob nesnesi için concurrencyPolicy durumunu inceliyelim. Öncelikle varsayılan ayar olan Allow seçeneğini inceleyelim. Bu durum aynı anda aynı iş nesnesi tarafından oluşturulmuş podların çalışmasına izin verir. Her bir dakikada çalışacak şekilde iş nesnesi oluşturup, iş nesnesine bağlı olan podların 90 saniye beklemeleri sağlanacaktır. Bu bekleme ile oluşan pod çalışmasına 90 saniye boyunca devam edecektir. 60 saniye dolduğunda ise diğer podun oluşması sağlanacaktır. Böylelikle aynı anda aynı iş için podların çalışması sağlanacaktır.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 90']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
concurrencyPolicy: Allow
Şimdi cronjob nesnesini oluşturalım.
kubectl create -f cronjob.yaml
kubectl get pods
Resimde görüldüğü üzere 60 saniye sonrasında diğer pod’un oluşturulması sağlanmıştır. Şimdi var olan cronjob’un silinmesi sağlanır. Ve diğer policy seçeneği incelenmek üzere yeni cronjob nesnesi oluşturulur.
kubectl delete -f cronjob.yaml
Forbid policy seçeneği incelenmek üzere yukarıdaki yaml dosyası düzenlenir. Bu durumda aynı cronjob nesnesine bağlı pod’un oluşması gerekiyorsa bu anda ilk oluşturulan pod çalışıyorsa yeni pod’un oluşturulması engellenir.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 90']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
concurrencyPolicy: Forbid
Cronjob nesnesini oluşturalım ve durumu inceliyelim.
kubectl create -f cronjob.yaml
kubectl get pods
Yukarıda görüldüğü üzere 86 saniye geçmesine rağmen diğer podun oluşturulması engellenmiştir. Aşağıdaki görselde ise 90 saniye geçtikten sonra yeni pod’un oluşturulduğu gözlemlenmiştir.
Replace policy seçeneği incelenmek üzere yukarıdaki yaml dosyası açılarak düzenlenmesi sağlanır. Bu durumda aynı cronjob nesnesine bağlı pod çalışırken yeni bir pod çalışması başlayacak ise eski podun çalışması sonlandırılır ve yeni podun çalışması sağlanır. Bu adımlardan önce eski işin silinmesi sağlanır. Silme iki işlem ile gerçekleştirilebilir.
kubectl delete cronjob cron-job-example
kubectl delete -f cronjob.yaml
Daha sonra cronjob nesnesine ait yaml dosyası açılarak düzenlenmesi sağlanır.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 90']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
concurrencyPolicy: Replace
Daha sonra ilgili cronjob nesnesi oluşturulur.
kubectl create -f cronjob.yaml
60 dk aralıklar ile çalışan pod oluşturulup çalışması sağlanır. 90 saniye bekleme süresi olduğu için ikinci pod’un çalışma vakti geldiğinde ilk pod silinir diğer podun çalışması sağlanır. Aşağıdaki görsel bu durumu ifade etmektedir.
kubectl get pods
Şimdi isteğe bağlı bir durum olan suspend durumunu inceleyelim.Bu ayar öncesinde var olan cronjob nesnesinin silinmesini sağlayalım.
kubectl delete -f cronjob.yaml
Şimdi ise yeni aşağıdaki kod ile yeni bir cronjob nesnesinin oluşmasını sağlayalım ve ardından suspend komutunun eklenmesi ile çalışmasında hangi değişiklikler olduğunu gözlemleyelim.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 15']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
kubectl create -f cronjob.yaml
Daha sonra cronjobların listelenmesini sağlayalım.
kubectl get cronjob
Görselde gözlemlendiği üzere nesnenin suspend durumunun false olarak kaldığı gözlemlenmektedir. Şimdi Aşağıdaki şekilde yaml dosyasını açıp ilgili satırın eklenmesini sağlayalım ve kodu replace ederek tekrar çalıştırılmasını sağlayalım.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 15']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
suspend: true
kubectl replace -f cronjob.yaml
kubectl get cronjob
Şimdi var olan podların listelenmesini sağlayalım. Ayrıca yukarıda görselde görüldüğü üzere en son schedule yapıldığı zamanın 67 sn önce olduğu gözlemlenmekte.Bu durumda podları listelediğimizde en son çalışan ve tamamlanan podların listelenmesini sağlayacağız ve çalışan pod eklenmediğini göreceğiz.
Bu durumda tekrar suspend satırını silerek veya false yaparak replace komutu tekrar pod schedule edilmesini sağlayabiliriz. Aşağıda bulunan görsel üzerinde bu durum açıkça gözlemlenmektedir.
kubectl get pods
kubectl get cronjob
Şimdi startingDeadlineSeconds durumunu incelemek üzere aşağıdaki şekilde yaml dosyası açılır ve içeriği aşağıdaki şekilde düzenlenir. Bu adımları yapmadan önce var olan cronjob nesnesinin silinmesi sağlanır.
kubectl delete -f cronjob.yaml
Aşağıdaki şekilde cronjob nesnesi oluşturulur. Aşağıdaki yaml dosyasında concurrencyPolicy: Forbid satırı ile yeni bir işin gelmesi engellenecektir. Cronjob nesnesi dakida bir çalışacak şekilde ayarlanmıştır. Ve her job çalışınca 80 saniye bekleme süresi verilmiştir. İkinci periyodda yeni bir işin oluşması concurrencyPolicy: Forbid seçeneği ile engellenecektir. Ve yeni bir iş başlaması için startingDeadlineSeconds: 10 komutu ile “10 saniye” verilmiştir. Yeni bir iş vakti geldiğinde “10 sn ” içinde başlamaz ise o iş başarısız sayılacak ve diğer işin schedule zamanına kadar beklenmesi sağlanacaktır. Bu şekilde istedğimiz komutun çaışması gözlemlenmiş olacaktır. Yani; bir iş için 60 dk period verilerek çalışması sağlanmıştır. O iş 80 saniye bekleme komutu ile bekletilerek yeni iş vakti ğeldiğinde yeni işin çalışması engellenmiş olup 10 saniye sonra o işin başarısız olması sağlanarak 80 sn sonunda schedule edilmesi engellenmiştir.
vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cron-job-example
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cron-job-example
image: alpine
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Pod Calisiyor ; sleep 80']
restartPolicy: OnFailure
terminationGracePeriodSeconds: 0
concurrencyPolicy: Forbid
startingDeadlineSeconds: 10
kubectl create -f cronjob.yaml
Şimdi podların listelenmesi sağlayalım.
kubectl get pods
Görselde gözlemlendiği üzere “85 sn ” geçmesine rağmen yeni bir podun oluşması sağlanmamıştır. Yeni pod yeni schedule zamanı yani “2 dk” sonra oluşturulmuştur. Aşağıdaki görsel durumu özetlemektedir.
kubectl get pods
KUBERNETES VOLUME TANIMLAMASI
Öncelikle volume işlemi yapılaması için kaç adet worker-node var ise içerisinde volume yapmak istediğiniz dizin içerisine ilgli klasörün açılması açılması sağlanır. Tabi birden fazla node olması durumunda bu pratik bir iş değildir. Bu sebeble podunuzun hangi node üzerinde oluşmasını istiyorsanız o node üzerinde oluşacak şekilde node selector, taint,toleration tanımlaması yapılmalıdır. Bu konulara daha sonra değineceğim. Biz burada nginx pod’unun oluşturulmasını sağlayacağız ardından ilgili pod’un web sayfalarının olduğu klasörü ilgili dizine mount edilmesini sağlayacağız.Aşağıdaki şekilde ilgili worker-node’ler üzerinde aşağıdaki şekilde klasör açılması sağlanır.
mkdir /opt/volume
Daha sonra aşağıdaki şekilde kubernetes persistent volume objesi oluşturulması için aşağıdaki şekilde yaml dosyası oluşturulmalıdır.
vim persistent_volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
labels:
type: local
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/opt/volume"
Storage Class Oluşturulması
Bu başlık altında storage class oluşturulması hakkında bilgi akataracağım. Burada kubernetes üzerinde privisioner ihtiyacıı olmayan local bir storage class kurulmasını sağlayacağım. Fakat Storage classımız dynamic provisioner olarak destek vermemektedir.
vim storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: test-storage
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain
volumeBindingMode: Immediate
kubectl create -f storageclass.yaml
Daha aşağıdaki komut ile oluşturduğumuz storage class listeleyelim.
kubectl get storageclass
Şimdi PV ve PVC tanımı oluşturarak duruma bakalım.
vim test_pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: testpv
labels:
type: local01
spec:
storageClassName: "test-storage"
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/opt/"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: testpvc
spec:
storageClassName: "test-storage"
volumeName: "testpv"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f test_pvc.yaml
Şimdi aşağıdaki şekilde kontrol edelim. Tabi bu yöntem ile yukarıdaki gibi pv tanımı oluşturmamız gerekti. Aslında diğer STC(Storage Class) kurulumlarında böyle bir ihityacımız olamayacak. Local STC dynamic provision şeklinde alan vermeyi desteklememektedir.
kubectl get pvc
KUBECTL İLE MULTİPLE CLUSTERIN YÖNETİLMESİ
NOT: Burada kontrol için iki adet yol anlatacağım. Birinci yolda her iki clusterın master node üzerinde bulunan default kurulumda gelen config dosyalarını kullanarak yapacağım. Burada bazı durumlar ile karşılaştım bunları size anlatmaya çalışacağım. Bu yönetem ile cluster master node üzerinde yapacağınız bütün işlemler kısıtlanmamış haliyle uzaktan da yapılabilecektir. Eğer zararlı bir kullanıcı ilgili makineye erişir ise tüm cluster yönetimini admin olarak kontrol edebilir ve kendisi için gerekli zararı verebilir. Biliyoruz ki zarar vermek iyi insanların işi değildir ve onlar için gerekli değildir.:)
CONFIGURASYON DOSYALARININ TAŞINMASI YÖNTEMİ İLE KONTROL
Burada “kubectl” komutu kubernetes kurulu olmayan bir linux makine üzerinden birden fazla kubernetes cluster’ının yönetilmesi anlatılacatır. Konu anlatımında 1 adet 1 master ve 1 worker node sahip cluster ve 1 adet master node sahip cluster ve “kubectl” kuracağımız bir adet linux makine kullanılmıştır. İlgili kubernetes kurulumu için gerekli bilgiye buradan ulaşabilirsiniz.
Öncelikle aşağıdaki şekilde uzaktan kontrol sağlayacağımız makine üzerinde “kubectl” uygulamasının kurulumu yapılır. Ayrıca bu makinenin her iki cluster’a erişmesi gerekmektedir.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
echo "$(<kubectl.sha256) kubectl" | sha256sum --check
Şimdi aşağıdaki şekilde versiyon kontrolü sağlayalım.
kubectl version --client
Şimdi her iki cluster’ın config dosyalarını taşıyacağız. Taşıma işlemi kopyalama yöntemi ile gerçekleştirilecektir.. Önce “.kube” klasörü oluşturup yetki vereceğiz daha sonra 1. cluster için dosya taşıma işlemini yapacağız.
mkdir -p $HOME/.kube
vim ~/.kube/cluster_one
Şimdi 2. Cluster için dosya taşıma işlemini yapalım.
vim ~/.kube/cluster_two
chown $(id -u):$(id -g) $HOME/.kube/*
Daha sonra aşağıdaki şekilde her iki cluster üzerindeki durumları kontrol edebiliriz.
kubectl get nodes --kubeconfig=/root/.kube/cluster_one
kubectl get nodes --kubeconfig=/root/.kube/cluster_two
NOT: Aşağıdaki şekilde birden fazla config dosyasını export edip kullanabiliriz ve komut sonuna konfig dosyasını belirtmemize gerek kalmadan kullanabiliriz. Fakat bu durumda her iki clusuter’ı biribirnde ayıran parametlerin olması gerekmektedir. Burada her iki clusterımız aynı isme sahip ve aynı user bilgisi ve aynı context isminde yani clusterı birbirinde ayıran değerler aynı. Bu bilgiler aynı olduğu için kullanımda hata alacaktır. Yani biz her seferinde context değiştirdiğimizde aynı clustera gidecektir. Bu sebeble cluster kurulum aşamasındayken clustera özel bilgiler verilmelidir. Aşağıdaki şekilde iki adet cluster’a ait config dosyaları export edilebilir.
Multiple config dosyası export etme;
export KUBECONFIG=~/.kube/cluster_one:~/.kube/cluster_two
Şimdi contextleri listeleyelim;Tabi burada her iki config dosyası aynı değerlere sahip olduğu için tek bir context ismi gelecektir.
kubectl config get-contexts
Şimdi farkı görmek için config dosyalarından birini değiştirelim.(Context kısmını cluster_one dosyası içerisinde değiştirip listeleyeceğim.)
kubectl config get-contexts
Yukarıda görüldüğü gibi context ismi değiştirildikten sonra listede iki adet görülmüştür. Daha sonra contextleri değiştirip clustera bağlantı sağlamak istediğimizde hep aynı cluster’a gidecektir. Cluster ismi değiştirilse bile bu seferde user bilgisi aynı olduğu için bir cluster’a gidip diğer clusterda login hatası alacaktır. Şimdi bu durumları deneyelim.
Öncelikle yukarıdaki görselde görüldüğü üzere listelenmiş context’ler için birinci context aktif context oalrak gözükmekte, biz bunu değiştireceğiz ve ikinci context’e geçiş yapacağız daha sonra yine node’ların listelenmesini sağlayacağız. Sonuçta yine aynı cluster’a gittiğini gözlemleyeceğiz.
kubectl config use-context kubernetes1-admin@kubernetes
Şimdi node’ları listeleyelim. Biliyoruz ki bir cluster’ımız tek node sahip. Diğer cluster’ımız iki adet node sahip. Şimdi node’ları listeleyerek hangi cluster’a gittiğini bulabiliriz. Context ismi değişse bile yine aynı cluster’a gidecektir.
Görselde gördüğümüz gibi yine aynı cluster’a gitmiştir.
SERTIFIKA VE KULLANICI OLUŞTURARAK İKİ FARKLI CLUSTERA UZAKTAN ERİŞİM
Not: Burada her cluster’ın ismi farklı olmalıdır. Ayrıca burada anlatılan yöntem bir önceki yönteme göre daha güvenlidir. Var olan clsuterınızda belirli kullanıcılar oluşturabilir, daha sonra bu kullanıcılara yetkiler verebilir ve cluster üzerinde hangi işlemleri yapacağına dair yetkilerek vererek cluster üzerinde işlem yapmalarına izin verebilirsiniz.
Bu bölümde öncelikle sertfika oluşturacağız .Daha sonra bu sertifikaları kubernetes üzerinde imzalayacağız, hemen sonrasında oluşturduğumuz kullanıcı için Cluster rol tanımlama işlemleri yapıp belirli işlemler için yetki vereceğiz. Bu kullanıcılardan 1. cluster için tanımlayacağımız user için sadece node ve podların listelenmesini sağlayacağız. İkinci cluster için tanımlayacağımız user için ise deployment ve job’rın listelenmesini sağlayacağız. Ayrıca her iki kullanıcı için kubernetes üzerinde tanımlı admin rolünü bu kullanıcılar için verebileceğimizi unutmamız gerekir. Hadi başlayalım.
Öncelikle aşağıdaki şekilde her iki cluster sertifika oluşturmamız gerekecek.
mkdir /opt/config
cd /opt/config
Cluster1 için:
openssl req -new -newkey rsa:4096 -nodes -keyout user_1-k8s.key -out user_1-k8s.csr -subj "/CN=user1/O=devops"
Cluster2 için:
openssl req -new -newkey rsa:4096 -nodes -keyout user_2-k8s.key -out user_2-k8s.csr -subj "/CN=user2/O=devops"
Şimdi aşağıdaki şekilde sertifikaların imzalanmasını sağlayacağız. Öncesinde aşağıdaki komut ile csr dosyamızın içeriğini base64 ile şifreliyelim ve içeriğini aşağıdaki şekilde oluşturacağımız yaml dosyası içerisine request kısmına ekleyelim. Bu işlemler her iki cluster içerisinde de yapılması gerekir.
cat user_1-k8s.csr | base64 | tr -d '\n'
vim k8s-csr_config.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: user1-k8s-access
spec:
groups:
- system:authenticated
request: <bu kısıma sertifika'nın şifrelenmiş hali yazılır>
usages:
- client auth
kubectl create -f k8s-csr_config.yaml
kubectl get csr
Aynı işlemleri diğer cluster’ımızda işaretli alan user2 olacak şekilde ayarlıyalım ve create edelim.
Yukrarıda görüldüğü üzere her iki sertifika Condition kısmında Pending olarak gözükmekte. Şimdide oluşturduğumuz sertfikayı onaylıyalım.
kubectl certificate approve <csr_name>
Tekrar sertifika imzalama objelerimizi çağıralım ve onaylandığını gözlemliyelim.
Şimdi CSR objemizden “.crt” uzantılı sertifikamızı her iki cluster üzerinde aşağıdaki komut ile oluşturalım.
kubectl get csr user1-k8s-access -o jsonpath='{.status.certificate}' | base64 --decode > user1-k8s-access.crt
İkinci cluster üzerinde de oluşturalım.
kubectl get csr user2-k8s-access -o jsonpath='{.status.certificate}' | base64 --decode > user2-k8s-access.crt
Şimdi aşağıdaki şekilde diğer bir gereksinim olan CA sertıfikasını elde etmemiz gerekicek. Bu kısmda mevcut cluster config dosyası içerisinde bulunan CA alınarak yapılacaktır. İşlem her iki cluster için yapılacaktır.
kubectl config view -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' --raw | base64 --decode - > k8s-ca.crt
Şimdide aşağıdaki şekilde oluşturacağımız konfigürasyon dosyası içerisine .crt dosyasının eklenmesini her iki cluster içerisinde sağlayalım.
kubectl config set-cluster $(kubectl config view -o jsonpath='{.clusters[0].name}') --server=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}') --certificate-authority=k8s-ca.crt --kubeconfig=user1-k8s-config --embed-certs
kubectl config set-cluster $(kubectl config view -o jsonpath='{.clusters[0].name}') --server=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}') --certificate-authority=k8s-ca.crt --kubeconfig=user2-k8s-config --embed-certs
Ayrıcaa user,client certificate ve client key ksımlarının eklenmesi gerekir.Aşağıdaki komutlar yardımı ile her iki cluster içerisinde o kısımların doldurulmasını sağlayalım.
Cluster1 için:
kubectl config set-credentials user1 --client-certificate=user1-k8s-access.crt --client-key=user_1-k8s.key --embed-certs --kubeconfig=user1-k8s-config
Cluster2 için:
kubectl config set-credentials user2 --client-certificate=user2-k8s-access.crt --client-key=user_2-k8s.key --embed-certs --kubeconfig=user2-k8s-config
Şimdi aşağıdaki şekilde her iki cluster için config dosyası içerisinde context kısmını ekleyelim.
kubectl config set-context user1 --cluster=$(kubectl config view -o jsonpath='{.clusters[0].name}') --namespace=user1 --user=user1 --kubeconfig=user1-k8s-config
kubectl config set-context user2 --cluster=$(kubectl config view -o jsonpath='{.clusters[0].name}') --namespace=user2 --user=user2 --kubeconfig=user2-k8s-config
Yukarıda kod satırımız içerisinde namespace kısmında user1 ve user2 adında her iki cluster için namespace belirtilmesi sağladık. Şimdi aşağıdaki şekilde her iki cluster için namespace oluşturalım.
Cluster1 için:
kubectl create ns user1
Cluster2 için:
kubectl create ns user2
Bu adımlardan sonra cluster içerisinde podların çağırılmasını sağlayalım. Önce mevcut contexti değiştireceğiz ve sonları podların listelenmesini sağlayacağız. Tabi bu işlemler her iki cluster içerisinde yapılacaktır.
Cluster1 için:
kubectl config use-context user1 --kubeconfig=user1-k8s-config
Cluster2 için:
kubectl config use-context user2 --kubeconfig=user2-k8s-config
kubectl get pods --kubeconfig=user1-k8s-config
Aşağıdaki şekilde yetki yok şeklinde hata almamız gerekir.
Şimdi her iki cluster üzerinde bu kullanıcı için cluster role ve clutser role binding tanımlaması yapalım.
Cluster1 için:
vim cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: user1-cr
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
resources: ["pods","nodes"]
verbs: ["get", "watch", "list"]
kubectl create -f cr.yaml
vim crb.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user1-crb
subjects:
- kind: User
name: user1 # Yetki vereceğimiz userın ismi
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: user1-cr
apiGroup: rbac.authorization.k8s.io
kubectl create -f crb.yaml
Cluster2 için:
vim cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: user2-cr
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
resources: ["pods","nodes"]
verbs: ["get", "watch", "list"]
kubectl create -f cr.yaml
vim crb.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: user2-crb
subjects:
- kind: User
name: user2 # Yetki vereceğimiz userın ismi
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: user2-cr
apiGroup: rbac.authorization.k8s.io
kubectl create -f crb.yaml
Şimdi aşağıdaki şekilde 1.cluster içerisinde yukarıdaki verdiğimiz yetki ile podların listelenmesini sağlayalım. Verdiğimiz yetkiye göre sadece pod’lar ve node’lar üzerinde “get”, watch”, “list” işlemleri yapabileceğiz.
kubectl get pods --kubeconfig=user1-k8s-config
kubectl get nodes --kubeconfig=user1-k8s-config
Şimdi yetkimiz olamayan bir kubernetes objesini listelemeye çalışalım. Yetkiniz yok diye hata almamız gerekir. Örn: Deployment nesnesini listelemeye çalışalım.
kubectl get deploy --kubeconfig=user1-k8s-config
Görüldüğü üzere hata alınmıştır. Ayrıca default olarak ayarladığımız user1 name space içerisinde sorgulama yapmaktadır bunun değiştirilmesini sağlayarak dilediğimiz namespace üzerinde işlem yapabiliriz.
kubectl get pods --kubeconfig=user1-k8s-config -n kube-system
Şimdi hazırladığımız bu konfigürasyon dosyalarının uzaktan kontrol edeceğimiz sunucu üzerine kaydedelim ve kontrol işlemi için aşağıdaki adımları takip edelim.
Öncelikle aşağıdaki şekilde bir klasör oluşturalım. Aşağıdaki şekilde her cluster için oluşturduğumuz dosyaların içeriğini kopyalayarak aynı isimde aşağıda oluşturacağımız klasör içerine dosyaları oluşturalım..
mkdir /opt/configs
cd /opt/configs
vim user1-k8s-config
Aynı işlem ikinci clusterı yöneteceğimiz user2 içinde yapılmalıdır.
vim user2-k8s-config
Vakit Buldukça Yazmaya Devam Edeceğim.
2 Responses
Emeginize saglik, gayet yararli bir yazi olmus.
Merhaba,
Çok teşekkür ederim inşallah faydalı olmuştur.