
Kubernetes Persistent Volume
Önceki makalede Kubernetes Volume kavramını ele almış ve volume’leri kabaca gruplamıştık. Bu makalede özellikle Kubernetes’e yeni başlayanlar tarafından kolaylıkla karıştırılabilecek önemli bir kavram olarak Persistent Volume (PV) ele alacağım. Kubernetes tasarımı pek çok kavramda gerçek hayattaki iş akışlarını modellemiştir. Persistent Volume kavramı da bunun örneklerinden birisidir. Dolayısıyla Persistent Volume’ü anlamak için öncelikle Kubernetes öncesi depolama alanı nasıl oluşturulur bilmekte fayda var.
IT ekipleri operasyonel olarak depolama alanlarını yönetirken 3 aşamadan geçmektedir;
- Depo alanının sağlanması
- Depo alanının ihtiyaçlar doğrultusunda yapılandırılması
- Depo alanın hedefe bağlanması
Operasyonel bakış açısıyla depolama alanı verilmesi süreci genelde fiziksel diskin bir sunucuya bağlanması ile başlamaktadır. Disk genellikle Storage Area Network (SAN) üyesi bir sunucuya bağlanır. SAN’a dahil olmasıyla birlikte disk artık bağlı olduğu sunucunun değil ağa bağlı sunucuların ortak malı haline gelmiş olur. Ağa bağlı sunucular bu depolama alanını ihtiyaçları kapsamında kullanabilirler. Öte yandan Disk’in SAN’a bağlı sunucuya takılması ile birlikte doğrudan kullanıma hazır hale gelmez. Örneğin, bu diske erişim için Local Unit Number (LUN) atanması gerekmektedir. Gerekli yapılandırmaların tamamlanması ardından depo alanı hedef sunucuya bağlanır ve uygulamaların kullanımına sunulur.
Bu kısa bilgilendirme ardında yukarıda saydığım 3 adımın Kubernetes’e yansımasını incelediğimizde karşımıza aşağıdaki tablo çıkacaktır;
Depo alanının Sağlanması | Persistent Volume |
Depo alanının yapılandırıması | Storage Class |
Depo alanının hedefe bağlanması | Persistent Volume Claim |
Kubernetes yöneticisi uygulamaların ihtiyaçları doğrultusunda kalıcı alan ihtiyaçlarını inceleyerek bir planlama yapar. Planlama neticesinde bir ya da birden fazla kaynak üzerinde hazırlanmış depolamanın sınıflandırması yapılarak depolama sağlayıcısı, dosya sistemi, block boyutu, alan boyutu v.b. bilgileri Storage Class (SC) yardımıyla bildirilir. Bu seviyede yer alan bilgi arkaplandaki kalıcı saklama alanı ile bu alana ait dosya sistemi, boyut ve depolama alanı özelindeki diğer gerekli detaylarını barındırmaktadır. Bu haliyle depolama alanı henüz Pod’ların kullanımına hazır değildir.
Geliştiriciler uygulamalarının gereksinimi göz önüne alarak kalıcı bir depolama alanı talebinde bulunurlar. Persistent Volume Claim (PVC) olarak yapılan bu talep gereksinim duyulan depolama boyutu ve depolama karakteristiklerini barındırmaktadır.
Dinamik atama kapsamında, Persistent Volume Claim’ler Kubernetes tarafından değerlendirilerek talebe uygun bir Persistent Volume aranarak atanmaya çalışılır. Uygun bir Persistent Volume bulunması durumunda talebe istinaden pod’a atanması yapılır. Uygun bir Persistent Volume bulunamaması durumunda sistem kaynakları incelenerek yeni bir Persistent Volume oluşturulmaya çalışılır. Statik atama kapsamında ise, Persistent Volume’ler Kubernetes yöneticilerince kontrol edilir, oluşturulur ve atanır. Kimi senaryolarda, talebe uygun bir Persistent Volume bulunamaz ya da oluşturulamaz. Bu durumda Kubernetes talebi yerine getirene kadar Pod’u ayağa kaldırmayacaktır. Bu sebeple sistem kaynak kullanımının yakından takip edilmesi önemlidir. Bu işleyişten de anlaşılacağı üzere Persistent Volume’leri sanal depolama alanları/volume olarak düşünebiliriz. Zaten Persistent Volume’ler aynı bir önceki makalede paylaştığım Volume’ler gibi bir Kubernetes Volume eklentisidirler.
Programcı bakış açısıyla konuya yaklaşırsak; Persistent Volume Claim’lerin Pod ile volume’ü birbirine bağlayan tutkal ya da eşleştirme tablosu olduğunu söyleyebiliriz. Persistent Volume Claim ile Persistent Volume bire bir bağlantıya sahiptir.
Toparlayacak olursak; Persistent Volume Claim’ler sadece bir kağıda yazdığımız dilekçedir, yerine getirecek biri olmadığı sürece rafta beklerler. Bu taleplerin gerçekleşmiş hali Persistent Volume’lerdir.
Persistent Volume Politikası
Bir Persistent Volume Claim (PVC) oluşturulurken bu talebe istinaden oluşturulacak Persistent Volume için de bir politika belirlenir. Persistent Volume yaşam döngüsünü de etkileyen bu politika aşağıdaki değerlere sahip olabilir;
- Retain: Talep silinse de oluşturulan Persistent Volume’un saklanması gerektiğini belirtir. Bu politikada Persistent Volume verisinin elle kurtarılabilecek şekilde saklanarak gelen yeni bir Persistent Volume Claim talebi ile bir Pod’a bağlanmaz. Elle temizleme işlemi ardından yeni taleplerde kullanılabilir.
- Recycle: Arkaplandaki volume eklentisinin desteklediği senaryolarda kullanılabilen bu politikada, talebin silinmesi ardından Persistent Volume içerisindeki veri otomatik olarak temizlenerek yeni kullanıma hazır hale getirilir. Bu politika güncel sürümlerde deprecated statusüne düşmüştür ve dinamik tanımlama kullanımı tavsiye edilmektedir.
- Delete: Talebin silinmesiyle birlikte Persistent Volume’ün de silineceğini belirtir.
Bu politikalardan da anlaşılacağı üzere Persistent Volume’ler pod’ların üzerinde ve pod’lardan farklı bir yaşam döngüsüne sahiptirler.
Veri Koruması
Persistent Volume Claim ve Persistent Volume tanımları olası bir veri kaybına karşı Kubernetes tarafından korunmaktadır. Aktif bir Pod’a bağlı olan Persistent Volume Claim tanımı silinmek istenirse, Pod kullanımı sonlanana kadar PVC tanımı silinmeyecektir. Benzer bir durum Persistent Volume için de geçerlidir. Bağlı bir PVC kaydı varsa bu kayıt silinene kadar Persistent Volume Kubernetes tarafından silinmeyecektir.
Alan Arttırımı
Depolama alanının desteklediği senaryolarda, Storage Class’ta verilecek allowVolumeExpansion parametresi sayesinde bu Storage Class ile oluşturulan Persistent Volume Claim’ler daha sonradan yeniden düzenlenerek daha geniş alan talep edilmesi mümkün olabilir. Talep Kubernetes tarafından incelenerek bağlı Persistent Volume genişletilmeye çalışılır.
Kubernetes Volume vs Persistent Volume
Şimdiye kadar paylaştıklarıma kısa bir es vererek bir konuya dikkatinizi çekmek istiyorum. Kubernetes Persistent Volume yaşam döngüsü Pod’dan tamamen bağımsız bir şekilde ilerlemektedir. Bu da verilerin Pod’lardan bağımsız olarak saklandığı, yani bağlandıkları Pod’ların yaşam döngülerinin sona ermesi ardından da kendi yaşam döngüleri doğrultusunda verilerini korumaya devam ettikleri anlamına gelmektedir. Bu önemli bir ayrıntıdır; çünkü Kubernetes Volume’leri ile Persistent Volume’leri birbirinden bu ayrıntı ayırmaktadır. En nihayetinde ortak eklentilerle aynı depolama yöntemlerini desteklemektedirler. Kubernetes Volume’lerinin yaşam döngüsü bağlı oldukları Pod yaşam döngüsüne bağlıdır. Bir Kubernetes Volume’u Pod ile birlikte söz konusudur. Pod’un döngüsünün sonlanması Kubernetes Volume’ün de döngüsünün sonlandığı anlamına gelmektedir.
Yukarıdaki bilgiler ışığında Kubernetes Volume ve Persistent Volume kavramlarını incelediğimizde Persistent Volume’ün Pod’lardan daha fazla ayrışmış, soyutlaştırılmış bir kavram olduğunu görebiliriz. Bunu biraz daha açarsak, Pod tanımı içerisinde bir saklama alanı için volume kullanılması durumunda tanım içerisinde saklama alanına dair detayları belirtmemiz gerekmektedir. Bunu bir önceki makalemde
yer alan örneklerde kolaylıkla görebilirsiniz. Bu durumda genel geçer bir dağıtıma sahip pod’lar oluşturmakta büyük bir engeldir. Geliştirici olarak gerekli depolama alanı bilgisine sahip olmam, tanımlamam, daha da önemlisi uygulamamın koştuğu Kubernetes kümesinde de bu tanıma sahip alanın olması gerekmektedir.
Kubernetes’in doğasının bir önceki paragrafta ifade etmeye çalıştığım bağımlılıkla tezat oluşturduğu düşünülürse Persistent Volume kavramının ortaya çıkması daha net anlaşılacaktır. Geliştirici olarak yapmam gereken çoğunlukla verinin ne şekilde, hangi dosya sistemi üzerinden saklanması gerektiğini belirtmekten çok hangi şartlarda saklanmasını istediğimi belirtmek olmalı. Uygulama en nihayetinde bu şartları sağlayan tüm ortamlarda çalışacaktır. Bu da Kubernetes yöneticilerinin arka planlandaki saklama alanı v.b. detaylara odaklanırken geliştiricilerin daha çok uygulama ve veriye odaklanmalarını sağlayacaktır. Sonuç olarak taşınabilir, her ortamda çalışabilir uygulamalar ortaya çıkacaktır.
Persistent Volume Tanımlama
Volume ile Persistent Volume arasındaki ayrımı ifade edebildiğimi umarak tekrar Persistent Volume özeline geri dönüyorum. Artık sıra geldi Kubernetes kümesinde kullanımını örneklemeye. Statik tanımlama ile ilerleyeceğimiz örneğimizde hostPath yardımıyla sunucu üzerindeki bir klasörü kullanacağız. Senaryoyu sade tutabilmek adına Kubernetes kümesinde tek bir worker node olduğunu varsayıyorum.
Öncelikle worker node üzerinde Persistent Volume hedefi olacak klasör oluşturulur;
sudo mkdir /mnt/data
Aşağıdaki komutla bu klasörde örnek bir index.html dosyası oluşturulur;
echo "Enterprisecoding'den merhaba" > /mnt/data/index.html
Aşağıdaki içeriğe sahip bir hostpath-pv.yml dosyası oluşturulur;
kind: PersistentVolume apiVersion: v1 metadata: name: ornek-volume labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data"
Bu dosya Persistent Volume tanımını barındırmaktadır. Statik tanımlama ile ilerlediğimiz için Persistent Volume üzerinde manual olarak StorageClass bilgileri de yer almaktadır (son iki satıra bakınız lütfen). Aşağıdaki komutla hazırladığımız tanımla bir Persistent Volume oluşturulur;
kubectl apply -f hostpath-pv.yml
Persistent Volume durumu aşağıdaki komutla kontrol edilebilir;
kubectl get pv ornek-volume
Aşağıdaki içerikle ornek-pvc.yml adında bir Persistent Volume Claim tanım dosyası oluşturulur;
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: ornek-volume-claim spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 3Gi
Aşağıdaki komutla hazırladığımız talep Kubernetes’e kayıt edilir;
kubectl apply -f ornek-pvc.yml
Bu işlem ardından Persistent Volume tekrar sorgulandığında talebimizin yerine getirildiği, Persistent Volume Claim ile Persistent Volume’ün birbirine bağlandığı görülecektir;
kubectl get pv ornek-volume

