Merhaba arkadaşlar, bu yazımda Kubernetes Volumes konusunun örneklerini yapacağız.
Container dosyaları geçici dosyalardır. Bir container’ın yıkılması veya yeniden başlatılması durumunda kaybolacaktırlar. Ek olarak bir pod içerisindeki container’lar arasında dosyaları paylaştırmak için birtakım yöntemlere ihtiyacımız olacaktır.
Volume, bir pod’daki container’lar tarafından erişilebilen bir dizindir. Mevcut Docker volume’lerinin aksine, bir Kubernetes volume’ü pod’ların yaşam döngüsüne sahiptir, container’ların değil. Aynı pod içerisinde farklı volume’lere sahip dizinler kullanılabilir ancak volume’ler içe içe geçmezler. Her birinin kendi bağlantı noktası olması gerekir. Volume’leri spec.volumes ve spec.containers.volumeMounts parametreleri ile bildiririz.
ConfigMap Kullanımı
Temel olaark bir key-value (anahtar- değer) çiftlerine sahip ConfigMap örnekleri yapacağız. Bu özelliklele verileri hazır duruma getirip pod’lara ortam değişkeni veya configürasyon verileri olarak okutabiliriz. Bir ConfigMap, Secret‘ın küçük halidir. Fark olarak base64 olarak şifrelenmemektedir. String formatında depolanırlar.
Bir ConfigMap’in veri alabilmesi için farklı üç yöntem vardır: Literal, Individual ve File. Bunları inceleyelim.
Şehirleri içeren bir ConfigMap oluşturacağız. ConfigMap’e tanımlanacak bir dizi dosya yaratacağız. İlk önce bir dizi oluşturup bunun içerisine dört tane şehir dosyası ve yaşadığımız şehiri belirten dosyalar oluşturacağız. Bu örnek üzerinden ConfigMap’i anlamaya çalışacağım.
$ mkdir sehirler
$ echo 34 > sehirler/istanbul
$ echo 61 > sehirler/trabzon
$ echo 55 > sehirler/samsun
$ echo 55 > sehirler/ankara
$ echo "baskent" >> sehirler/ankara
$ echo yalova > yasanilanSehir
Şimdi bir ConfigMap oluşturup bu dosyaları ekleyelim.
$ kubectl create configmap sehirler --from-literal=text=ankara --from-file=./sehirler --from-file=./yasanilanSehir
configmap/sehirler created
ConfigMap’imizi listeleyelim, bakalım nasıl bir sonuç elde edeceğiz.
$ kubectl get configmap sehirler
NAME DATA AGE
sehirler 6 44s
$ kubectl get configmap sehirler -o yaml
apiVersion: v1
data:
ankara: |
06
baskent
istanbul: |
34
samsun: |
55
text: ankara
trabzon: |
61
yasanilanSehir: |
yalova
kind: ConfigMap
....
Artık oluşturduğumuz ConfigMap’i kullanmak için bir pod oluşturup deneyebiliriz.
$ vim config-ornek.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-ornek
spec:
containers:
- name: nginx
image: nginx
env:
- name: ortam
valueFrom:
configMapKeyRef:
name: sehirler
key: yasanilanSehir
$ kubectl create -f config-ornek.yaml
pod/config-ornek created
$ kubectl exec -it config-ornek -- /bin/bash -c 'echo $ortam'
yalova
$ kubectl delete po config-ornek
pod "config-ornek" deleted
Evet arkadaşlar burda oluşturduğumuz pod içerisinde ortam değişkeni belirledik. Bunuda env anahtarı ile gerçekleştirdik. Ardından bu ortam değişkenine ConfigMap’teki yasanilanSehir değerini yerleştirdik. Sonra pod içerisinde komut çalıştırarak ekrana yazdırdık. yalova yazısını gördük. Şimdi daha gelişmiş bir örnek yapalım. YAML dosyamızı açalım ve aşağıdaki kodlarla değiştirelim ve sonuca bakalım.
$ vim config-ornek.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-ornek
spec:
containers:
- name: nginx
image: nginx
envFrom:
- configMapRef:
name: sehirler
$ kubectl create -f config-ornek.yaml
pod/config-ornek created
$ kubectl exec -it config-ornek -- /bin/bash -c 'env'
HOSTNAME=config-ornek
NJS_VERSION=1.15.12.0.3.1-1~stretch
NGINX_VERSION=1.15.12-1~stretch
samsun=55
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
text=ankara
KUBERNETES_PORT=tcp://10.96.0.1:443
PWD=/
HOME=/root
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_PORT=443
ankara=06
baskent
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
TERM=xterm
yasanilanSehir=yalova
SHLVL=1
KUBERNETES_SERVICE_PORT=443
istanbul=34
trabzon=61
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_SERVICE_HOST=10.96.0.1
_=/usr/bin/env
$ kubectl delete pod config-ornek
pod "config-ornek" deleted
Burda sonuca baktığımzı zaman oluşturulan pod’un tüm ortam değişkenlerini listelediğimzide bizim YAML dosyasında belirttiğimiz ConfigMap’inde bu listede göründüğünü fark ettik. Kısaca ConfigMap’i kısıtlayıp pod’a atayabiliriz veya direk kayıtlı ConfigMap’i atayabiliriz.
Şimdi YAML dosyası üzerinden bir ConfigMap oluşturalım ve listeleyelim. Ardından bir pod oluşturup denemesini gerçekleştirelim.
$ vim telefon-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: akilli-telefon
namespace: default
data:
telefon.marka: Huawei
telefon.model: P30
$ kubectl create -f telefon-map.yaml
configmap/akilli-telefon created
$ vim config-map.yaml
apiVersion: v1
kind: Pod
metadata:
name: config-ornek
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: telefon-vol
mountPath: /etc/telefon
volumes:
- name: telefon-vol
configMap:
name: akilli-telefon
Artık ConfigMap’i bir pod’a mount edilmiş bir volume olarak kullanabilmeyi sağlayacağız.
$ kubectl create -f config-ornek.yaml
pod/config-ornek created
$ kubectl exec -it config-ornek -- /bin/bash -c 'df -ha | grep telefon'
/dev/sda1 9.7G 2.7G 7.0G 28% /etc/telefon
$ kubectl exec -it config-ornek -- /bin/bash -c 'cat /etc/telefon/telefon.marka'
Huawei
Görmüş olduğunuz üzere volume mount ettik ve ardından ConfigMap’i bu birime yerleştirdik. Bu önceki örneğe göre daha standardize olmuş bir örnek oldu. Şimdi bu pod’u silip bir sonraki başlığımıze geçebiliriz.
$ kubectl delete pods config-ornek
pod "config-ornek" deleted
$ kubectl delete configmap akilli-telefon sehirler
configmap "akilli-telefon" deleted
configmap "sehirler" deleted
Kalıcı NFS Volume’ü Oluşturalım (PV)
(Persistent Volume)
İlk önce NFS sunucusu dağtıacağız ve test edeceğiz. Sonra container’ların taleplerine göre onlara NFS volume oluşturacağız.
Bunun için ilk olarak NFS sunucusu kurmak için aşağıdaki yazılımı kurmamız gerekiyor.
$ sudo apt-get update && sudo apt-get install -y nfs-kernel-server
Bir dizin oluşturup içini dolduralım.
$ sudo mkdir /opt/ylv
$ sudo chmod 1777 /opt/ylv
$ sudo bash -c 'echo yalova > /opt/ylv/merhaba.txt'
Yeni oluşturulan dizini paylaşmak için NFS sunucusu dosyasını düzenlememiz lazım. Dizini herkesle paylaşacağız.
$ sudo vim /etc/exports
/opt/ylv/ *(rw,sync,no_root_squash,subtree_check)
Yukarıdaki dizini açtığımzıda örnek ekleme şekillerini görürüz. Hemen altında yazan değeri dosyanın içine ekledik.
Eklediğimiz yazıyı etkinleştirmek için dosyayı tekrardan okutmamız lazım. Okutmak için aşağıdaki kodu çalıştırıyoruz.
$ sudo exportfs -ra
Ortamımızda iki node bulunduğu için kaynağı ikinci node’a mount edip test etmemiz lazım. Şimdi worker-node-1 node’una bağlanalım ve aşağıdaki komutları çalıştıralım.
$ (worker-node-1) sudo apt-get -y install nfs-common
....
$ (worker-node-1) showmount -e master-node-1
Export list for master-node-1:
/opt/ylv *
$ (worker-node-1) sudo mount 10.128.0.2:/opt/ylv /mnt
$ (worker-node-1) ls -l /mnt
total 4
-rw-r--r-- 1 root root 7 Apr 18 14:45 merhaba.txt
worker-node-1’de master-node-1’e kurduğumuz volume’ü mount ettik ardından test işlemini sağladık. Şimdi master-node’umuza dönebiliriz.
Oluşturduğumuz ve kurduğumuz NFS volume’ünü şimdi bir pod aracılığıyla test edelim.
$ vim PVol.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvvol
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /opt/ylv
server: master-node-1
readOnly: false
$ kubectl create -f PVol.yaml
persistentvolume/pvvol created
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
pvvol 1Gi RWX Retain Available ....
Kalıcı Claim Volume Oluşturalım (PVC)
(Persistent Volume Claim)
Pod’ların yeni PV’den yararlanması için PVC oluşturmamız gerekiyor. Hadi başlayalım.
$ kubectl get pvc
No resources found.
$ vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-deneme
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi
Yeni PVC’yi kuralım ve bağlı olduğunu doğrulayalı. 200Mi önermesine rağmen boyutun 1Gi olduğunu unutmayalım. Sadece bir volume bu boyutu kullanabilir.
$ kubectl create -f pvc.yaml
persistentvolumeclaim/pvc-deneme created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-deneme Bound pvvol 1Gi RWX 2s
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
pvvol 1Gi RWX Retain Bound default/pvc-deneme
$ kubectl delete pvc pvc-deneme
$ kubectl delete pv pvvol
PVC Adetini ve Kullanımını Sınırlamak için ResourceQuota Kullanımı
Cloud tabanlı depolamanın esnekliği, genellikle kullanıcılar arasında tüketimin sınırlandırmasını gerektirir. Hem toplam tüketimi hemde kalıcı Volume Claim talep sayısını sınırlandırmak için ResourceQuota nesnesini kullanacağız.
ResourceQuota nesnesi için bir YAML dosyası oluşturalım. Toplam 500Mi kullanımıyla depolama sınırı ve 10 claims ayarlayacağız.
$ vim depolama-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-quota
spec:
hard:
persistentvolumeclaims: "10"
requests.storage: "500Mi"
Bir namespace oluşturacağız. Adını “kucuk” olarak belirleyeceğiz ve sınırlandırma getireceğiz.
$ kubectl create namespace kucuk
namespace/kucuk created
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
No resource limits.
Oluşturduğumuz namespace içerisinde bir önceki başlıkta oluşturduğumuz YAML dosyalarını dağıtıyoruz.
$ kubectl -n kucuk create -f PVol.yaml
persistentvolume/pvvol created
$ kubectl -n kucuk create -f pvc.yaml
persistentvolumeclaim/pvc-deneme created
ResourceQuota’mızıda bu namespace içerisinde oluşturuyoruz.
$ kubectl -n kucuk create -f depolama-quota.yaml
resourcequota/storage-quota created
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
Resource Quotas
Name: storage-quota
Resource Used Hard
-------- --- ---
persistentvolumeclaims 1 10
requests.storage 200Mi 500Mi
No resource limits.
Namespace’imizin detaylarını görüntülediğimiz zaman artık ResourceQuota’nın namespace içerisinde aktif olduğunu görebiliriz.
Şimdi bu namespace’de bir deployment çalıştırma vaktimiz geldi. Sizin için önceden hazırladığım bu adresteki YAML dosyasını dağıtacağız. YAML dosyasındaki değerler bu başlık altındaki PV ve PVC’nin adları hedef alınarak düzenlenmiştir. Eğer siz başka isimde oluşturduysanız düzenleyip ardından dağıtımı başlatmalısınız.
$ wget https://tinyurl.com/y3pysh7x -O nfs-vol.yaml
$ kubectl -n kucuk create -f nfs-vol.yaml
deployment.apps/nginx-nfs created
$ kubectl get deploy --namespace=kucuk
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-nfs 1/1 1 1 20s
Oluşturulan pod’u inceleyelim.
$ kubectl get po -n kucuk
NAME READY STATUS RESTARTS AGE
nginx-nfs-7f5f75d6fd-94hq8 1/1 Running 0 65s
$ kubectl -n kucuk describe pod nginx-nfs-7f5f75d6fd-94hq8
....
Mounts:
/opt from nfs-vol (rw)
....
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
Resource Quotas
Name: storage-quota
Resource Used Hard
-------- --- ---
persistentvolumeclaims 1 10
requests.storage 200Mi 500Mi
No resource limits.
Burada nfs-vol içerisinden /opt dizininin mount edildiğini teyit ettik. Şimdi /opt/ylv dizininin içerisinde 300Mi’lık bir dosya oluşturalım ve ResourceQuota’yı tekrardan görüntüleyelim.
$ sudo dd if=/dev/zero of=/opt/ylv/ucyuzlukdosya bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB, 300 MiB) copied, 0.278532 s, 1.1 GB/s
$ du -h /opt/
301M /opt/ylv
101M /opt/cni/bin
101M /opt/cni
401M /opt/
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
Resource Quotas
Name: storage-quota
Resource Used Hard
-------- --- ---
persistentvolumeclaims 1 10
requests.storage 200Mi 500Mi
No resource limits.
Tekrardan ResourceQuotas bilgilerine baktığımızda 300Mi’lik bir dosya oluşturmamıza rağmen burada kullanılan halen 200Mi olarak gösterilmektedir. Çünkü deployment olarak oluşturulmayan dosyalar bu kotaya dahil değildir.
Şimdide nginx-nfs deployment’ımızı silerek kotamıza bakalım nasıl değişecek.
$ kubectl -n kucuk delete deploy nginx-nfs
deployment.extensions "nginx-nfs" deleted
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
Resource Quotas
Name: storage-quota
Resource Used Hard
-------- --- ---
persistentvolumeclaims 1 10
requests.storage 200Mi 500Mi
No resource limits.
Deployment’ımızı kaldırmamıza rağmen şunu görüyoruz kotamız hiçbir şekilde değişmedi. Halbuki 200Mi’lik alanı bu dağıtım karşılıyordu. Demekki sadece dağıtımı silmek kotadan yer açmıyor. Bu işlemleri yönetebilmek için policy’ler oluşturmak veya tanımlamak gerekiyor. Şuanki PV’deki policy’miz Retain olarak tanımlı. Bizim burda bileceğimzi üç tane policy ayarı mevcut: Delete, Retain ve Recycle.
Şimdi policy içeren birtakım örnekler yapalım. Öncelikle işe PVC’mizi ve PV’mizi silerek başlayalım.
$ kubectl -n kucuk delete pvc/pvc-deneme
persistentvolumeclaim "pvc-deneme" deleted
$ kubectl -n kucuk delete pv/pvvol
persistentvolume "pvvol" deleted
Burada tekrardan PV’mizi dağıtalım ve çalışır durumdayken Retain durumunu Delete durumuna çekelim.
$ kubectl create -f PVol.yaml
persistentvolume/pvvol created
$ kubectl patch pv pvvol -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}'
persistentvolume/pvvol patched
$ kubectl get pv/pvvol
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
pvvol 1Gi RWX Delete Available
Şuanki kotamıza bakalım.
$ kubectl describe ns kucuk
Name: kucuk
Labels: <none>
Annotations: <none>
Status: Active
Resource Quotas
Name: storage-quota
Resource Used Hard
-------- --- ---
persistentvolumeclaims 0 10
requests.storage 0 500Mi
No resource limits.
PVC’mizi tekrardan kuralım. Çalıştırılmış olan bir pod olmadığı halde yinede kaynak kullanımını kontrol edelim.
$ kubectl -n kucuk create -f pvc.yaml
persistentvolumeclaim/pvc-deneme created
$ kubectl describe ns kucuk
....
requests.storage 200Mi 500Mi
Herhangi bir pod olmamasına rağmen az önce Retain policy’si aktif olduğu için önceki pod’dan ayrılmış olan alan halen duruyor. Eğer pod’u tekrardan dağıtırsak daha önceden tuttuğu alanı kullanmaya devam edecektir.
Fakat şuanda policy’miz Delete ve şuankinden farklı bir deployment yapar ve silersek bu deployment’ı tutma işlemi yapmayacaktır.
Diğer bir policy olan Recycle adından da anlaşılacağı gibi pod silindiği zaman tutulacak olan alanı bir geri dönüşüm kutusuna koyar ve istersek bu geri dönüşüm kutusundan geri döndürüp pod’a tekrardan kullandırabiliriz.
Labaratuvar yazımız burada sonlandı. Ortamımızda oluşturduğumuz PV, PVC ve namespace’i silelim. Bir sonraki yazımda görüşmek üzere hoşçakalın.
$ kubectl -n kucuk delete deployment nginx-nfs
deployment.extensions "nginx-nfs" deleted
$ kubectl -n kucuk delete pvc/pvc-deneme
persistentvolumeclaim "pvc-deneme" deleted
$ kubectl -n kucuk delete pv/pvvol
persistentvolume "pvvol" deleted
$ kubectl delete ns kucuk
namespace "kucuk" deleted
Umarım bu yazı sizin için bilgilendirici olmuştur. Yazıyla ilgili bir sorunuz, görüşünüz veya isteğiniz varsa alt kısımda bulunan yorumlardan veya mail adresimden iletişime geçebilirsiniz. Bu yazının başkaları içinde bilgilendirici olduğunu düşünüyorsanız sosyal olun ve sosyal medyada paylaşın! Okuduğunuz için teşekkürler !!!!