Kubernetes depolaması için birim eklentileri: Flexvolume'dan CSI'ya

Kubernetes depolaması için birim eklentileri: Flexvolume'dan CSI'ya

Kubernetes hâlâ v1.0.0 iken, birim eklentileri mevcuttu. Kalıcı (kalıcı) konteyner verilerini depolamak için sistemleri Kubernetes'e bağlamak için bunlara ihtiyaç vardı. Sayıları azdı ve ilk olanlar arasında GCE PD, Ceph, AWS EBS ve diğerleri gibi depolama sağlayıcıları vardı.

Eklentiler Kubernetes ile birlikte teslim edildi, bu yüzden ağaç içi adını aldılar. Ancak çoğu kişi için bu tür eklentilerden oluşan mevcut setin yetersiz olduğu ortaya çıktı. Zanaatkarlar, yamalar kullanarak Kubernetes çekirdeğine basit eklentiler ekledikten sonra kendi Kubernetes'lerini toplayıp sunucularına kurdular. Ancak zamanla Kubernetes geliştiricileri şunu fark etti: balık sorun çözülemez. İnsanların ihtiyacı olta. Ve Kubernetes v1.2.0 sürümünde ortaya çıktı...

Flexvolume eklentisi: minimal olta

Kubernetes geliştiricileri, üçüncü taraf geliştiriciler tarafından uygulanan Flexvolume sürücüleriyle çalışmaya yönelik değişkenlerin ve yöntemlerin mantıksal bir çerçevesi olan FlexVolume eklentisini oluşturdu.

Şimdi biraz duralım ve FlexVolume sürücüsünün ne olduğuna daha yakından bakalım. Bu kesin bir çalıştırılabilir dosya (ikili dosya, Python betiği, Bash betiği vb.), yürütüldüğünde komut satırı argümanlarını girdi olarak alır ve önceden bilinen alanları içeren bir mesajı JSON formatında döndürür. Geleneksel olarak, ilk komut satırı argümanı her zaman bir yöntemdir ve geri kalan argümanlar onun parametreleridir.

Kubernetes depolaması için birim eklentileri: Flexvolume'dan CSI'ya
OpenShift'teki CIFS Paylaşımları için bağlantı şeması. Flexvolume Sürücüsü - Tam Merkezde

Minimum yöntem seti Bu şuna benzer:

flexvolume_driver mount # отвечает за присоединение тома к pod'у
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
}

flexvolume_driver unmount # отвечает за отсоединение тома от pod'а
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
}

flexvolume_driver init # отвечает за инициализацию плагина
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
  // Определяет, использует ли драйвер методы attach/deatach
  "capabilities":{"attach": True/False}
}

Yöntemleri Kullanmak attach и detach sürücüyü çağırırken kubelet'in gelecekte hareket edeceği senaryoyu tanımlayacaktır. Özel yöntemler de var expandvolume и expandfs, birimin dinamik olarak yeniden boyutlandırılmasından sorumludurlar.

Yöntemin eklediği değişikliklere bir örnek olarak expandvolumeve hacimleri gerçek zamanlı olarak yeniden boyutlandırma yeteneği sayesinde, çekme isteğimiz Rook Ceph Operatöründe.

Ve işte Flexvolume sürücüsünün NFS ile çalışmak için uygulanmasına bir örnek:

usage() {
    err "Invalid usage. Usage: "
    err "t$0 init"
    err "t$0 mount <mount dir> <json params>"
    err "t$0 unmount <mount dir>"
    exit 1
}

err() {
    echo -ne $* 1>&2
}

log() {
    echo -ne $* >&1
}

ismounted() {
    MOUNT=`findmnt -n ${MNTPATH} 2>/dev/null | cut -d' ' -f1`
    if [ "${MOUNT}" == "${MNTPATH}" ]; then
        echo "1"
    else
        echo "0"
    fi
}

