概述
存儲管理與計算管理是兩個不同的問題。Persistent Volume 子系統,對存儲的供應和使用做了抽象,以 API 形式提供給管理員和用戶使用。要完成這一任務,我們引入了兩個新的 API 資源:Persistent Volume(持久卷) 和 Persistent Volume Claim(持久卷消費者)。
Persistent Volume(PV)是集羣之中的一塊網絡存儲。跟 Node 一樣,也是集羣的資源。PV 跟 Volume (卷) 類似,不過會有獨立於 Pod 的生命週期。這一 API 對象包含了存儲的實現細節,例如 NFS、iSCSI 或者其他的雲提供商的存儲系統。Persistent Volume Claim (PVC) 是用戶的一個請求。跟 Pod 類似,Pod 消費 Node 的資源,PVC 消費 PV 的資源。Pod 能夠申請特定的資源(CPU 和內存);Claim 能夠請求特定的尺寸和訪問模式(例如可以加載一個讀寫,以及多個只讀實例)
PV 與 PVC
PV 是集羣的資源。PVC 是對這一資源的請求,也是對資源的所有權的檢驗。PV 和 PVC 之間的互動遵循如下的生命週期。
- 供應: 集羣管理員會創建一系列的 PV。這些 PV 包含了爲集羣用戶提供的真實存儲資源,它們可利用 Kubernetes API 來消費。
- 綁定: 用戶創建一個包含了容量和訪問模式的持久卷申請。Master 會監聽 PVC 的產生,並嘗試根據請求內容查找匹配的 PV,並把 PV 和 PVC 進行綁定。用戶能夠獲取滿足需要的資源,並且在使用過程中可能超出請求數量。如果找不到合適的卷,這一申請就會持續處於非綁定狀態,一直到出現合適的 PV。例如一個集羣準備了很多的 50G 大小的持久卷,(雖然總量足夠)也是無法響應 100G 的申請的,除非把 100G 的 PV 加入集羣。
- 使用: Pod 把申請作爲捲來使用。集羣會通過 PVC 查找綁定的 PV,並 Mount 給 Pod。對於支持多種訪問方式的卷,用戶在使用 PVC 作爲卷的時候,可以指定需要的訪問方式。一旦用戶擁有了一個已經綁定的 PVC,被綁定的 PV 就歸該用戶所有了。用戶的 Pods 能夠通過在 Pod 的卷中包含的 PVC 來訪問他們佔有的 PV。
- 釋放: 當用戶完成對卷的使用時,就可以利用 API 刪除 PVC 對象了,而且他還可以重新申請。刪除 PVC 後,對應的卷被視爲 “被釋放”,但是這時還不能給其他的 PVC 使用。之前的 PVC 數據還保存在卷中,要根據策略來進行後續處理。
- 回收: PV 的回收策略向集羣闡述了在 PVC 釋放卷的時候,應如何進行後續工作。目前可以採用三種策略:保留,回收或者刪除。保留策略允許重新申請這一資源。在持久卷能夠支持的情況下,刪除策略會同時刪除持久卷以及 AWS EBS/GCE PD 或者 Cinder 卷中的存儲內容。如果插件能夠支持,回收策略會執行基礎的擦除操作(
rm -rf /thevolume/*
),這一卷就能被重新申請了。
定義 PV
持久卷插件
持久卷是以插件方式實現的,目前支持的插件如下:
- GCEPersistentDisk google的我們用不了
- AWSElasticBlockStore 亞馬遜的雲存儲方案
- NFS(我們採用的是該方案)
- iSCSI
- RBD (Ceph Block Device)
- Glusterfs
- HostPath (單節點測試使用)
- 本地持久卷
YAML 配置
切換到虛擬機k8s-master上,創建目錄
mkdir -p /usr/local/kubernetes/volumes
cd /usr/local/kubernetes/volumes
創建一個名爲 nfs-pv-mysql.yml
的配置文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-mysql
spec:
# 設置容量 總共容量20G給mysql分配5G,看需求
capacity:
storage: 5Gi
# 訪問模式
accessModes:
# 該卷能夠以讀寫模式被多個節點同時加載,類似p2p網絡,多節點都讀寫
- ReadWriteMany
# 回收策略,這裏是基礎擦除 `rm-rf/thevolume/*`
persistentVolumeReclaimPolicy: Recycle
nfs:
# NFS 服務端配置的路徑
path: "/usr/local/kubernetes/volumes"
# NFS 服務端地址
server: 192.168.222.130
readOnly: false
# 部署
kubectl create -f nfs-pv-mysql.yml
# 刪除
kubectl delete -f nfs-pv-mysql.yml
# 查看
kubectl get pv
配置說明
Capacity(容量)
一般來說,PV 會指定存儲容量。這裏需要使用 PV 的 capcity 屬性。目前存儲大小是唯一一個能夠被申請的指標,今後會加入更多屬性,例如 IOPS,吞吐能力等。
AccessModes(訪問模式)
只要資源提供者支持,持久卷能夠被用任何方式加載到主機上。每種存儲都會有不同的能力,每個 PV 的訪問模式也會被設置成爲該卷所支持的特定模式。例如 NFS 能夠支持多個讀寫客戶端,但是某個 NFS PV 可能會在服務器上以只讀方式使用。每個 PV 都有自己的一系列的訪問模式,這些訪問模式取決於 PV 的能力。訪問模式的可選範圍如下:
- ReadWriteOnce: 該卷能夠以讀寫模式被加載到一個節點上
- ReadOnlyMany: 該卷能夠以只讀模式加載到多個節點上
- ReadWriteMany: 該卷能夠以讀寫模式被多個節點同時加載
在 CLI 下,訪問模式縮寫爲:
- RWO: ReadWriteOnce
- ROX: ReadOnlyMany
- RWX: ReadWriteMany
另外,一個卷不論支持多少種訪問模式,同時只能以一種訪問模式加載。例如一個 GCE Persistent Disk 既能支持 ReadWriteOnce,也能支持 ReadOnlyMany。
RecyclingPolicy(回收策略)
當前的回收策略可選值包括:
- Retain: 人工重新申請,防止刪庫跑路
- Recycle: 基礎擦除(
rm-rf/thevolume/*
) - Delete: 相關的存儲資產例如 AWS EBS,GCE PD 或者 OpenStack Cinder 卷一併刪除
目前,只有 NFS 和 HostPath 支持 Recycle 策略,AWS EBS、GCE PD 以及 Cinder 卷支持 Delete 策略。
階段(Phase)
一個卷會處於如下階段之一:
- Available: 可用資源,尚未被綁定到 PVC 上
- Bound: 該卷已經被綁定
- Released: PVC 已經被刪除,但該資源尚未被集羣回收
- Failed: 該卷的自動回收過程失敗
定義 PVC
創建一個名爲 nfs-pvc-mysql-myshop.yml
的配置文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc-mysql-myshop
spec:
accessModes:
# 需要使用和 PV 一致的訪問模式
- ReadWriteMany
# 按需分配資源
resources:
requests:
storage: 1Gi
# 部署
kubectl create -f nfs-pvc-mysql-myshop.yml
# 刪除
kubectl delete -f nfs-pvc-mysql-myshop.yml
# 查看
kubectl get pvc
部署 MySQL8
注意: 要確保每臺 Node 都安裝了 NFS 客戶端,
apt-get install -y nfs-common
創建mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-myshop
spec:
selector:
matchLabels:
app: mysql-myshop
replicas: 1
template:
metadata:
labels:
name: mysql-myshop
app: mysql-myshop
spec:
containers:
- name: mysql-myshop
image: mysql:8.0.16
# 只有鏡像不存在時,纔會進行鏡像拉取
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
# 同 Docker 配置中的 environment
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
# 容器中的掛載目錄
volumeMounts:
- name: nfs-vol-myshop
mountPath: /var/lib/mysql
volumes:
# 掛載到數據卷
- name: nfs-vol-myshop
persistentVolumeClaim:
claimName: nfs-pvc-mysql-myshop
---
apiVersion: v1
kind: Service
metadata:
name: mysql-myshop
spec:
ports:
- port: 3306
targetPort: 3306
type: LoadBalancer
selector:
name: mysql-myshop
測試運行
進入192.168.222.130可以看到mysql數據文件已經同步創建
部署成功後可以使用 kubectl get service
查看我們 MySQL 的運行端口,使用工具連接。
如果使用連接工具連接報如下錯誤
意思爲無法使用密碼的方式登錄。
在 Docker 部署時我們可以在 YAML 中配置相關參數解決這個問題;下一節我們講解在 Kubernetes 中採用 ConfigMap 的方式配置 MySQL。