當 Kubernetes 還是 v1.0.0 時,就有捲插件了。 它們需要將系統連接到 Kubernetes 以儲存持久(永久)容器資料。 他們的數量很少,最早的儲存提供者包括 GCE PD、Ceph、AWS EBS 等。
這些插件與 Kubernetes 一起提供,這就是它們得名的原因 - in-tree。 然而,對於許多人來說,現有的此類插件集是不夠的。 工匠們使用補丁為 Kubernetes 核心添加簡單的插件,之後他們組裝了自己的 Kubernetes 並將其安裝在自己的伺服器上。 但隨著時間的推移,Kubernetes 開發人員意識到 魚 問題無法解決。 人們需要 釣魚竿。 在 Kubernetes v1.2.0 的發布中它出現了...
Flexvolume 外掛:最小釣竿
Kubernetes 開發人員創建了 FlexVolume 插件,它是一個變數和方法的邏輯框架,用於與第三方開發人員實現的 Flexvolume 驅動程式一起使用。
讓我們停下來仔細看看 FlexVolume 驅動程式是什麼。 這是一定的 執行檔 (二進位檔案、Python 腳本、Bash 腳本等),執行時將命令列參數作為輸入,並傳回一條包含 JSON 格式的預先已知欄位的訊息。 依照約定,第一個命令列參數總是方法,其餘參數是其參數。
OpenShift 中 CIFS 共享的連結圖。 Flexvolume 驅動程式 - 位於中心
最小方法集 看起來像這樣:
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}
}
使用方法 attach
и detach
將定義 kubelet 將來呼叫驅動程式時將採取的場景。 還有一些特殊的方法 expandvolume
и expandfs
,它們負責動態調整磁碟區的大小。
作為該方法添加的更改的範例 expandvolume
,並且能夠即時調整磁碟區大小,您可以熟悉
以下是使用 NFS 的 Flexvolume 驅動程式的實作範例:
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
因此,在準備好實際的可執行檔後,您需要 將驅動程式上傳到Kubernetes集群。 驅動程式必須按照預定的路徑位於每個叢集節點上。 預設已選擇:
/usr/libexec/kubernetes/kubelet-plugins/volume/exec/имя_поставщика_хранилища~имя_драйвера/
……但當使用不同的 Kubernetes 發行版(OpenShift、Rancher...)時,路徑可能會有所不同。
Flexvolume問題:如何正確拋竿?
事實證明,將 Flexvolume 驅動程式上傳到叢集節點並非易事。 手動完成一次操作後,很容易遇到叢集中出現新節點的情況:由於新增節點、自動水平擴展,或者更糟的是由於故障而更換節點。 在這種情況下,應該處理這些節點上的存儲 不可能,直到您仍然手動向其中新增 Flexvolume 驅動程式。
這個問題的解決方案是 Kubernetes 原語之一 - DaemonSet
。 當叢集中出現新節點時,它會自動包含來自 DaemonSet 的 pod,本地磁碟區沿著尋找 Flexvolume 驅動程式的路徑附加到該 pod。 成功建立後,pod 會將驅動程式工作所需的檔案複製到磁碟。
以下是用於佈置 Flexvolume 插件的 DaemonSet 的範例:
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>
...以及用於佈置 Flexvolume 驅動程式的 Bash 腳本範例:
#!/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
重要的是不要忘記複製操作 不是原子的。 kubelet 很有可能在其配置過程完成之前開始使用驅動程序,從而導致系統崩潰。 正確的方法是首先以不同的名稱複製驅動程式文件,然後使用原子重命名操作。
在 Rook Operator 中使用 Ceph 的示意圖:圖中的 Flexvolume 驅動程式位於 Rook 代理程式內部
使用 Flexvolume 驅動程式時的下一個問題是對於叢集節點上的大多數存儲 必須安裝必要的軟體 (例如,Ceph 的 ceph-common 包)。 最初,Flexvolume 插件並不是為了實現如此複雜的系統而設計的。
這個問題的原始解決方案可以在 Rook 操作符的 Flexvolume 驅動程式實作中看到:
驅動程式本身被設計為 RPC 客戶端。 用於通訊的IPC套接字與驅動程式本身位於同一目錄中。 我們記得,要複製驅動程式文件,最好使用 DaemonSet,它將目錄與驅動程式作為磁碟區連接起來。 複製必要的 rook 驅動程式檔案後,該 pod 不會消失,而是透過附加磁碟區作為成熟的 RPC 伺服器連接到 IPC 套接字。 ceph-common 軟體包已安裝在 pod 容器內。 IPC 套接字可確保 kubelet 將與位於相同節點上的 pod 進行準確通訊。 一切巧妙的事情都很簡單!...
再見,我們深情的...樹內插件!
Kubernetes 開發人員發現核心內用於儲存的插件數量為 XNUMX 個。 其中每一項的變更都會以某種方式貫穿整個 Kubernetes 發布週期。
事實證明,要使用新版本的儲存插件, 您需要更新整個集群。 除此之外,你可能會感到驚訝的是,新版本的Kubernetes 會突然與你正在使用的Linux 內核變得不相容......所以你擦乾眼淚,咬緊牙關,與你的管理層和使用者協調時間更新Linux核心和Kubernetes叢集。 提供服務可能會出現停機。
這種情況不只是滑稽,你不覺得嗎? 整個社區都清楚地意識到這種方法不起作用。 Kubernetes 開發人員故意宣布,核心將不再接受用於處理儲存的新插件。 此外,正如我們所知,在 Flexvolume 插件的實施過程中發現了一些缺陷...
Kubernetes 中最新加入的磁碟區插件 CSI 被要求一勞永逸地解決持久性資料儲存的問題。 它的 alpha 版本,更完整地稱為 Out-of-Tree CSI Volume Plugins,在發行版中宣布
容器儲存接口,或CSI 3000旋轉桿!
首先,我想指出CSI不僅僅是一個卷插件,而是一個真正的
Kubernetes 中的 CSI 插件的結構是怎麼樣的? CSI 插件與特殊驅動程式搭配使用(CSI 驅動程式)由第三方開發人員編寫。 Kubernetes 中的 CSI 驅動程式至少應包含兩個元件(pod):
- 調節器 — 管理外部持久性儲存。 它被實作為 gRPC 伺服器,並使用原語
StatefulSet
. - 節點 — 負責將持久性儲存安裝到叢集節點。 它也被實作為 gRPC 伺服器,但它使用原語
DaemonSet
.
CSI 插件如何在 Kubernetes 中運作
您可以了解 CSI 工作的其他一些細節,例如,從文章“
這種實施方式的優點
- 對於諸如為節點註冊驅動程式之類的基本操作,Kubernetes 開發人員實作了一組容器。 您不再需要像 Flexvolume 插件那樣自己產生帶有功能的 JSON 回應。
- 我們現在將 Pod 上傳到集群,而不是將可執行檔「滑動」到節點上。 這是我們最初對 Kubernetes 的期望:所有程序都發生在使用 Kubernetes 原語部署的容器內。
- 您不再需要開發 RPC 伺服器和 RPC 用戶端來實現複雜的驅動程式。 這個客戶端是由 Kubernetes 開發人員為我們實現的。
- 透過 gRPC 協定傳遞參數比透過命令列參數傳遞參數更加方便、靈活且可靠。 要了解如何透過新增標準化 gRPC 方法來為 CSI 添加對磁碟區使用指標的支持,您可以閱讀:
我們的拉取請求 對於 vsphere-csi 驅動程式。 - 通訊透過 IPC 套接字進行,以免混淆 kubelet 是否將請求傳送到正確的 pod。
這份清單讓你想起什麼了嗎? CSI的優點是 解決同樣的問題,開發 Flexvolume 插件時沒有考慮到這一點。
發現
CSI 作為實現與資料倉儲互動的自訂插件的標準受到了社群的熱烈歡迎。 此外,由於其優點和多功能性,甚至為 Ceph 或 AWS EBS 等儲存系統創建了 CSI 驅動程序,在 Kubernetes 的第一個版本中添加了用於使用這些系統的插件。
2019年初,樹內插件
我們自己已經擁有使用 ceph-csi、vsphere-csi 的經驗,並準備將其添加到此列表中! 到目前為止,CSI 正在出色地處理分配給它的任務,但我們將拭目以待。
不要忘記,一切新事物都是對舊事物的良好反思!
聚苯乙烯
另請閱讀我們的博客:
來源: www.habr.com