domount() {
    MNTPATH=$1

    NFS_SERVER=$(echo $2 | jq -r '.server')
    SHARE=$(echo $2 | jq -r '.share')

    if [ $(ismounted) -eq 1 ] ; then
        log '{"status": "Success"}'
        exit 0
    fi

    mkdir -p ${MNTPATH} &> /dev/null

    mount -t nfs ${NFS_SERVER}:/${SHARE} ${MNTPATH} &> /dev/null
    if [ $? -ne 0 ]; then
        err "{ "status": "Failure", "message": "Failed to mount ${NFS_SERVER}:${SHARE} at ${MNTPATH}"}"
        exit 1
    fi
    log '{"status": "Success"}'
    exit 0
}

unmount() {
    MNTPATH=$1
    if [ $(ismounted) -eq 0 ] ; then
        log '{"status": "Success"}'
        exit 0
    fi

    umount ${MNTPATH} &> /dev/null
    if [ $? -ne 0 ]; then
        err "{ "status": "Failed", "message": "Failed to unmount volume at ${MNTPATH}"}"
        exit 1
    fi

    log '{"status": "Success"}'
    exit 0
}

op=$1

if [ "$op" = "init" ]; then
    log '{"status": "Success", "capabilities": {"attach": false}}'
    exit 0
fi

if [ $# -lt 2 ]; then
    usage
fi

shift

case "$op" in
    mount)
        domount $*
        ;;
    unmount)
        unmount $*
        ;;
    *)
        log '{"status": "Not supported"}'
        exit 0
esac

exit 1

Yani, gerçek yürütülebilir dosyayı hazırladıktan sonra şunları yapmanız gerekir: sürücüyü Kubernetes kümesine yükleyin. Sürücünün her küme düğümünde önceden belirlenmiş bir yola göre konumlandırılması gerekir. Varsayılan olarak seçiliydi:

/usr/libexec/kubernetes/kubelet-plugins/volume/exec/имя_поставщика_хранилища~имя_драйвера/

... ancak farklı Kubernetes dağıtımları (OpenShift, Rancher...) kullanıldığında yol farklı olabilir.

Flexvolume sorunları: olta nasıl doğru şekilde atılır?

Flexvolume sürücüsünü küme düğümlerine yüklemenin önemsiz olmayan bir görev olduğu ortaya çıktı. İşlemi manuel olarak bir kez yaptıktan sonra, kümede yeni düğümlerin ortaya çıktığı bir durumla karşılaşmak kolaydır: yeni bir düğümün eklenmesi, otomatik yatay ölçeklendirme veya daha kötüsü bir arıza nedeniyle bir düğümün değiştirilmesi nedeniyle. Bu durumda, bu düğümlerdeki depolama ile çalışma yapılmalıdır. imkânsızFlexvolume sürücüsünü bunlara manuel olarak ekleyene kadar.

Bu sorunun çözümü Kubernetes'in ilkellerinden biriydi. DaemonSet. Kümede yeni bir düğüm göründüğünde, otomatik olarak DaemonSet'ten Flexvolume sürücülerini bulma yolu boyunca yerel bir birimin eklendiği bir bölmeyi içerir. Başarılı bir şekilde oluşturulduktan sonra bölme, sürücünün çalışması için gerekli dosyaları diske kopyalar.

Flexvolume eklentisini düzenlemek için böyle bir DaemonSet örneği:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: flex-set
spec:
  template:
    metadata:
      name: flex-deploy
      labels:
        app: flex-deploy
    spec:
      containers:
        - image: <deployment_image>
          name: flex-deploy
          securityContext:
              privileged: true
          volumeMounts:
            - mountPath: /flexmnt
              name: flexvolume-mount
      volumes:
        - name: flexvolume-mount
          hostPath:
            path: <host_driver_directory>

... ve Flexvolume sürücüsünü düzenlemek için bir Bash betiği örneği:

#!/bin/sh

set -o errexit
set -o pipefail

VENDOR=k8s.io
DRIVER=nfs

driver_dir=$VENDOR${VENDOR:+"~"}${DRIVER}
if [ ! -d "/flexmnt/$driver_dir" ]; then
  mkdir "/flexmnt/$driver_dir"
fi

cp "/$DRIVER" "/flexmnt/$driver_dir/.$DRIVER"
mv -f "/flexmnt/$driver_dir/.$DRIVER" "/flexmnt/$driver_dir/$DRIVER"

while : ; do
  sleep 3600
