Kubernetes Volumes

Kubernetes Volumes, detaylı düşünülmüş, oldukça beğendiğim Kubernetes kavramlarından biridir. Birden fazla makale ayırmayı planladığım bu konuya hızlıca bir giriş yapalım. Container disk’leri en basit tanımı ile “fani”dir. Herhangi bir sebepten dolayı pod’un yaşam döngüsü bitmesi ardından diskte bulunan her şey kaybolur. İşte bu noktada sahneye volume’ler çıkıyor. Kubernetes volume’leri için pod tarafından erişilebilen ve yeniden başlatmalarda verisini kaybetmeyen klasörler diyebiliriz. Kubernetes volumes tanımını biraz açtığımızda ise kabaca 5 gruba ayrıldığını görebiliriz;

  1. Yerel erişilebilir türler (örneğin; emtyDir, hostPath, local)
  2. Dosya paylaşım türleri (örneğin; nfs)
  3. Dağıtık dosya sistemi türleri (örneğin; cephfs, glusterfs)
  4. Bulut-sağlayıcı özelinde türler (örneğin; azureDisk, azureFile, awsElasticBlockStore, gcePersistentDisk)
  5. Amaca özel türler (örneğin; configMap, secret, gitRepo)

Docker kullananların alışık olduğu volume kavramı, Kubernetes’e gelince biraz değişmekte. Docker’da volume’ler yerel dizinler ve güncel sürümlerle birlikte kısıtlı bir fonksiyonalite ile yerel dislere izin verilmektedir. Öte yandan Kubernetes’de volume fonksiyonalite ve çeşitliliği arttığı gibi, birden fazla pod’un aynı volume’ü paylaşması da mümkün.

Yukarıdaki gruplamada da görebileceğiniz gibi configMap ya da secret gibi kavramlar akıllıca volume mantığı içerisinde gerçelleştirilmiş. Bu yaklaşımla ek fonksiyonaliteler basitce işletim sistemi desteği ile geliştiricilere sunulmuş durumda.

Bir volume’ü kullanabilmek için öncelikle .spec.volumes bölümü içerisinde hangi volume’lerin hangi yapılandırma ile sunulacağı belirtilir. Ardından .spec.containers.volumeMounts bölümünde hazırlanan bu volume’lerin container’da nereye bağlanacağı belirtilir. Bu noktadan itibaren Container içerisinden bir bakış açısı ile hepsi yerel dosya sistemindeki okunur ya da salt okunur durumdaki klasör ya da dosyalar haline gelmektedir. İşleyiş açısında Container içerisideki process’lerin farklı volume’lere erişim için ek bir işlem gerçekleştirme ihtiyacı bulunmuyor.

Aşağıdaki örnek pod tanımı içerisinde emptyDir yardımıyla nasıl bir volume oluşturularak pod’a bağlandığını görebilirsiniz;

kind: Pod
apiVersion: v1
metadata:
  name: volume-ornegi
spec:
  volumes:
    - name: ornek-volume
      emptyDir: {}

  containers:
    - name: app
      image: alpine
      volumeMounts:
        - name: ornek-volume
          mountPath: /volumeDizini
      command: ["/bin/sh"]
      args: ["-c", "while true; do date >> /volumeDizini/ornek.txt; sleep 5; done"]

Bu örnekte Pod içerisinde /data/test klasöründe oluşturulan ornek.txt dosyası pod’un yeniden başlatılması ardında kaybedilecektir. Buna bir alternatif olarak aşağıdaki örnekte olduğu gibi nfs volume kullanımı tercih edilebilir;

kind: Pod
apiVersion: v1
metadata:
  name: volume-ornegi
spec:
  volumes:
    - name: ornek-volume
      nfs:
        server: 192.168.200.2 
        path: /var/nfs_paylasimi/

  containers:
    - name: app
      image: alpine
      volumeMounts:
        - name: ornek-volume
          mountPath: /volumeDizini
      command: ["/bin/sh"]
      args: ["-c", "while true; do date >> /volumeDizini/ornek.txt; sleep 5; done"]

İki örnek karşılaştırdığında değişenin volume tanımlaması olduğu görülecektir. Bu haliyle ornek.txt dosyası pod yeniden başlatmaları ardında değişiklikleri korunacaktır.

Pod içerisindeki tüm container’lar aynı kernel namespace’lerini paylaşması nedeniyle aynı volume’lere ulaşabilmektedir. Dolayısıyla emptyDir örneğinden devam edecek olursak, aşağıdaki şekilde birden fazla container barındıran pod’larda aynı volume yazabilir;

kind: Pod
apiVersion: v1
metadata:
  name: volume-ornegi
spec:
  volumes:
    - name: ornek-volume
      emptyDir: {}

  containers:
    - name: app1
      image: alpine
      volumeMounts:
        - name: ornek-volume
          mountPath: /volumeDizini
      command: ["/bin/sh"]
      args: ["-c", "while true; do date >> /volumeDizini/ornek1.txt; sleep 5; done"]


    - name: app2
      image: alpine
      volumeMounts:
        - name: ornek-volume
          mountPath: /volumeDizini
      command: ["/bin/sh"]
      args: ["-c", "while true; do date >> /volumeDizini/ornek2.txt; sleep 5; done"]

Aşağıdaki komut yardımıtla oluşturulan dosyalar listelenebilir;

kubectl exec  volume-ornegi -c app1 -- ls /volumeDizini

ls-volumedizini

Fatih Boy

Ankara'da yaşayan Fatih, kendi şirketinde özellikle bankacılık, sigortacılık ve otomotiv sektörlerinde IT danışmanlıkları vermektedir. Devops, ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook

1 Yorum

  1. Pingback: Kubernetes Persistent Volume - Fatih'in Notları

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.