【編者的話】本次分享分爲三大部分。第一部分主要介紹Kubernetes中經常使用的幾種存儲,及其使用場景和生命週期等等。第二部分試圖介紹一些設計原則和基本架構,並簡要介紹各類存儲plugin的實現機制及持久卷的一些特性,例如訪問模式、回收策略等等。動態卷供給是一個Kubernetes獨有的功能,這一功能容許按需建立存儲卷,使管理員沒必要預先建立存儲卷,而是隨用戶需求進行建立。第三部分會介紹一下v1.9中存儲的一些新特性。html
在Kubernetes中部署和運行的服務大體分爲:git
Kubernetes使用ReplicaSet來保證一個服務的實例數量,若是說某個Pod實例因爲某種緣由掛掉或崩潰,ReplicaSet會馬上用這個Pod的模版新啓一個Pod來替代它。因爲是無狀態的服務,新Pod與舊Pod如出一轍。此外Kubernetes經過Service(一個Service後面能夠掛多個Pod)對外提供一個穩定的訪問接口,實現服務的高可用。github
和無狀態服務相比,它多了狀態保存的需求。Kubernetes提供了以Volume和Persistent Volume爲基礎的存儲系統,能夠實現服務的狀態保存。docker
和普通有狀態服務相比,它多了集羣管理的需求。要運行有狀態集羣服務要解決的問題有兩個,一個是狀態保存,另外一個是集羣管理。Kubernetes爲此開發了StatefulSet(之前叫作PetSet),方便有狀態集羣服務在Kubernetes上部署和管理。安全
簡單來講是經過Init Container來作集羣的初始化工做,用Headless Service來維持集羣成員的穩定關係,用動態存儲供給來方便集羣擴容,最後用StatefulSet來綜合管理整個集羣。架構
分析以上的服務類型,Kubernetes中對於存儲的使用主要集中在如下幾個方面:app
目前Kubernetes所支持的Volume Plugins以下表所示,less
Kubernetes已經提供很是豐富的Volume和Persistent Volume插件,你們能夠根據本身業務的須要,使用這些插件給容器提供存儲服務。每一種Plugin的使用方法和注意事項在此不作贅述,請參考 Kubernetes Volume 的官方文檔。ide
容器存儲接口(Container Storage Interface,CSI )是一項跨行業標準倡議,旨在下降雲原生存儲開發工做的門檻,從而進一步確保兼容性水平。Kubernetes v1.9已經引入了 CSI 的一套alpha實現版本,將新分卷插件的安裝流程簡化至與安裝pod至關,並容許第三方存儲供應商在無需接觸核心Kubernetes代碼庫的前提下開發本身的解決方案。post
若是上述的這些Plugin不知足業務要求, 你能夠經過如下兩種途徑進行二次開發,
feature-gate
中enable,不推薦在production環境中使用。v1.9已經把 CSI 做爲in-tree plugin,把out-off-tree volume插件的開發從 Kubernetes 中脫離出來,極大地方便了插件的開發、維護和集成。如何使用CSI,可參考How to Use Kubernetes 1.9.0 with CSI。Kubernete存儲在設計的時候遵循着Kubernetes的一向哲學,即聲明式(Declarative)架構。同時爲了儘量多地兼容各類存儲平臺,Kubernetes以in-tree plugin的形式來對接不一樣的存儲系統,知足用戶能夠根據本身業務的須要使用這些插件給容器提供存儲服務。同時兼容用戶使用FlexVolume和CSI定製化插件。相比較於Docker Volume,支持的存儲功能更加豐富和多樣。
Kubernetes中mount 一個PV的基本過程包括:
in-tree
或者out-of-tree
),建立PV,並在系統中與對應的PVC綁定;其實對於Kubernetes中大部分的Volume Plugin來講,mount的過程遵循着以下的規則:
/some/global/mount/path -> /var/lib/kubelet/pods/<pod uid> /volumes/<volume plugin>/<volume name>/ -> container volume
這種方式的好處至關於熱插拔,一旦Pod掛掉,kubelet能夠立刻重啓,並快速mount volume,不會出現相似於device busy的情形。
可是對於hostpath
這個Plugin而言,直接就是 /some/global/mount/path -> container volume
。
一個運行中的容器,缺省狀況下,對文件系統的寫入,都是發生在其分層文件系統的可寫層的(Copy-on-Write)。當遷移的應用程序從開發到生產環境時候,開發人員面臨着巨大的挑戰。當容器掛掉、崩潰或運行結束時,任何與之相關的數據都會丟失。爲了解決這個問題引起的數據丟失,咱們須要將數據存儲持久化,也能夠稱爲Persistent Volume。
Kubernetes使用兩種資源管理存儲:
Kubernetes中的Volume則是基於Docker進行擴展,使用Docker Volume掛載宿主機上的文件目錄到容器中。
通常來講,Kubernetes中Pod經過以下三種方式來訪問存儲資源。
該種方式移植性較差,可擴展能力差,把Volume的基本信息徹底暴露給用戶,有嚴重的安全隱患,同時須要協調不一樣users對Volume的訪問。
StorageClass將說明Volume將由哪一種Volume Plugin建立、建立時參數以及從其餘功能性/非功能性角度描述的後臺volume的各類參數。通常爲storage cluster的一些配置信息,以及label註釋信息。
通常來講,PV和PVC的生命週期分爲5個階段:
根據這5個階段,Volume的狀態有如下4種:
詳細的步驟請參考相關的 Proposal及其代碼實現。
簡單來講,這個Fianlizer相似於垃圾回收(GC)裏面的指針計數,當這個使用這個PVC的POD都被刪除(deleted)或處於完成狀態(completed)時,才能夠刪除這個PVC。從而避免了刪除正在運行中的container的PVC,從而引起數據丟失。