done

Kopyalama işleminin unutulmaması önemlidir. atomik değil. Kubelet'in, sağlama işlemi tamamlanmadan sürücüyü kullanmaya başlaması ve sistemin çökmesine neden olması ihtimali yüksektir. Doğru yaklaşım, önce sürücü dosyalarını farklı bir adla kopyalamak, ardından atomik yeniden adlandırma işlemini kullanmaktır.

Kubernetes depolaması için birim eklentileri: Flexvolume'dan CSI'ya
Rook operatöründe Ceph ile çalışma şeması: Diyagramdaki Flexvolume sürücüsü Rook aracısının içinde bulunur

Flexvolume sürücülerini kullanırken bir sonraki sorun, bir küme düğümündeki depolamanın çoğu için olan sorundur. bunun için gerekli yazılımın yüklenmesi gerekir (örneğin, Ceph için ceph-ortak paketi). Başlangıçta Flexvolume eklentisi bu tür karmaşık sistemleri uygulamak için tasarlanmamıştı.

Bu soruna orijinal bir çözüm, Rook operatörünün Flexvolume sürücü uygulamasında görülebilir:

Sürücünün kendisi bir RPC istemcisi olarak tasarlanmıştır. İletişim için IPC soketi sürücünün kendisi ile aynı dizinde bulunur. Sürücü dosyalarını kopyalamak için dizini sürücüye birim olarak bağlayan DaemonSet'i kullanmanın iyi olacağını hatırlıyoruz. Gerekli kale sürücüsü dosyalarını kopyaladıktan sonra bu bölme ölmez, ancak ekli birim aracılığıyla IPC soketine tam teşekküllü bir RPC sunucusu olarak bağlanır. Ceph-common paketi zaten kapsül kabının içine kuruludur. IPC soketi, kubelet'in kendisiyle aynı düğümde bulunan pod ile tam olarak iletişim kurmasını sağlar. Ustaca olan her şey basittir!..

Hoşçakal, sevimli... ağaç içi eklentilerimiz!

Kubernetes geliştiricileri, çekirdekteki depolamaya yönelik eklenti sayısının yirmi olduğunu keşfetti. Ve her birindeki değişiklik, öyle ya da böyle, Kubernetes'in yayın döngüsünün tamamından geçer.

Depolama eklentisinin yeni sürümünü kullanmak için, kümenin tamamını güncellemeniz gerekiyor. Buna ek olarak, Kubernetes'in yeni sürümünün bir anda kullandığınız Linux çekirdeğiyle uyumsuz hale gelmesine şaşırabilirsiniz... Böylece gözyaşlarınızı siler ve dişlerinizi gıcırdatarak yönetiminiz ve kullanıcılarınızla koordinasyonu sağlarsınız. Linux çekirdeğini ve Kubernetes kümesini güncelleyin. Hizmetlerin sağlanmasında olası kesintiler ile.

Durum sizce de komik değil mi? Yaklaşımın işe yaramadığı tüm topluluk tarafından açıkça görüldü. Kubernetes geliştiricileri kasıtlı bir kararla, depolamayla çalışmaya yönelik yeni eklentilerin artık çekirdeğe kabul edilmeyeceğini duyurdu. Ayrıca zaten bildiğimiz gibi Flexvolume eklentisinin uygulanmasında bir takım eksiklikler tespit edildi...

Kubernetes'e birimler için eklenen en son eklenti olan CSI, kalıcı veri depolama sorununu kesin olarak kapatmak için çağrıldı. Daha kapsamlı olarak Ağaç Dışı CSI Cilt Eklentileri olarak anılan alfa sürümü, sürümde duyuruldu. Kubernet'ler 1.9.

Konteyner Depolama Arayüzü veya CSI 3000 eğirme çubuğu!

Öncelikle şunu belirtmek isterim ki CSI sadece bir hacim eklentisi değil, gerçek bir eklentidir. standart veri ambarlarıyla çalışmak için özel bileşenler oluşturma hakkında. Kubernetes ve Mesos gibi konteyner düzenleme sistemlerinin, bu standarda göre uygulanan bileşenlerle nasıl çalışılacağını "öğrenmesi" gerekiyordu. Ve şimdi zaten Kubernetes'i öğrendim.

