我們在 Kubernetes 中為 Yandex.Cloud 開發 CSI 驅動程序的經驗

我們在 Kubernetes 中為 Yandex.Cloud 開發 CSI 驅動程序的經驗

我們很高興地宣布,Flant 正在擴大其對 Kubernetes 開源工具的貢獻,發布了 CSI 驅動程式的 alpha 版本 Yandex.Cloud(容器儲存介面)。

但在繼續討論實現細節之前,讓我們先回答為什麼在 Yandex 已經有服務的情況下還需要這樣做的問題 Kubernetes 託管服務.

介紹

為什麼是這樣?

在我們公司內部,從一開始在生產中使用 Kubernetes 開始(即現在已經好幾年了),我們一直在開發自己的工具(deckhouse),順便說一句,我們還計劃很快將其作為開源專案提供。 在它的幫助下,我們統一配置和配置我們所有的集群,目前已經有 100 多個集群,分佈在各種硬體配置和所有可用的雲端服務中。

使用 Deckhouse 的叢集擁有操作所需的所有組件:平衡器、使用方便的圖表、指標和警報進行監控、透過外部提供者進行使用者驗證以存取所有儀表板等等。 在託管解決方案中安裝這樣的「啟動」叢集是沒有意義的,因為這通常要么是不可能的,要么會導致需要停用一半的元件。

NB: 這是我們的經驗,而且很具體。 我們絕不建議每個人都應該自行部署 Kubernetes 集群,而不是使用現成的解決方案。 順便說一句,我們沒有從 Yandex 操作 Kubernetes 的實際經驗,因此在本文中我們不會對此服務進行任何評估。

它是什麼以及為誰而存在?

因此,我們已經討論了 Kubernetes 中的現代儲存方法: CSI 是如何運作的? и 社區是如何誕生的 到這種方法。

目前,許多大型雲端服務供應商都開發了將其雲端磁碟用作 Kubernetes 中的持久卷的驅動程式。 如果供應商沒有這樣的驅動程序,但所有必要的功能都是透過 API 提供的,那麼沒有什麼可以阻止您自己實作驅動程式。 Yandex.Cloud 就是這樣。

我們以 DigitalOcean 雲端的 CSI 驅動程式 和一些想法 GCP 驅動程式,因為與這些雲端(Google 和 Yandex)的 API 的交互作用有許多相似之處。 特別是,API 和 GCP,並在 Yandex的 回傳一個對象 Operation 追蹤長時間運行的操作的狀態(例如,建立新磁碟)。 若要與 Yandex.Cloud API 交互,請使用 Yandex.Cloud Go SDK.

所做工作的結果 發佈在 GitHub 上 對於那些出於某種原因在 Yandex.Cloud 虛擬機器(但不是現成的託管叢集)上使用自己的 Kubernetes 安裝並希望透過 CSI 使用(訂購)磁碟的人來說可能很有用。

履行

主要特點

目前該驅動支援以下功能:

  • 根據叢集中節點的拓撲對叢集所有Zone中的磁碟進行排序;
  • 取出先前訂購的光碟;
  • 離線調整磁碟大小 (Yandex.Cloud 不支持 增加安裝到虛擬機器的磁碟)。 有關如何修改驅動程式以盡可能輕鬆地調整大小的信息,請參閱下文。

未來,我們計劃實現對建立和刪除磁碟快照的支援。

主要困難及克服方法

Yandex.Cloud API 缺乏即時增加磁碟的能力是一個限制,使 PV(持久卷)的調整大小操作變得複雜:在這種情況下,需要停止使用該磁碟的應用程式 pod,這可能會導致應用程式停機。

根據 CSI規範,如果 CSI 控制器報告它只能「離線」調整磁碟大小(VolumeExpansion.OFFLINE),那麼增加磁碟的過程應該是這樣的:

如果插件只有 VolumeExpansion.OFFLINE 擴展能力和卷當前已在節點上發布或可用 ControllerExpandVolume 必須僅在以下任一之後呼叫:

  • 該插件有控制器 PUBLISH_UNPUBLISH_VOLUME 能力和 ControllerUnpublishVolume 已經調用成功。

要不然

  • 該插件沒有控制器 PUBLISH_UNPUBLISH_VOLUME 能力,插件有節點 STAGE_UNSTAGE_VOLUME 能力,以及 NodeUnstageVolume 已成功完成。

