Pemalam volum untuk storan Kubernetes: daripada Flexvolume kepada CSI

Pemalam volum untuk storan Kubernetes: daripada Flexvolume kepada CSI

Ketika Kubernetes masih v1.0.0, terdapat pemalam volum. Mereka diperlukan untuk menyambungkan sistem kepada Kubernetes untuk menyimpan data bekas yang berterusan (kekal). Bilangan mereka adalah kecil, dan antara yang pertama ialah pembekal storan seperti GCE PD, Ceph, AWS EBS dan lain-lain.

Pemalam telah dihantar bersama-sama dengan Kubernetes, itulah sebabnya mereka mendapat nama mereka - dalam pokok. Walau bagaimanapun, bagi kebanyakan orang, set pemalam yang sedia ada ternyata tidak mencukupi. Tukang menambah pemalam mudah pada teras Kubernetes menggunakan tampalan, selepas itu mereka memasang Kubernetes mereka sendiri dan memasangnya pada pelayan mereka. Tetapi dari masa ke masa, pemaju Kubernetes menyedarinya ikan masalah tidak dapat diselesaikan. Rakyat perlukan tong menangkap ikan. Dan dalam keluaran Kubernetes v1.2.0 ia muncul...

Pemalam Flexvolume: pancing minimum

Pembangun Kubernetes mencipta pemalam FlexVolume, yang merupakan rangka kerja logik pembolehubah dan kaedah untuk bekerja dengan pemacu Flexvolume yang dilaksanakan oleh pembangun pihak ketiga.

Mari kita berhenti dan lihat dengan lebih dekat apakah pemacu FlexVolume itu. Ini adalah sesuatu yang pasti fail boleh laku (fail binari, skrip Python, skrip Bash, dll.), yang, apabila dilaksanakan, mengambil argumen baris arahan sebagai input dan mengembalikan mesej dengan medan yang telah diketahui dalam format JSON. Mengikut konvensyen, argumen baris arahan pertama sentiasa kaedah, dan argumen yang selebihnya ialah parameternya.

Pemalam volum untuk storan Kubernetes: daripada Flexvolume kepada CSI
Gambar rajah sambungan untuk Saham CIFS dalam OpenShift. Pemacu Flexvolume - Betul-betul di Pusat

Set kaedah minimum kelihatan seperti ini:

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}
}

Menggunakan Kaedah attach ΠΈ detach akan menentukan senario di mana kubelet akan bertindak pada masa hadapan apabila memanggil pemandu. Terdapat juga kaedah khas expandvolume ΠΈ expandfs, yang bertanggungjawab untuk mengubah saiz volum secara dinamik.

Sebagai contoh perubahan yang ditambahkan oleh kaedah expandvolume, dan dengan itu keupayaan untuk mengubah saiz volum dalam masa nyata, anda boleh membiasakan diri dengannya permintaan tarik kami dalam Operator Rook Ceph.

Dan berikut ialah contoh pelaksanaan pemacu Flexvolume untuk bekerja dengan NFS:

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

Jadi, selepas menyediakan fail boleh laku sebenar, anda perlu muat naik pemacu ke gugusan Kubernetes. Pemacu mesti terletak pada setiap nod kluster mengikut laluan yang telah ditetapkan. Secara lalai ia telah dipilih:

/usr/libexec/kubernetes/kubelet-plugins/volume/exec/имя_поставщика_Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°~имя_Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€Π°/

... tetapi apabila menggunakan pengedaran Kubernetes yang berbeza (OpenShift, Rancher...) laluannya mungkin berbeza.

Masalah kelantangan fleksibel: bagaimana untuk melontar pancing dengan betul?

Memuat naik pemacu Flexvolume ke nod kelompok ternyata menjadi tugas yang tidak remeh. Setelah melakukan operasi secara manual sekali, adalah mudah untuk menghadapi situasi di mana nod baharu muncul dalam kluster: disebabkan penambahan nod baharu, penskalaan mendatar automatik, atau - apa yang lebih teruk - penggantian nod akibat kerosakan. Dalam kes ini, kerja dengan storan pada nod ini harus dilakukan mustahil, sehingga anda masih menambah pemacu Flexvolume secara manual padanya.

