Longhorn ile Kubernetes’te Dinamik Depolama Tahsisi
Merhaba! Bu yazımda, Kubernetes’te hayati bir rol oynayan Dynamic Storage Provisioning konseptini keşfedecek ve Kubernetes ekosistemi için özel olarak geliştirilmiş açık kaynaklı bir dağıtık blok depolama sistemi(distributed block storage system) olan Longhorn’u keşfederek, uygulamalı bir yaklaşımla bu güçlü aracın nasıl kullanılacağını ele alacağız.
İçerik
- Bölüm 1: Kubernetes Dynamic Storage Provisioning Nedir?
- Bölüm 2: Longhorn Nedir? Temel Bileşenleri ve Avantajları
- Bölüm 3: Cluster Kurulumu ve Ayarları
- Bölüm 4: Longhorn Kurulumu ve Örnekleri
Bölüm 1: Kubernetes Dynamic Storage Provisioning Nedir?
Kubernetes, uygulamalarımızın ölçeklenebilir ve yönetilebilir bir şekilde çalışmasını sağlamak için tasarlanmış güçlü bir konteyner orkestrasyon platformudur. Ancak, bu platformun sağladığı esneklik ve ölçeklenebilirlik, depolama kaynaklarını dinamik bir şekilde yönetme ihtiyacını da beraberinde getirir. İşte tam bu noktada, “Kubernetes Dynamic Storage Provisioning” devreye girer.
Dynamic Storage Provisioning Nedir?
- Dynamic Storage Provisioning, depolama kaynaklarını dinamik olarak tahsis etme sürecini ifade eder. Geleneksel depolama sistemlerinde olduğu gibi, her bir uygulama için önceden belirlenmiş bir depolama alanı oluşturmak yerine, dinamik storage provisioning, uygulamaların ihtiyaçlarına göre depolama alanlarını otomatik olarak sağlar. Bu, ölçeklenme ve kaynakların verimli kullanılması açısından önemlidir.
Static Provisioning ile Dynamic Provisioning Karşılaştırması
Static Provisioning ve Dynamic Provisioning, depolama tahsisinde iki farklı yaklaşım sunar.
Static Provisioning:
- Kullanıcılar önceden belirlenmiş StorageClass ve persistent volume’lar tanımlar. PVC talep edildiğinde, önceden belirlenmiş PV ile eşleşir.
Dynamic Provisioning:
- Depolama kaynakları, uygulama ihtiyaçlarına göre dinamik olarak tahsis edilir. PVC talep edildiğinde, Kubernetes, Storage Class’a dayalı olarak dinamik bir PV oluşturur.
- Kısacası, Static Provisioning’de kullanıcılar önceden tahsis ederken, Dynamic Provisioning’de Kubernetes otomatik olarak tahsis eder.
- Seçim, uygulama gereksinimlerine ve otomatikleştirmeye bağlıdır. Dynamic Provisioning, esneklik ve otomatikleştirme sağlayarak genellikle tercih edilir.
Her iki yöntem de avantajlara sahiptir, ancak dynamic storage provisioning genellikle Kubernetes ortamlarında daha yaygın olarak tercih edilmektedir, çünkü bu yöntem esneklik ve otomatikleştirme sağlar.
Bölüm 2: Longhorn Nedir? Temel Bileşenleri ve Avantajları
Longhorn Nedir?
- Longhorn, Rancher Labs tarafından geliştirilen açık kaynaklı bir distributed block storage system dir. Kubernetes ortamlarında kullanılır ve konteyner uygulamalarının depolama ihtiyaçlarını karşılamak üzere tasarlanmıştır. Kullanıcılara esnek, güvenilir ve ölçeklenebilir bir depolama çözümü sunar, depolama yönetimini basitleştirir ve uygulamaların sorunsuz dağıtılabilmesi için gerekli altyapıyı sağlar. Daha fazla bilgi için web sitesini ziyaret edebilirsiniz.
Longhorn‘un Temel Bileşenleri
- Longhorn Controller Manager: Longhorn’un Kubernetes ortamındaki ana kontrol bileşenidir. Longhorn Controller Manager, Longhorn’un Kubernetes cluster’ı içindeki kaynakları ve olayları izleyerek, Longhorn’un depolama çözümünü etkinleştiren ve yöneten bir bileşendir.
- Longhorn Engine: Longhorn’un ana bileşenidir. Longhorn Engine, depolama işlemlerini yönetir ve depolama hacimlerini sağlar. Dinamik olarak oluşturulan PV’leri (Persistent Volume) yönetir ve veri dayanıklılığını sağlamak için replikaları yönetir.
- Replikalar: Longhorn, verilerin dayanıklılığını artırmak için depolanan verilerin birçok replikasını oluşturabilir. Bu replikalar, farklı Kubernetes node’ları arasında senkronize edilir ve veri kaybını önlemek için kullanılır. Replikalar, Longhorn’un yüksek dayanıklılık ve güvenilirlik sağlayan kilit bileşenleridir.
Longhorn’un Avantajları ve Özellikleri:
- Ölçeklenebilirlik: Longhorn, uygulama ve depolama taleplerinin dinamik olarak büyüdüğü ortamlarda etkili bir şekilde çalışmak üzere tasarlanmıştır. Kubernetes cluster’ınızın büyüklüğüne kolayca uyum sağlayabilme kapasitesine sahiptir, hem küçük hem de büyük ölçekli ortamlarda esneklik sunar.
- Dayanıklılık ve Güvenilirlik: Yüksek dayanıklılık özellikleri ile tasarlanan Longhorn, veri kaybını önlemek ve sistem güvenilirliğini artırmak amacıyla kullanılır. Özellikle felaket senaryolarında veri kurtarma süreçlerini hızlandırarak iş sürekliliğini sağlar.
- Snapshot ve Backup: Longhorn, uygulamaların anlık görüntülerini alabilme (Snapshot) ve belirli zaman aralıklarında depolama verilerini yedekleme (Backup) yeteneklerine sahiptir. Bu özellikler, veri durumlarını koruma, geri yükleme ve olası veri kayıplarına karşı koruma sağlama imkanı sunar.
- Dinamik Hacim Genişletme: Longhorn, “Dinamik Hacim Genişletme” özelliği ile hızlı ve esnek bir şekilde depolama ihtiyaçlarına yanıt verir. Artan veri miktarları veya uygulama talepleri gibi durumlarda otomatik olarak uyum sağlar, bu da sistem yöneticileri ve kullanıcılar için manuel müdahale olmadan performans ve esneklik sağlar.
Bölüm 3: Cluster Kurulumu ve Ayarları
Bu bölümde, Vagrant ve VirtualBox kullanarak Kubernetes cluster’ı kuracağız.
- Öncelikle, bilgisayarınıza Vagrant ve VirtualBox’u indirip kurmalısınız. Aşağıdaki adımları takip ederek her iki aracı da yükleyebilirsiniz.
- Vagrant kurulumu için >> Vagrant Install
- VirtualBox kurulumu için >> Virtualbox Install
Vagrantfile kullanarak sanal makineleri ayağa kaldırma
- Aşağıdaki repomu bilgisayarınıza klonlayıp, komutları takip ederek sanal makinelerimizi oluşturalım.
git clone https://github.com/fatihabdioglu/k8s-vagrant.git
cd k8s-vagrant
vagrant up
- Ardından aşağıdaki komutla nodelarımızın running duruma geldiğini görelim
vagrant status
- Bu işlemlerden sonra terminalden
vagrant ssh master
veyavagrant ssh <node-name>
komutlarıyla istediğimiz Node’a bağlanabiliriz.
vagrant ssh master # Master node üzerinde
kubectl get nodes
kubectl get pods --all-namespaces
- 1 Master ve 2 Worker’dan oluşan 3 node lu bir clusterımız var ve Node’lar running durumda.
- Şimdi Bölüm 4 e geçip Longhorn’un kurulum ve kullanım adımlarına bakabiliriz.
Bölüm 4: Longhorn Kurulumu ve Örnekleri
Bu bölümde, Kubernetes cluster’ımıza dinamik depolama sağlayan Longhorn’u kurarak, uygulamalı örneklerle daha iyi anlamaya çalışacağız.
- Longhorn’u, aşağıdaki komutlarla clusterımıza yükleyelim
vagrant ssh master
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
- Dağıtımın başarılı olup olmadığını kontrol edelim.(Kaynakların running olması biraz sürüyor)
kubectl -n longhorn-system get pod
kubectl get all -n longhorn-system
komutuyla bütün oluşan kaynaklara göz atabilirsiniz.- Şimdi, Longhorn'un arayüzüne tarayıcıdan ulaşmak için,
longhorn-frontend
isimli servisi dışarıdan erişime açmak için, ClusterIP olan servis tipini aşağıdaki komutla NodePort’a dönüştürüyoruz.
kubectl -n longhorn-system patch svc longhorn-frontend --type='json' -p '[{"op":"replace","path":"/spec/type","value":"NodePort"},{"op":"replace","path":"/spec/ports/0/nodePort","value":30005}]'
- Artık
<node-ip>:30005
portundan Longhorn arayüzüne resimdeki gibi girebilmemiz gerekiyor. kubectl get node -o wide
komutuyla nodeların IP’sini görebilirsiniz.
Longhorn Arayüz İncelemesi
- Arayüze baktığımızda şuan hiç volume ümüz yok ve 2 adet schedule edilebilir worker node umuz olduğunu görüyoruz.
- Node kısmından işyüklerini alacak nodelarımızı görebiliriz.
- Aşağıdaki gibi, düzenleme yapacağımız node u seçip, gelen ekrandan nodelarımıza tagler ekleyebilir veya depolama yolunun nereye mount edildiğine bakabiliriz.
- Node detaylarına girdiğimizde Path kısmının
/var/lib/longhorn
olduğunu görüyoruz. Buda bu node lardaki volume lerin buraya mount edileceği anlamına geliyor. - İsterseniz burada yeni bir disk ekleyebilir ve ona bir mountPath atayabilirsiniz.
- Longhorn arayüzünden, Volume kısmına geldiğimizde başlangıç olarak boş olduğunu görüyoruz. Biz bir
PersistentVolumeClaim
objesi oluşturduğumuzda bu PVC’ler Volume kısmında otomatik olarak gözükecek. İsterseniz arayüzden Volume>Create Volume kısmından da oluşturabiliriz ve buradan ihtiyaca göre volume hacmi, access mode, replica sayısı gibi detayları belirleyebiliriz.
- Backup kısmına geldiğimizde
back target URL is empty
diye bir uyarı mesajı görürüz ki bunun sebebi bir Backup yapılandırmamış olmamızdan kanaklanıyor. - Arayüzden Setting/General kısmına geldiğimizde Backup kısmından bu verilerimizi cluster dışına çıkarmak için bir AWS S3 endpointi veya bir NFS endpointi belirleyerek bu verileri yedekleyebilir ve yedekten geri döndürebiliriz.
Örnek-1: ReadWriteOnce(RWO) Kullanımı
- Bu örnekte, ReadWriteOnce(RWO) yöntemiyle bir PVC oluşturuyoruz. (RWO, bir PVC’nin yalnızca bir düğüme bağlı olduğunu belirtir, yani bir Pod’un bu PVC’yi sadece tek bir Node üzerinden okuyup yazabileceği anlamına gelir.) PVC oluşturup bir Pod’a bağlayarak değişiklikler yapıp snapshot ve backup alma işlemlerini gerçekleştireceğiz. Son olarak, farklı bir Node üzerinde başka bir Pod oluşturup bu verilere erişip erişemediğimizi kontrol edeceğiz.
- Şimdi longhorn-pvc.yaml adında bir dosya oluşturalım.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-vol
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi
kubectl apply -f longhorn-pvc.yaml
- PVC oluşturduktan sonra Longhorn arayüzünde Volume kısmından kontrol ettiğimizde oluştuğunu görüyoruz.
kubectl get pvc
- PVC oluşmuş ve “Bound” durumda ve kullanıma hazır. Bu genellikle Longhorn’un depolama taleplerini karşıladığı ve PVC’nin bir PV(Persistent Volume) ile bağlandığı anlamına gelir. Bu durumda, PVC’nin normal bir şekilde kullanılabilir olduğunu söyleyebiliriz.
- Eğer PVC’yi kullanmaya başlamak istiyorsak, bu PVC’yi bir Pod ile ilişkilendirebiliriz. Pod, bu PVC’ye yazdığında veya bu PVC’yi okuduğunda, Longhorn altında otomatik olarak oluşturulan PV’yi kullanacaktır.
kubectl get pv
dediğimizde pv nin longhorn tarafından otomatik olarak oluştuğunu ve bound edildiğini de görüyoruz.
Not: Longhorn volume PV/PVC oluşturulurken zaten mevcut olduğundan, Longhorn volume ünü dinamik olarak sağlamak için bir StorageClass gerekli değildir. Ancak, PVC bounding amacıyla kullanılmak üzere PVC/PV’de
StorageClassName
alanı ayarlanmalıdır. Ve kullanıcıların ilgili StorageClass nesnesini oluşturmasına gerek yoktur.
- Longhorn Dashboard’da 1 Detached volume ve 2 node umuz olduğunu görüyoruz.
- Şimdi bu volume ü kullanan pod-1.yaml adında bir pod oluşturalım ve içeriği aşağıdaki gibi yapalım.
apiVersion: v1
kind: Pod
metadata:
name: longhorn-pod-1
spec:
volumes:
- name: longhorn-storage
persistentVolumeClaim:
claimName: longhorn-vol
containers:
- name: longhorn-container-1
image: nginx
volumeMounts:
- mountPath: "/mnt/data"
name: longhorn-storage
kubectl apply -f pod-1.yaml
- Pod running olduktan sonra Longhorn arayüzünden Volume’ün healthy olması için Volume kısmından oluşan volume ü seçip replica sayısını node sayımız kadar yapıyoruz ve healthy olduğunu görüyoruz.
Replica sayısını node sayısı ile aynı yapmak, her node üzerinde bir replica oluşturulmasını sağlar ve bu da sağlıklı bir durumda PVC’nin kullanılabilir olduğu anlamına gelir.
Eğer node başarısızlıklarına karşı dayanıklılık sağlamak istiyorsanız, replica sayısını node sayısından daha büyük bir değere ayarlamak daha güvenli olabilir. Bu, Longhorn’un aynı veriyi farklı node’lar üzerinde çoğaltmasına ve node başarısızlıkları durumunda bile veri kaybını önlemesine yardımcı olabilir. Ancak, bu durumda daha fazla disk alanına ve kaynağa ihtiyaç duyulacaktır.
- Şimdi podumuza bağlanıp değişiklikler yapalım.
kubectl exec -it longhorn-pod-1 -- bash
cd /mnt/data
echo "Hello World!!" > deneme.txt
exit
- Bu aşamada snapshot ve backup kısmına geçmeden şu anki podum worker-1 de çalışıyor ve ben worker-2 de başka bir pod oluşturup, pod-1 ile mnt/data içerisine yazdığım veriyi görebilecekmiyim buna bakıcam.
# pod-2.yaml #
apiVersion: v1
kind: Pod
metadata:
name: longhorn-pod-2
spec:
volumes:
- name: longhorn-storage
persistentVolumeClaim:
claimName: longhorn-vol
containers:
- name: longhorn-container-2
image: nginx
volumeMounts:
- mountPath: "/mnt/data"
name: longhorn-storage
nodeName: k8s-worker-2
# kubectl apply -f pod-2.yaml
- pod-2 yi gözlemlediğim zaman running olmadığını ve detaylarına baktığımda volume’ün multi attach e izin vermediği için başlatılamadığını görüyorum.
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedAttachVolume 2m4s attachdetach-controller Multi-Attach error for volume "pvc-6e483777-729e-4130-8a47-0f33a67efae8" Volume is already used by pod(s) longhorn-pod-1
- Şimdi, bu pod-2.yaml dosyasını silelim ve nodeName kısmını
k8s-worker-1
yapıp tekrar pod-2 yi oluşturalım ve aynı node üzerinde verinin erişilebilir olduğunu görelim.
kubectl delete -f pod-2.yaml
vi pod-2.yaml # nodeName: k8s-worker-1 yapıp çıkalım
kubectl apply -f pod-2.yaml
kubectl exec -it longhorn-pod-2 -- bash
ls mnt/data/
- Evet gördüğümüz gibi
deneme.txt
dosyamıza aynı node üzerindeki poddan erişip gördük. Bunun sebebi, PVC’mizin ReadWriteOnce (RWO) olarak oluşturulması yani bu, volume ün yalnızca bir Node’a bağlı olabileceği ve bu Node’da replicalar oluşturabileceği anlamına gelir. - İkinci örneğimizde bu PVC’yi NFS tipi ile oluşturup farklı nodelardan erişmeyi göreceğiz.
- Bu işlemlerin ardından arayüzden Volume kısmına gidip oluşan volume e gidip şuanki durumdan bir snapshot alalım.
- Şuan bir snapshotımız var ve tekrar podlardan birine bağlanıp oluşturduğumuz
deneme.txt
dosyasını siliyoruz.
kubectl exec -it longhorn-pod-1 -- bash
cd /mnt/data
rm -rf deneme.txt
exit
- Bu aşamada dosyamız silindi ama snapshot aldığımız için yapmamız gereken önce podları delete etmek.
kubectl delete -f pod-1.yaml
kubectl delete -f pod-2.yaml
- Volume ün detach olduğunu görüyoruz ve aşağıdaki gibi worker-1 node a attach ediyoruz.
- Attach işleminden sonra volume e gidip, snapshottan Revert işlemi etkinleşecek ona tıklıyoruz ve gelen uyarıya “ok” diyoruz.
- Bu aşamada snapshot a geri döndük. Şimdi volume e tekrar gidip detach edicez. Detach dedikten sonra çıkan ekrandan Force detach ı seçip “ok” diyelim.
- Ardından podumuzu tekrar oluşturup poda bağlanıp
/mnt/data/
dizinindedeneme.txt
dosyamızın backup ile geri geldiğini görmüş oluyoruz.
kubectl apply -f pod-1.yaml
kubectl exec -it longhorn-pod-1 -- bash
ls /mnt/data/
deneme.txt lost+found # dosyamızın backuptan geri geldiğini görüyoruz
- Ayrıca Longhorn’un “recurring job schedule” (tekrarlayan görev zamanlaması), belirli bir görevin düzenli aralıklarla otomatik olarak çalıştırılmasını sağlayan bir mekanizmadır. Bu tür bir mekanizma, periyodik bakım görevleri, otomatik yedekleme işlemleri veya diğer düzenli görevleri planlamak için kullanılabilir.
- Örnek olarak her saatin 5.dakikasından itibaren her 3 dakikada bir düzenli snapshot alması için aşağıdaki gibi basit bir job oluşturuyorum.
- Belirli dakika aralığında snapshot ın otomatik olarak alındığını resimdeki gibi görüyoruz.
- Longhorn’un “recurring job schedule” özelliği, sistem yöneticilerine ve kullanıcılara depolama sistemini düzenli olarak bakım yapmak veya otomatik yedekleme işlemleri gibi önemli görevleri zaman içinde planlamak için bir yol sunar.
kubectl delete -f longhorn-pvc.yaml
kubectl delete -f pod-1.yaml
kubectl delete -f pod-2.yaml
Örnek-2: ReadWriteMany(RWX) Kullanımı
- Bu senaryoda, bir PVC’yi, ReadWriteMany(RWX) olarak oluşturucaz. Bir PVC’nin birden fazla Node üzerinden read ve write erişimine sahip olduğunu belirtir. Bu özellik, bir pod’un verilere aynı anda birden fazla node dan erişebileceği durumlar için uygundur.
- Burada RWX bir PVC kullanabilmek için öncelikle NFS Client’ını worker nodelarımıza aşağıdaki komutla kurmamız gerekiyor.
vagrant ssh worker-1
apt-get install nfs-common # Debian and Ubuntu için
+++++++++++++++++++++++++++++++++++++++++++++++++++
vagrant ssh worker-2
apt-get install nfs-common
longhorn
adından defaultStorageClass
mevcut olduğundan bunu kullanarak bu senaryo için bir PVC(PersistentVolumeClaim) oluşturacağız.
# longhorn-nfs.yaml #
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: 4Gi
kubectl apply -f longhorn-nfs.yaml
- Ardından rwx-deployment.yaml adında 3 replikadan oluşan deployment oluşturucaz.
# rwx-deployment.yaml #
apiVersion: apps/v1
kind: Deployment
metadata:
name: longhorn-rwx
labels:
app: rwx-test
spec:
replicas: 3
selector:
matchLabels:
app: rwx-test
template:
metadata:
labels:
app: rwx-test
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
name: http
volumeMounts:
- mountPath: /usr/share/nginx/html
name: rwx-test
restartPolicy: Always
volumes:
- name: rwx-test
persistentVolumeClaim:
claimName: longhorn-nfs
kubectl apply -f rwx-deployment.yaml
kubectl get po -o wide
- 2 worker-nodeda da konuşlanmış bir şekilde 3 replikalı dağıtımımız oluştu. Bu podlardan worker-1 de olanına bağlanıp
/usr/share/nginx/html
yolunda, içerisinde “Hello World!” yazandeneme.txt
adında bir dosya oluşturalım.
kubectl exec -it longhorn-rwx-f7b9d87d8-2zdmv -- bash
cd /usr/share/nginx/html/
echo "Hello World!" > deneme.txt
exit
- Şimdi, worker-2 deki diğer poda bağlanıp bu yolu kontrol edicez.
kubectl exec -it longhorn-rwx-f7b9d87d8-tl6r6 -- bash
cd /usr/share/nginx/html/
cat deneme.txt
root@longhorn-rwx-f7b9d87d8-tl6r6:/usr/share/nginx/html# cat deneme.txt
Hello World!
- Bu özellik sayesinde PVC, birden çok pod ve Node üzerinden aynı Volume’ü read ve write etme yeteneğine sahip oluyor. Longhorn arayüzünde Volume detaylarına baktığımızda, bu PVC’nin replikasyonu ile verilerin birden çok node üzerinde
replicaset
olarak dağıldığını görüyoruz. Bu durum, verilere erişimi güçlendirir ve arızalara karşı yedeklilik sağlar. Eğer bir node başarısız olursa, örneğimizdeki gibi diğer node’lar üzerindeki replikalar kullanılarak hizmet devam edebilir veya verilere erişilebilir.
- Hangi durumda ne kadar replikasyon yapılacağını dikkatlice planlamak önemlidir, çünkü aşırı replikasyon, depolama alanını ve kaynakları gereksiz yere kullanabilir.
- Bu adımları tamamladıktan sonra, sanal makineleri ve cluster’ı silmek için aşağıdaki komutu kullanabilirsiniz:
vagrant destroy -f
Kubernetes’te Dynamic Storage Provisioning ve Longhorn’un sunduğu avantajlara dair detayları paylaştığımız yazımızı tamamlıyoruz. Bu güçlü araç sayesinde depolama ihtiyaçlarınızı daha etkili bir şekilde karşılayabilir ve uygulamalarınızı güvenilir bir şekilde yönetebilirsiniz.
Eğer bu konudaki görüşleriniz veya ek sorularınız varsa, lütfen paylaşmaktan çekinmeyin. Teşekkür ederim!