kubernetes雲原生紀元:共享存儲-PV&&PVC(上)
之前我們學習的都是無狀態的服務,如果有狀態的服務就非常麻煩,比如有的服務會把自己文件存放到自己服務器的目錄上,如果直接嵌入到docker 上那個這個目錄每次都會清空,沒有創建一個容器磁盤空間都是全新的,可能有人會說用目錄掛載,把目錄掛載到宿主機上,設置好節點的親和性就可以每次部署都部署到同一臺服務器上不就行了嗎?沒錯這樣是可以的,但是缺點比較大,首先你綁定了一臺機器,一旦這臺機器掛了,應用處於不可用狀態了,還有就是數據備份問題,但是上面的kubernetes都想到了,我們開始學習共享存儲。
概念
PV
PV
是persistentVolume的簡寫 ,persistentVolume是描述的是持久化數據卷。由管理員提供的網絡存儲的一部分。就像集羣中的節點一樣,PV也是集羣中的一種資源。它也像Volume一樣,是一種volume插件,但是它的生命週期卻是和使用它的Pod相互獨立的。PV這個API對象,捕獲了諸如NFS、ISCSI、或其他雲存儲系統的實現細節。
小例子
遠程共享存儲
storage: 10Gi
存儲容量10g,
accessModes: accessModes:
訪問模式是ReadWriteOnce 意思是隻有一個pod 使用這個pv,權限是讀寫,如果多個pod使用這個地方設置爲ReadWriteMany
訪問模式包括:
▷ ReadWriteOnce —— 該volume只能被單個節點以讀寫的方式映射
▷ ReadOnlyMany —— 該volume可以被多個節點以只讀方式映射
▷ ReadWriteMany —— 該volume只能被多個節點以讀寫的方式映射
nfs:
# kubernetes 提供的存儲方式,
nfs遠程目錄地址 path: "/tmp"
server: 172.22.1.2
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
capacity:
storage: 10Gi #存儲容量10g
accessModes: # 訪問模式是ReadWriteOnce 意思是隻有一個pod
- ReadWriteOnce
nfs: # kubernetes 提供的存儲方式,
path: "/tmp"
server: 172.22.1.2
PVC
PVC
是PersistentVolumeClaim的簡寫,PersistentVolumeClaim是描述的一個pod所希望使用的持久化存儲的需求,比如多少磁盤,內存大小,讀寫權限。
PVC必須和使用它的pod在同一個命名空間,集羣發現pod命名空間的PVC,根據PVC得到其後端的PV,然後PV被映射到host中,再提供給pod
下面定義的是一個具有讀寫權限的並且只能由我獨佔ReadWriteOnce
的一個有10g 空間大小的這樣一個存儲。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes: #
- ReadWriteOnce
resources:
requests:
storage: 10Gi
這是一個pod對共享存儲的需求和期望
PV && PVC 的綁定
PV和PVC都創建好了,這時候需要建立他們之間的綁定 ,PV要滿足PVC的要求:
權重大小,讀寫權限,
PV和PVC stroageclass 的name 必須一致
滿足這些PersistentVolumeConroller
會發現匹配的PV和PVC,自動建立綁定關係,本質上是在 PVC的描述對象裏把p V名字填進去
綁定好就可以直接使用了,通過volume
掛載persistentVolumeClaim
指定PVC的名字
apiVersion: v1
kind: Pod
metadata:
name: web-dev
spec:
containers:
- name: web-dev
image: web:v1
ports:
- containerPort: 8080
volumeMounts:
- name: nfs
mountPath: "/files"
volumes:
- name: nfs
persistentVolumeClaim: # 指定PVC的名字
claimName: nfs
具體原理:
Pod裏面聲明一個PVC的名字,PVC裏面描述了pod的需求權限,空間…並且PVC綁定了一個PV,PV描述具體存儲的後端服務的地址,如何訪問,都有哪些參數。
關於後端具體的存儲服務和PV 的配置一般由集羣管理員事先給我們配置好,剩下又kubernetes自己解決,包括運維定義的PVPVC建立綁定關係,把Pod 調度起來,把Pod 的volume 設置好 都是由kubernetes搞定的
設置volume首先是volume對應本地具體的目錄,對於共享存儲就不是一個目錄,每種不同的共享存儲服務,有不同處理過程,像nfs kubelt 會把這個目錄掛載遠程PV指定的位置,相當於執行mount命令,把主機的目錄掛載nfs server 上,之後對於docker 來說並沒有什麼區別,還是用 -v
參數把這個目錄映射到容器裏面,最終實現了這個共享存儲。
StorageClass
這個時候有很多POD需要共享存儲,每次建立一個就需要讓運維同學給我們配置一個PV,不用還得通知他得回收,這個代價太大了,kubernetes提供自動管理PV的機制叫做StorageClass。它的本質就是PV的模版。StorageClass自動創建PV
provisioner: kubernetes.io/aws-ebs
#kubernetes內置存儲插件的名字
parameters:
#具體創建PV用到的參數
type: io1
,zone: us-east-1d
,iopsPerDB: "10“
是aws-ebs創建PV所用到的。如果換成其他存儲插件,這些參數有所區別。每種插件都有自己所需要的參數。
例子
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: stroage-class-demo
provisioner: kubernetes.io/aws-ebs #kubernetes內置存儲插件的名字
parameters: #具體創建PV用到的參數
type: io1
zone: us-east-1d
iopsPerDB: "10“
有了StorageClass後PVC的配置
storageClassName:
指定StorageClass的名字,這樣我使用kubeContro 去創建PVC的時候 kub ernetes會根據這個名字 找我剛纔定義的StorageClass根據它自動創建一個大小10G的PV,然後建立起綁定關係。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo
spec:
accessModes:
- ReadWriteOnce
storageClassName: storage-class-demo
resources:
requests:
storage: 10Gi
StorageClass的設計要點
-
每個PV和PVC都有StorageClass
沒有設置就會有一個默認空的StorageClass,手動創建PV也是可以指定StorageClass,PVC中指定相同名字的StorageClass ,kubernetes會自動建立綁定關係,並不在意StorageClass不需要真實存在,只要名字一樣就可以。
-
StorageClass不需要真實存在
一張圖概括:
存儲插件:ceph…
PV :可以說集羣管理員創建的也可以是同storageClass自動創建的PV,
storageClass必定只能對應一種類型的後端存儲
對應關係:一個POD可以使用多個PVC,一個PVC也可以同時給多個POD提供服務,一個PVC只能綁定一個PV,一個PV只能對應一種後端存儲。
實踐
我們這裏用 GlusterFs
做存儲插件,使用GitHub gluster-kubernetes 這個項目,相關重要組件還有heketi
,
當然對我們基礎環境也有一定的要求: