如何透過 open-local 玩轉容器本地儲存? | 龍蜥技術
編者按:雲原生背景下,本地儲存相比分散式儲存,在易用性、可維護性、IO 效能上都更勝一籌,但使用本地儲存任然有諸多問題。那麼 open-local 會帶來什麼不一樣的體驗呢?來看看作者怎麼說。本文整理自 龍蜥大講堂第 30 期,精彩分享影片回放已上傳至龍蜥官網(首頁-動態-影片),歡迎檢視!
雲原生背景下,有狀態應用需要藉助一套儲存方案進行資料持久化儲存。本地儲存相比分散式儲存,在易用性、可維護性、IO 效能上都更勝一籌,但使用本地儲存作為目前低成本交付 Kubernetes 叢集,依然存在許多問題:
-
本地儲存管理能力有限:使用本地儲存需要一定的人力成本,如透過為節點打標來限制 Pod 排程、人工管理不同機型的磁碟、人工透過 Hostpath 方式掛載指定磁碟到容器等;同時還有一些現場交付問題,如繫結了錯誤的宿主機路徑使得故障無法及時發現,這些都嚴重影響了 K8s 交付效率以及應用執行時穩定性。
-
本地儲存空間隔離能力缺失:應用掛載不適當的宿主機目錄(如掛載到宿主機根路徑)導致宿主機故障,如因應用資料寫滿磁碟導致容器執行時無響應、觸發 Pod 驅逐等問題。
-
K8s 原生本地儲存能力有限。透過 Hostpath 無法做到節點保持,使得 Pod 漂移後應用資料丟失;而使用半自動靜態 Local PV 可保證節點保持,但是無法實現全自動,仍然需要為人為參與(如建立資料夾路徑,為節點打標等);無法使用一些高階儲存能力(例如快照)。
針對以上問題, open-local 應用而生,接下來一起來看看 open-local 都有哪些效能?
open-local 介紹
開源地址:
open-local 是阿里巴巴開源的一款本地儲存管理系統。透過 open-local,在 Kubernetes 上使用本地儲存就像使用集中式儲存一樣簡單。
目前 open-local 支援以下儲存特性:本地儲存池管理、儲存捲動態分配、儲存排程演算法擴充套件、儲存卷擴容、儲存卷快照、儲存卷監控、儲存卷 IO 限流、原生塊裝置及臨時卷。
1、use case
-
應用本身已支援多副本高可用,希望使用本地盤以提高儲存資源利用率,提高資料讀寫效能,如 HBase、MinIO 等。
-
應用期望資料卷具備容量隔離能力,避免出現諸如日誌打滿系統盤的情況。
-
應用需要大量本地儲存並依賴節點保持,如 etcd、zookeeper、Elasticsearch 等。
-
叢集本地磁碟數量眾多,希望透過排程器實現有狀態應用的自動化部署。
-
透過儲存快照能力為資料庫類應用備份瞬時資料等。
2、架構
┌─────────────────────────────────────────────────────────────────────────────┐ │ Master │ │ ┌───┬───┐ ┌────────────────┐ │ │ │Pod│PVC│ │ API-Server │ │ │ └───┴┬──┘ └────────────────┘ │ │ │ bound ▲ │ │ ▼ │ watch │ │ ┌────┐ ┌───────┴────────┐ │ │ │ PV │ │ Kube-Scheduler │ │ │ └────┘ ┌─┴────────────────┴─┐ │ │ ▲ │ open-local │ │ │ │ │ scheduler-extender │ │ │ │ ┌────►└────────────────────┘◄───┐ │ │ ┌──────────────────┐ │ │ ▲ │ │ │ │ NodeLocalStorage │ │create│ │ │ callback │ │ │ InitConfig │ ┌┴──────┴─────┐ ┌──────┴───────┐ ┌────┴────────┐ │ │ └──────────────────┘ │ External │ │ External │ │ External │ │ │ ▲ │ Provisioner │ │ Resizer │ │ Snapshotter │ │ │ │ watch ├─────────────┤ ├──────────────┤ ├─────────────┤ │ │ ┌─────┴──────┐ ├─────────────┴──┴──────────────┴──┴─────────────┤GRPC│ │ │ open-local │ │ open-local │ │ │ │ controller │ │ CSI ControllerServer │ │ │ └─────┬──────┘ └────────────────────────────────────────────────┘ │ │ │ create │ └──────────┼──────────────────────────────────────────────────────────────────┘ │ ┌──────────┼──────────────────────────────────────────────────────────────────┐ │ Worker │ │ │ │ │ │ ▼ ┌───────────┐ │ │ ┌──────────────────┐ │ Kubelet │ │ │ │ NodeLocalStorage │ └─────┬─────┘ │ │ └──────────────────┘ │ GRPC Shared Disks │ │ ▲ ▼ ┌───┐ ┌───┐ │ │ │ ┌────────────────┐ │sdb│ │sdc│ │ │ │ │ open-local │ create volume └───┘ └───┘ │ │ │ │ CSI NodeServer ├───────────────► VolumeGroup │ │ │ └────────────────┘ │ │ │ │ │ │ Exclusive Disks │ │ │ ┌─────────────┐ ┌───┐ │ │ │ update │ open-local │ init device │sdd│ │ │ └────────────────┤ agent ├────────────────► └───┘ │ │ └─────────────┘ Block Device │ │ │ └─────────────────────────────────────────────────────────────────────────────┘
2.1 open-local 包含四個元件:
1)scheduler-extender:作為 Kube-Scheduler 的擴充套件元件,透過 Extender 方式實現,新增本地儲存排程演算法。
2)CSI 外掛:按照 CSI(Container Storage Interface) 標準實現本地磁碟管理能力,包含建立/刪除/擴容儲存卷、建立/刪除快照、暴露儲存卷 metrics 等能力。
3)agent:執行在叢集中的每個節點,根據配置清單初始化儲存裝置,並透過上報叢集中本地儲存裝置資訊以供 Scheduler-Extender 決策排程。
4)controller:獲取叢集儲存初始化配置,並向執行在各個節點的 Agent 下發詳細的資源配置清單。
2.2 open-local 包含兩個 CRD
1)NodeLocalStorage:open-local 透過 NodeLocalStorage 資源上報每個節點上的儲存裝置資訊,該資源由 controller 建立,由每個節點的 agent 元件更新其 status。該 CRD 屬於全域性範圍的資源。2)NodeLocalStorageInitConfig:open-local controller 可透過 NodeLocalStorageInitConfig 資源建立每個 NodeLocalStorage 資源。NodeLocalStorageInitConfig 資源中包含全域性預設節點配置和特定節點配置,若節點的 node label 滿足表示式則使用特定節點配置,否則使用預設配置。
如何在 ack-distro 中使用 open-local
1、初始化配置
前置條件:環境中已經安裝 lvm 工具
ack-distro 部署時會預設安裝 open-local。編輯 NodeLocalStorageInitConfig 資源,進行儲存初始化配置。
# kubectl edit nlsc open-local
使用 open-local 要求環境中有 VG(VolumeGroup),若使用者環境中已存在 VG 且有剩餘空間,則可以配置在白名單;若環境中沒有 VG,使用者需提供一個塊裝置名稱供 open-local 建立 VG。
apiVersion: csi.aliyun.com/v1alpha1 kind: NodeLocalStorageInitConfig metadata: name: open-local spec: globalConfig: # 全域性預設節點配置,初始化建立 NodeLocalStorage 時會填充到其Spec中 listConfig: vgs: include: # VolumeGroup 白名單,支援正規表示式 - open-local-pool-[0-9]+ - your-vg-name # 若環境中已有 VG,可以寫入白名單由 open-local 納管 resourceToBeInited: vgs: - devices: - /dev/vdc # 若環境中沒有 VG,使用者需提供一個塊裝置 name: open-local-pool-0 # 將塊裝置 /dev/vdc 初始化為名叫 open-local-pool-0 的 VG
NodeLocalStorageInitConfig 資源編輯完畢後,controller 和 agent 會更新所有節點的 NodeLocalStorage 資源。
2、儲存捲動態供應
open-local 預設在叢集中部署了一些儲存類别範本,我們以 open-local-lvm、open-local-lvm-xfs 和 open-local-lvm-io-throttling 舉例:
# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE open-local-lvm local.csi.aliyun.com Delete WaitForFirstConsumer true 8d open-local-lvm-xfs local.csi.aliyun.com Delete WaitForFirstConsumer true 6h56m open-local-lvm-io-throttling local.csi.aliyun.com Delete WaitForFirstConsumer true
建立一個 Statefulset,該 Statefulset 使用 open-local-lvm 儲存類别範本。此時建立的儲存卷檔案系統為 ext4。若使用者指定 open-local-lvm-xfs 儲存模板,則儲存卷檔案系統為 xfs。
# kubectl apply -f
檢查 Pod/PVC/PV 狀態,可看到儲存卷建立成功:
# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-lvm-0 1/1 Running 0 3m5s # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE html-nginx-lvm-0 Bound local-52f1bab4-d39b-4cde-abad-6c5963b47761 5Gi RWO open-local-lvm 104s # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS AGE local-52f1bab4-d39b-4cde-abad-6c5963b47761 5Gi RWO Delete Bound default/html-nginx-lvm-0 open-local-lvm 2m4s kubectl describe pvc html-nginx-lvm-0
3、儲存卷擴容
編輯對應 PVC 的 spec.resources.requests.storage 欄位,將 PVC 宣告的儲存大小從 5Gi 擴容到 20 Gi。
# kubectl patch pvc html-nginx-lvm-0 -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
檢查 PVC/PV 狀態:
# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE html-nginx-lvm-0 Bound local-52f1bab4-d39b-4cde-abad-6c5963b47761 20Gi RWO open-local-lvm 7h4m # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE local-52f1bab4-d39b-4cde-abad-6c5963b47761 20Gi RWO Delete Bound default/html-nginx-lvm-0 open-local-lvm 7h4m
4、儲存卷快照
open-local 有如下快照類:
# kubectl get volumesnapshotclass NAME DRIVER DELETIONPOLICY AGE open-local-lvm local.csi.aliyun.com Delete 20m
建立 VolumeSnapshot 資源:
# kubectl apply -f volumesnapshot.snapshot.storage.k8s.io/new-snapshot-test created # kubectl get volumesnapshot NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE new-snapshot-test true html-nginx-lvm-0 1863 open-local-lvm snapcontent-815def28-8979-408e-86de-1e408033de65 19s 19s # kubectl get volumesnapshotcontent NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT AGE snapcontent-815def28-8979-408e-86de-1e408033de65 true 1863 Delete local.csi.aliyun.com open-local-lvm new-snapshot-test 48s
建立一個新 Pod,該 Pod 對應的儲存卷資料與之前快照點時刻的資料一致:
# kubectl apply -f service/nginx-lvm-snap created statefulset.apps/nginx-lvm-snap created # kubectl get po -l app=nginx-lvm-snap NAME READY STATUS RESTARTS AGE nginx-lvm-snap-0 1/1 Running 0 46s # kubectl get pvc -l app=nginx-lvm-snap NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE html-nginx-lvm-snap-0 Bound local-1c69455d-c50b-422d-a5c0-2eb5c7d0d21b 4Gi RWO open-local-lvm 2m11s
5、原生塊裝置
open-local 支援建立的儲存卷將以塊裝置形式掛載在容器中(本例中塊裝置在容器 /dev/sdd 路徑):
# kubectl apply -f
檢查 Pod/PVC/PV 狀態:
# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-lvm-block-0 1/1 Running 0 25s # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE html-nginx-lvm-block-0 Bound local-b048c19a-fe0b-455d-9f25-b23fdef03d8c 5Gi RWO open-local-lvm 36s # kubectl describe pvc html-nginx-lvm-block-0 Name: html-nginx-lvm-block-0 Namespace: default StorageClass: open-local-lvm ... Access Modes: RWO VolumeMode: Block # 以塊裝置形式掛載入容器 Mounted By: nginx-lvm-block-0 ...
6、IO 限流
open-local 支援為 PV 設定 IO 限流,支援 IO 限流的儲存類别範本如下:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: open-local-lvm-io-throttling provisioner: local.csi.aliyun.com parameters: csi.storage.k8s.io/fstype: ext4 volumeType: "LVM" bps: "1048576" # 讀寫吞吐量限制在 1024KiB/s 上下 iops: "1024" # IOPS 限制在 1024 上下 reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true
建立一個 Statefulset,該 Statefulset 使用 open-local-lvm-io-throttling 儲存類别範本。
# kubectl apply -f
Pod 處於 Running 狀態後,進入 Pod 容器中:
# kubectl exec -it test-io-throttling-0 sh
此時儲存卷是以原生塊裝置掛載在 /dev/sdd 上,執行 fio 命令:
# fio -name=test -filename=/dev/sdd -ioengine=psync -direct=1 -iodepth=1 -thread -bs=16k -rw=readwrite -numjobs=32 -size=1G -runtime=60 -time_based -group_reporting
結果如下所示,可見讀寫吞吐量限制在 1024KiB/s 上下:
...... Run status group 0 (all jobs): READ: bw=1024KiB/s (1049kB/s), 1024KiB/s-1024KiB/s (1049kB/s-1049kB/s), io=60.4MiB (63.3MB), run=60406-60406msec WRITE: bw=993KiB/s (1017kB/s), 993KiB/s-993KiB/s (1017kB/s-1017kB/s), io=58.6MiB (61.4MB), run=60406-60406msec Disk stats (read/write): dm-1: ios=3869/3749, merge=0/0, ticks=4848/17833, in_queue=22681, util=6.68%, aggrios=3112/3221, aggrmerge=774/631, aggrticks=3921/13598, aggrin_queue=17396, aggrutil=6.75% vdb: ios=3112/3221, merge=774/631, ticks=3921/13598, in_queue=17396, util=6.75%
7、臨時卷
open-local 支援為 Pod 建立臨時卷,其中臨時卷生命週期與 Pod 一致,即 Pod 刪除後臨時卷也隨之刪除。此處可理解為 open-local 版本的 emptydir。
# kubectl apply -f ./example/lvm/ephemeral.yaml
結果如下:
# kubectl describe po file-server Name: file-server Namespace: default ...... Containers: file-server: ...... Mounts: /srv from webroot (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-dns4c (ro) Volumes: webroot: # 此為 CSI 臨時卷 Type: CSI (a Container Storage Interface (CSI) volume source) Driver: local.csi.aliyun.com FSType: ReadOnly: false VolumeAttributes: size=2Gi vgName=open-local-pool-0 default-token-dns4c: Type: Secret (a volume populated by a Secret) SecretName: default-token-dns4c Optional: false
8、監控大盤
open-local 自帶了監控大盤,使用者可透過 Grafana 檢視叢集本地儲存資訊,包含儲存裝置和儲存卷資訊。
總而言之,藉助 open-local ,在運維方面可減少人力成本,提高叢集執行時的穩定性;功能方面,將本地儲存的優勢最大化,使使用者不僅能體驗到本地盤的高效能,同時各種高階儲存特性豐富了應用場景,讓廣大開發者體驗雲原生帶來的紅利,實現應用上雲尤其是有狀態應用雲原生部署關鍵一步。
關於影片回放和課件獲取
【影片回放】:影片回訪已上傳至龍蜥官網: 檢視。
【PPT課件獲取】:關注微信公眾號(OpenAnolis),回覆“龍蜥課件”即可獲取。有任何疑問請隨時諮詢龍蜥助手—小龍(微信:openanolis_assis)。
—— 完 ——
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70004278/viewspace-2909663/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 與容器服務 ACK 發行版的深度對話最終彈:如何透過 open-local 玩轉容器本地儲存
- 與容器服務 ACK 發行版的深度對話最終彈:如何通過 open-local 玩轉容器本地儲存
- 龍蜥社群高效能儲存技術 SIG 11 月運營回顧 | 龍蜥 SIG
- 探秘Kubernetes:在本地環境中玩轉容器技術
- 淺談mysql資料庫技術,輕鬆玩轉儲存過程MySql資料庫儲存過程
- 容器化RDS—— 計算儲存分離 or 本地儲存
- 儲存廠商旌存半導體加入龍蜥社群
- 技術門檻高?來看 Intel 機密計算技術在龍蜥社群的實踐 | 龍蜥技術Intel
- 每天5分鐘玩轉Docker容器技術(二)Docker
- 通過 Service 訪問 Pod - 每天5分鐘玩轉 Docker 容器技術(136)Docker
- 一文解讀機密容器的崛起和發展 | 龍蜥技術
- IoTDB透過MQTT儲存 windowsMQQTWindows
- iOS如何本地儲存PHAssetiOS
- Docker配置本地映象與容器的儲存位置Docker
- 縱存科技加入龍蜥社群,共建高效能儲存軟體棧
- 前端儲存技術前端
- 助力Koordinator雲原生單機混部,龍蜥混部技術提升CPU利用率達60%|龍蜥技術
- 如何用 Graylog 管理日誌? - 每天5分鐘玩轉 Docker 容器技術(93)Docker
- Kubernetes Dashboard - 每天5分鐘玩轉 Docker 容器技術(173)Docker
- 回收 PV - 每天5分鐘玩轉 Docker 容器技術(152)Docker
- Network Policy - 每天5分鐘玩轉 Docker 容器技術(171)Docker
- Prometheus Operator - 每天5分鐘玩轉 Docker 容器技術(177)PrometheusDocker
- PV & PVC - 每天5分鐘玩轉 Docker 容器技術(150)Docker
- 玩轉雲端 | 天翼雲物件儲存ZOS高可用的關鍵技術揭秘物件
- openGauss儲存技術(一)——行儲存引擎儲存引擎
- JAVA儲存過程(轉)Java儲存過程
- 從編譯到可執行,eBPF 加速容器網路的原理分析 | 龍蜥技術編譯eBPF
- eBPF 雙子座:天使 or 惡魔?| 龍蜥技術eBPF
- 龍蜥作業系統上玩轉銅鎖密碼庫作業系統密碼
- 龍蜥開源Plugsched:首次實現 Linux kernel 排程器熱升級 | 龍蜥技術Linux
- SSD 儲存領域廠商大普微加入龍蜥社群,完成與龍蜥作業系統適配作業系統
- 【Docker】(9)---每天5分鐘玩轉 Docker 容器技術之映象Docker
- 外部 Storage Provider - 每天5分鐘玩轉 Docker 容器技術(149)IDEDocker
- Liveness 探測 - 每天5分鐘玩轉 Docker 容器技術(143)Docker
- Helm 架構 - 每天5分鐘玩轉 Docker 容器技術(161)架構Docker
- 如何透過Hibernate/JPA在MySQL中儲存UTC時區?MySql
- 依然順滑!Dragonwell 11如何改造全新垃圾回收器ZGC? | 龍蜥技術GoGC
- 如何保證 Java 應用安全?標準答案來了 | 龍蜥技術Java