Kubernetes'teki CSI eklentisinin yapısı nedir? CSI eklentisi özel sürücülerle çalışır (CSI sürücüleri) üçüncü taraf geliştiriciler tarafından yazılmıştır. Kubernetes'teki bir CSI sürücüsü en az iki bileşenden (bölmeler) oluşmalıdır:

  • kontrolör — harici kalıcı depolamaları yönetir. İlkelin kullanıldığı bir gRPC sunucusu olarak uygulanır. StatefulSet.
  • Düğüm — kalıcı depolamanın küme düğümlerine bağlanmasından sorumludur. Aynı zamanda bir gRPC sunucusu olarak da uygulanır, ancak bunun için bir ilkel kullanılır DaemonSet.

Kubernetes depolaması için birim eklentileri: Flexvolume'dan CSI'ya
Kubernetes'te CSI eklentisi nasıl çalışır?

CSI'nin çalışmalarının diğer bazı ayrıntılarını örneğin "" makalesinden öğrenebilirsiniz.C.S.I.'ı Anlamak' hangisinin çevirisi bir yıl önce yayınlamıştık.

Böyle bir uygulamanın avantajları

  • Bir düğüm için sürücü kaydetme gibi temel şeyler için Kubernetes geliştiricileri bir dizi kapsayıcı uyguladı. Artık Flexvolume eklentisinde yapıldığı gibi, yeteneklere sahip bir JSON yanıtı oluşturmanıza gerek yok.
  • Yürütülebilir dosyaları düğümlere "kaydırmak" yerine artık kümeye bölmeler yüklüyoruz. Başlangıçta Kubernetes'ten beklediğimiz şey budur: tüm işlemler Kubernetes temel öğeleri kullanılarak konuşlandırılan konteynerlerin içinde gerçekleşir.
  • Karmaşık sürücüleri uygulamak için artık bir RPC sunucusu ve RPC istemcisi geliştirmenize gerek yok. İstemci bizim için Kubernetes geliştiricileri tarafından uygulandı.
  • Bağımsız değişkenleri gRPC protokolü üzerinden çalışmak üzere iletmek, bunları komut satırı bağımsız değişkenleri aracılığıyla iletmekten çok daha kullanışlı, esnek ve güvenilirdir. Standartlaştırılmış bir gRPC yöntemi ekleyerek CSI'ya hacim kullanımı ölçümlerine yönelik desteğin nasıl ekleneceğini anlamak için şunları okuyabilirsiniz: çekme isteğimiz vsphere-csi sürücüsü için.
  • Kubelet'in isteği doğru bölmeye gönderip göndermediği konusunda kafa karışıklığı yaratmamak için iletişim IPC soketleri aracılığıyla gerçekleşir.

Bu liste size bir şey hatırlatıyor mu? CSI'nin avantajları şunlardır: aynı sorunları çözmekFlexvolume eklentisi geliştirilirken bunlar dikkate alınmadı.

Bulgular

Veri ambarlarıyla etkileşime yönelik özel eklentilerin uygulanmasına yönelik bir standart olarak CSI, topluluk tarafından çok sıcak karşılandı. Üstelik avantajları ve çok yönlülüğü nedeniyle CSI sürücüleri, Kubernetes'in ilk sürümüne eklenen eklentiler olan Ceph veya AWS EBS gibi depolama sistemleri için bile oluşturulmuştur.

2019'un başında ağaç içi eklentiler geçerliliğini yitirdiği ilan edildi. Flexvolume eklentisini desteklemeye devam etmeyi planlıyoruz ancak bunun için yeni işlevler geliştirmeyeceğiz.

Biz zaten ceph-csi, vsphere-csi kullanma deneyimine sahibiz ve bu listeye eklemeye hazırız! Şu ana kadar CSI kendisine verilen görevlerle büyük bir başarıyla başa çıkıyor, ancak bekleyip göreceğiz.

Yeni olan her şeyin eskinin güzel bir yeniden düşünülmesi olduğunu unutmayın!

PS

Blogumuzda da okuyun:

Kaynak: habr.com

Yorum ekle