Benzer şekilde status değeri olarak Bound görülecektir.
Aşağıdaki komutla da Persistent Volume Claim sorgulanarak durumu teyit edilebilir;
kubectl get pvc ornek-volume-claim

Görüldüğü gibi PVC durumu da Bound ve bağlı volume olarak ornek-volume görülmekte.
Aşağıdaki içeriğe sahip ornek-pod.yml dosyası yardımıyla Persistent Volume Claim’i kullanabileceğimiz bir pod oluşturabiliriz;
kind: Pod apiVersion: v1 metadata: name: ornek-pod spec: volumes: - name: ornek-claim persistentVolumeClaim: claimName: ornek-volume-claim containers: - name: ornek-pv-container image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/usr/share/nginx/html" name: ornek-claim
Aşağıdaki komutla pod oluşturulur;
kubectl apply -f ornek-pod.yml
Pod’un başlaması ardından aşağıdaki komutla pod ip adresi öğrenilir;
kubectl get pod -o wide
Bu ip adresine yapılan taleple önceki adımlarda oluşturduğumuz ve Persistent Volume’de yer alan içeriğimizi görebiliriz;

Merhaba,
EBYS tarzı projelerde (birden fazla podun çalışacağı) dokümanlarımız veritabanında değilde dosya sisteminde tutmak istenirse tavsiyeniz ne olur? (NFS, glusterfs vb)
Merhaba Emre,
Bu sorunun tek bir cevabı bulunmuyor. Sistemin okuma yoğun, yazma yoğun olması, rastgele ya da ardıl erişim durumları, donanım durumları v.b. farklı kriterler açısından incelenmelidir. Yoğun I/O gerektiren sistemlerde erişimin network’e çıkartılması ciddi bir ağ trafiği oluşturabilecektir örneğin.
Alternatif senaryolar da ise hostpath üzerinden paylaşım değerlendirilebilir. Sanallaştırma dünyasında olgunluğa ulaşmış çözümleri burada kullanılarak daha iyi sonuçlar da alınabilir. Ortak paylaşılan disk’ler Kubernetes Cluster’ı sanal makinelerine bağlanarak hostpath ile devam edilebilir.