Penyelesaian kepada masalah ini adalah salah satu daripada primitif Kubernetes - DaemonSet. Apabila nod baharu muncul dalam kluster, ia secara automatik mengandungi pod daripada DaemonSet kami, yang mana volum tempatan dilampirkan di sepanjang laluan untuk mencari pemacu Flexvolume. Selepas penciptaan berjaya, pod menyalin fail yang diperlukan untuk pemandu berfungsi ke cakera.

Berikut ialah contoh DaemonSet untuk meletakkan pemalam Flexvolume:

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>

... dan contoh skrip Bash untuk meletakkan pemacu Flexvolume:

#!/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

Adalah penting untuk tidak lupa bahawa operasi salinan bukan atom. Terdapat kemungkinan besar kubelet akan mula menggunakan pemacu sebelum proses penyediaannya selesai, menyebabkan sistem ranap. Pendekatan yang betul ialah menyalin fail pemacu terlebih dahulu di bawah nama yang berbeza, dan kemudian menggunakan operasi nama semula atom.

Pemalam volum untuk storan Kubernetes: daripada Flexvolume kepada CSI
Gambar rajah bekerja dengan Ceph dalam operator Rook: pemacu Flexvolume dalam rajah terletak di dalam ejen Rook

Masalah seterusnya apabila menggunakan pemacu Flexvolume ialah untuk kebanyakan storan pada nod kluster perisian yang diperlukan untuk ini mesti dipasang (contohnya, pakej ceph-common untuk Ceph). Pada mulanya, pemalam Flexvolume tidak direka untuk melaksanakan sistem yang kompleks tersebut.

Penyelesaian asal kepada masalah ini boleh dilihat dalam pelaksanaan pemacu Flexvolume pengendali Rook:

Pemacu itu sendiri direka sebagai pelanggan RPC. Soket IPC untuk komunikasi terletak dalam direktori yang sama dengan pemandu itu sendiri. Kami ingat bahawa untuk menyalin fail pemacu adalah baik untuk menggunakan DaemonSet, yang menghubungkan direktori dengan pemacu sebagai volum. Selepas menyalin fail pemacu benteng yang diperlukan, pod ini tidak mati, tetapi bersambung ke soket IPC melalui volum yang dilampirkan sebagai pelayan RPC sepenuhnya. Pakej ceph-common sudah dipasang di dalam bekas pod. Soket IPC memastikan bahawa kubelet akan berkomunikasi dengan betul-betul pod yang terletak pada nod yang sama. Semua yang cerdik adalah mudah!..

Selamat tinggal, pemalam dalam pokok penyayang kami!

Pembangun Kubernetes mendapati bahawa bilangan pemalam untuk storan dalam teras ialah dua puluh. Dan perubahan dalam setiap daripada mereka, satu cara atau yang lain, melalui kitaran keluaran Kubernetes penuh.

Ternyata untuk menggunakan versi baharu pemalam storan, anda perlu mengemas kini keseluruhan kluster. Di samping itu, anda mungkin terkejut bahawa versi baharu Kubernetes tiba-tiba menjadi tidak serasi dengan kernel Linux yang anda gunakan... Jadi anda mengesat air mata anda dan, mengetap gigi anda, menyelaraskan masa dengan pihak pengurusan dan pengguna anda untuk kemas kini kernel Linux dan kelompok Kubernetes. Dengan kemungkinan masa henti dalam penyediaan perkhidmatan.

Situasi ini lebih daripada lucu, bukankah anda fikir? Ia menjadi jelas kepada seluruh komuniti bahawa pendekatan itu tidak berfungsi. Dengan keputusan yang disengajakan, pembangun Kubernetes mengumumkan bahawa pemalam baharu untuk bekerja dengan storan tidak akan diterima lagi ke dalam kernel. Di samping itu, seperti yang kita sedia maklum, beberapa kelemahan telah dikenal pasti dalam pelaksanaan pemalam Flexvolume...

Pemalam tambahan terbaharu untuk volum dalam Kubernetes, CSI, diminta untuk menutup isu dengan penyimpanan data yang berterusan sekali dan untuk semua. Versi alfanya, lebih dirujuk sepenuhnya sebagai Out-of-Tree CSI Volume Plugins, telah diumumkan dalam keluaran Kubernetes 1.9.

