(二十一)Kubernetes資源管理PV&PVC
阿新 • • 發佈:2022-05-12
kubernetes支援持久卷的儲存外掛:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
PersistenVolume(PV):對儲存資源建立和使用的抽象,使得儲存作為叢集中的資源管理,分為有靜態與動態。(可以連線:NFS,CEPG/GFS、Ceph)
PersistentVolumeClaim(PVC):讓使用者不需要關心具體的Volume實現細節
- PV:提供者、提供儲存容量,由k8s配置的儲存,PV同樣是叢集的一類資源,
- PVC:消費者、消費容量
注:PV與PVC成繫結關係。(容器應用-->卷需求模板-->資料卷定義)
一、 Kubernetes靜態PV使用
kubernetes支援持久卷的儲存外掛:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- 缺點:手動建立pv比較繁瑣、不適合大工程
- 優點:小規模使用方便靈活
1、建立pvc yaml檔案
vim pvc.yaml apiVersion: v1 kind: Pod metadata: name: nginx6 spec: containers: - name: nginx6 image: nginx # 掛在點 volumeMounts: - name: wwwroot mountPath: /usr/share/nginx/html ports: - containerPort: 80 # 掛載來源 volumes: - name: wwwroot # 定義PVC persistentVolumeClaim: # 定義PVC名稱 claimName: my-pvc --- apiVersion: v1 # 使用PVC型別 kind: PersistentVolumeClaim metadata: # 與容器應用PVC相同 name: my-pvc spec: # 定義讀寫許可權 accessModes: - ReadWriteMany # 請求資源 resources: requests: # 儲存空間 5G storage: 5Gi
2、建立pv yaml檔案
vim pv.yaml
apiVersion: v1
# PV型別
kind: PersistentVolume
metadata:
# PV名稱與PVC相同
name: my-pv
spec:
# 定義容量
capacity:
storage: 5Gi
# 讀寫許可權
accessModes:
- ReadWriteMany
# nfs分配網路儲存
nfs:
path: /data/nfs
server: 192.168.1.115
3、執行建立pv容器
kubectl apply -f pv.yaml
4、檢視建立pv
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
# RWX:讀寫模式、Available:為可用狀態
my-pv 5Gi RWX Retain Available 23s
5、建立pvc容器
kubectl apply -f pvc.yaml
6、檢視pvc建立容器
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx6 1/1 Running 0 20s
7、檢視pv與pvc狀態
kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
# Bound:已經使用以成繫結裝填
persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 3m44s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# 以繫結到pv
persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 78s
8、nfs共享目錄下建立一個index.html
echo "<h1>xxxxxxxxx</h1>" > /data/nfs/index.html
9、進入容器測試
kubectl exec -it nginx6 bash
ls /usr/share/nginx/html
index.html
NFS型別PV模板
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
spec:
capacity: # PV容量
storage: 5Gi
volumeMode: Filesystem # 掛載的型別,Filesystem\block
accessModes: # PV訪問模式
- ReadWriteOnce # 可以被單節點讀寫的模式掛載
persistentVolumeReclaimPolicy: Recycle # 回收策略
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
persistenVolumeReclaimPolicy: Recycle: 回收/Retain: 保留/Delete刪除(pvc刪除pv也會刪除,動態儲存的預設方式)
- ReadWriteOnce # 可以被單節點讀寫的模式掛載
- ReadWriteMany # 可以被多個點讀寫的模式掛載
- ReadOnlyOnce # 可以多個節點只讀的模式掛載
PV的狀態:
- Availabe:空閒PV,沒有被任何PVC繫結
- Bond:已被PVC繫結
- Released:PVC被刪除,但是資源未被重新使用
- Failed:自動回收失敗
PVC模板
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector: #選擇和標籤匹配的PVC
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
建立POD掛載PVC
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
很多情況下:(建立PVC之後,一直繫結不上PV[Pending狀態])
- PVC的空間申請大小大於PV的大小
- PVC的StorageClassName沒有和PV一致
- PVC的accessMode和PV的不一致
建立掛載了PVC的Pod之後,一直處於Pending狀態:
- PVC沒有建立成功,或者被創
- PVC和Pod不在同一個Namespace
刪除PVC後---->k8s會建立一個用於回收的Pod---->根據PV的回收策略進行PV的回收---->回收完以後PV的狀態會變成可繫結的狀態也就是空閒狀態---->其他Pending狀態的PVC如果匹配到了這個PV,他就能和這個PV進行繫結。
二、Kubernetes 動態PV使用
Kubernetes支援動態供給的儲存外掛:
https://kubernetes.io/docs/concepts/storage/storage-classes/
- Dynamic Provisioning機制工作的核心在於StorageClass的API物件。
- StorageClass宣告儲存外掛,用於自動建立PV
建立動態PVStorageClass
1、建立storageclass相關檔案
1.1、vim storageclass-nfs.yaml:標識外掛建立storageclass名稱
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
# StorageClass名稱
name: managed-nfs-storage
# 預設不支援nfs儲存,新增支援web外掛標識
provisioner: fuseim.pri/ifs
1.2、vim deployment-nfs.yaml:建立nfs相關儲存指定服務名稱
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
imagePullSecrets:
- name: registry-pull-secret
# 繫結角色定義的名稱
serviceAccount: nfs-client-provisioner
containers:
# 映象拉取
- name: nfs-client-provisioner
image: lizhenliang/nfs-client-provisioner:v2.0.0
# 自定義變數格式處理
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
# 指定標識外掛的值
value: fuseim.pri/ifs
- name: NFS_SERVER
# nfs地址
value: 192.168.1.115
- name: NFS_PATH
# 掛在路徑
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
# nfs地址
server: 192.168.1.115
# 共享路徑
path: /data/nfs
1.3、vim rbac.yaml:建立rbac授權apiserver
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: nfs-client-provisioner-runner
# 角色中可以訪問的許可權
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
---
# 角色繫結
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: run-nfs-client-provisioner
subjects:
# 繫結角色 ServiceAccount
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
2、建立檔案
kubectl apply -f storageclass-nfs.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment-nfs.yaml
3、檢視建立的storageclass
kubectl get storageclass
NAME PROVISIONER AGE
managed-nfs-storage fuseim.pri/ifs 57s
4、檢視建立的nfs容器
kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-565b4456f6-v9b97 1/1 Running 0 67s
使用動態 PV StorageClass 案例一:部署mysql
1、建立yaml配置檔案。vim mysql.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
name: mysql
# 建立service為無頭服務,標識容器
clusterIP: None
selector:
app: mysql-public
---
apiVersion: apps/v1beta1
kind: StatefulSet
# 名稱
metadata:
name: db
spec:
# 指定service名稱
serviceName: "mysql"
# 標籤選擇器
template:
metadata:
labels:
app: mysql-public
spec:
# 映象容器編輯
containers:
- name: mysql
image: mysql:5.7
env:
# 建立資料庫使用者密碼
- name: MYSQL_ROOT_PASSWORD
value: "123456"
# 建立資料庫
- name: MYSQL_DATABASE
value: test
# 啟用埠
ports:
- containerPort: 3306
# 資料卷
volumeMounts:
# 掛在容器目錄
- mountPath: "/var/lib/mysql"
# 使用來源
name: mysql-data
# 使用資料捲來源
volumes:
# 資料卷名稱
- name: mysql-data
# 指定資料捲動態供給
persistentVolumeClaim:
# pvc動態供給名稱
claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
# pvc名稱
name: mysql-pvc
spec:
# 讀寫許可權
accessModes:
- ReadWriteMany
# 使用的儲存類
storageClassName: managed-nfs-storage
# 定義容量
resources:
requests:
storage: 5Gi
2、建立容器
kubectl apply -f mysql.yaml
3、檢視持久卷
kubectl get PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-public-mysql-public-0 Bound default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO managed-nfs-storage 39m
mysql-pvc Bound default-mysql-pvc-pvc-b8584af2-c89d-11e9-9db0-000c292e28d6 5Gi RWX managed-nfs-storage 14m
使用動態 PV StorageClass 案例二
1、建立檔案
vim sts.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 1Gi
2、建立容器
kubectl create -f sts.yaml
3、檢視pod
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-statefulset-0 1/1 Running 0 3m21s
nginx-statefulset-1 1/1 Running 0 3m16s
nginx-statefulset-2 1/1 Running 0 3m11s
4、檢視動態pv,pvc儲存kubectl get pv,pvc
kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO Delete Bound default/mysql-public-mysql-public-0 managed-nfs-storage 63m
persistentvolume/default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-0 managed-nfs-storage 11m
persistentvolume/default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-1 managed-nfs-storage 11m
persistentvolume/default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-2 managed-nfs-storage 11m
persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 133m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 133m
persistentvolumeclaim/mysql-public-mysql-public-0 Bound default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO managed-nfs-storage 63m
persistentvolumeclaim/www-nginx-statefulset-0 Bound default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m
persistentvolumeclaim/www-nginx-statefulset-1 Bound default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m
persistentvolumeclaim/www-nginx-statefulset-2 Bound default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m
5、nfs伺服器會自動建立pv資料
[root@localhost nfs]# ls
default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317
default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317
default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317