要不然

  • 該插件沒有控制器 PUBLISH_UNPUBLISH_VOLUME 能力,也不是節點 STAGE_UNSTAGE_VOLUME 能力,以及 NodeUnpublishVolume 已成功完成。

這本質上意味著您需要在擴展磁碟之前將磁碟與虛擬機器分開。

然而,不幸的是 實作 透過 sidecar 的 CSI 規範不符合以下要求:

  • 在邊車容器中 csi-attacher,這應該負責安裝之間存在所需的間隙,但在離線調整大小中根本沒有實現此功能。 對此發起了討論 這裡.
  • 在這種情況下,邊車容器到底是什麼? CSI 插件本身不會與 Kubernetes API 交互,而僅回應 sidecar 容器發送給它的 gRPC 呼叫。 最新的 正在開發中 由 Kubernetes 社群提供。

在我們的例子(CSI插件)中,增加磁碟的操作如下所示:

  1. 我們收到 gRPC 調用 ControllerExpandVolume;
  2. 我們嘗試在 API 中增加磁碟,但收到一條錯誤,提示由於磁碟已掛載而無法執行該操作;
  3. 我們將磁碟標識符儲存在map中,其中包含需要執行增加操作的磁碟。 下面,為了簡潔起見,我們將這張地圖稱為 volumeResizeRequired;
  4. 手動刪除正在使用該磁碟的 pod。 Kubernetes 將重新啟動它。 使磁碟沒有時間掛載(ControllerPublishVolume)在嘗試掛載時完成增加操作之前,我們檢查給定的磁碟是否仍在 volumeResizeRequired 並返回錯誤;
  5. CSI 驅動程式嘗試重新執行調整大小操作。 如果操作成功,則將磁碟從 volumeResizeRequired;
  6. 因為磁碟 ID 缺失 volumeResizeRequired, ControllerPublishVolume 透過成功,磁碟掛載,pod啟動。

一切看起來都很簡單,但一如既往地存在著陷阱。 擴大磁碟 外部縮放器,如果操作過程中出現錯誤 使用隊列 超時時間呈指數增長,最多 1000 秒:

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

這可能會定期導致磁碟擴充操作延長 15 分鐘以上,從而導致相應的 pod 不可用。

唯一可以輕鬆無痛地減少潛在停機時間的選擇是使用我們的具有最大超時限制的外部調整器版本 5 秒後:

workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)

我們認為沒有必要緊急發起討論並修補外部調整器,因為離線調整磁碟大小是一種回歸,很快就會從所有雲端供應商中消失。

如何開始使用它?

Kubernetes 版本 1.15 及更高版本支援此驅動程式。 駕駛員要工作,必須滿足以下要求:

  • --allow-privileged 設定為值 true 用於 API 伺服器和 kubelet;
  • 包括 --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true 用於 API 伺服器和 kubelet;
  • 安裝傳播(安裝傳播) 必須在叢集上啟用。 使用 Docker 時,必須將守護程式配置為允許共用掛載。

安裝本身的所有必要步驟 自述文件中描述。 安裝涉及從清單在 Kubernetes 中建立物件。

為了使驅動程式正常工作,您需要以下內容:

  • 在清單中指定目錄識別碼(folder-id) Yandex.Cloud (查看文件);
  • 為了與 Yandex.Cloud API 交互,CSI 驅動程式使用服務帳戶。 在清單中,必須傳遞 Secret 授權密鑰 來自服務帳戶。 在文件中 描述,如何建立服務帳戶並取得金鑰。

總而言之 - 嘗試,我們很高興收到回饋和 新問題如果您遇到任何問題!

進一步支持

因此,我們要指出的是,我們實現這個 CSI 驅動程式並不是出於想用 Go 編寫應用程式的樂趣,而是因為公司內部的迫切需求。 對我們來說,維護自己的實現似乎並不實際,因此,如果 Yandex 表現出興趣並決定繼續支持該驅動程序,我們將很樂意將存儲庫轉移給他們。

此外,Yandex 可能在其託管 Kubernetes 叢集中擁有自己的 CSI 驅動程式實現,該實現可以開源發布。 我們還認為這種開發選項是有利的 - 社區將能夠使用來自服務提供者的經過驗證的驅動程序,而不是來自第三方公司的驅動程式。

聚苯乙烯

另請閱讀我們的博客:

來源: www.habr.com

添加評論