Antara Muka Penyimpanan Kontena, atau rod pemutar CSI 3000!

Pertama sekali, saya ingin ambil perhatian bahawa CSI bukan sahaja pemalam volum, tetapi nyata standard untuk mencipta komponen tersuai untuk bekerja dengan gudang data. Sistem orkestrasi kontena seperti Kubernetes dan Mesos sepatutnya "mempelajari" cara bekerja dengan komponen yang dilaksanakan mengikut piawaian ini. Dan kini saya telah pun mempelajari Kubernetes.

Apakah struktur pemalam CSI dalam Kubernetes? Pemalam CSI berfungsi dengan pemacu khas (pemacu CSI) yang ditulis oleh pembangun pihak ketiga. Pemacu CSI dalam Kubernetes mestilah terdiri daripada dua komponen (pod):

  • Pengawal β€” menguruskan storan berterusan luaran. Ia dilaksanakan sebagai pelayan gRPC, yang mana primitif digunakan StatefulSet.
  • nod β€” bertanggungjawab untuk memasang storan berterusan ke nod kelompok. Ia juga dilaksanakan sebagai pelayan gRPC, tetapi ia menggunakan primitif DaemonSet.

Pemalam volum untuk storan Kubernetes: daripada Flexvolume kepada CSI
Cara pemalam CSI berfungsi dalam Kubernetes

Anda boleh mengetahui tentang beberapa butiran lain tentang kerja CSI, contohnya, daripada artikel β€œMemahami C.S.I.' terjemahan yang mana kami terbitkan setahun yang lalu.

Kelebihan pelaksanaan sedemikian

  • Untuk perkara asas seperti mendaftarkan pemacu untuk nod, pembangun Kubernetes melaksanakan satu set bekas. Anda tidak perlu lagi menjana respons JSON dengan keupayaan sendiri, seperti yang dilakukan untuk pemalam Flexvolume.
  • Daripada "meluncur" fail boleh laku ke nod, kami kini memuat naik pod ke kluster. Inilah yang pada mulanya kami jangkakan daripada Kubernetes: semua proses berlaku di dalam bekas yang digunakan menggunakan primitif Kubernetes.
  • Anda tidak perlu lagi membangunkan pelayan RPC dan klien RPC untuk melaksanakan pemacu yang kompleks. Pelanggan telah dilaksanakan untuk kami oleh pembangun Kubernetes.
  • Meluluskan hujah untuk mengatasi protokol gRPC adalah lebih mudah, fleksibel dan boleh dipercayai daripada menghantarnya melalui hujah baris arahan. Untuk memahami cara menambah sokongan untuk metrik penggunaan volum pada CSI dengan menambahkan kaedah gRPC yang standard, anda boleh membaca: permintaan tarik kami untuk pemacu vsphere-csi.
  • Komunikasi berlaku melalui soket IPC, supaya tidak keliru sama ada kubelet menghantar permintaan ke pod yang betul.

Adakah senarai ini mengingatkan anda tentang apa-apa? Kelebihan CSI ialah menyelesaikan masalah yang sama, yang tidak diambil kira semasa membangunkan pemalam Flexvolume.

Penemuan

CSI sebagai piawaian untuk melaksanakan pemalam tersuai untuk berinteraksi dengan gudang data telah diterima dengan baik oleh komuniti. Lebih-lebih lagi, disebabkan kelebihan dan kepelbagaian mereka, pemacu CSI dicipta walaupun untuk sistem storan seperti Ceph atau AWS EBS, pemalam untuk berfungsi yang telah ditambahkan dalam versi pertama Kubernetes.

Pada awal tahun 2019, pemalam dalam pokok telah diisytiharkan usang. Kami merancang untuk terus menyokong pemalam Flexvolume, tetapi tidak akan membangunkan fungsi baharu untuknya.

Kami sendiri sudah mempunyai pengalaman menggunakan ceph-csi, vsphere-csi dan bersedia untuk menambah senarai ini! Setakat ini, CSI sedang menghadapi tugas yang diberikan kepadanya dengan hebat, tetapi kami akan tunggu dan lihat.

Jangan lupa bahawa semua yang baru adalah pemikiran semula yang baik tentang yang lama!

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen