前面我们了解了K8s中各种存储卷及其特点,PV/PVC也是存储卷的一种,PV/PVC主要解决提高安全问题和组织结构分工问题。
为了解决提高安全问题和组织结构分工问题,k8s引入pvc和pv
示例:
# cat nfs-pvc示例.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-pvc
spec:
selector:
matchLabels:
app: nginx-nfs-pvc
replicas: 2
template:
metadata:
labels:
app: nginx-nfs-pvc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
该yaml文件分为两部分,第一部分为deployment(具体运行业务的pod),第二部分为PersistentVolumeClaim(开发人员申请的PVC)
# kubectl describe web-pvc-7f646ddbdb-hbrlh
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 59s 0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
Warning FailedScheduling 59s 0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Pending
生成出来pod为Pending状态,报错是没有绑定pvc,查看pvc为Pending状态可知,还没有pv去给pvc提供可用存储空间。
# cat pv示例.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/nfsdir
server: 10.7.7.222
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 5Gi RWX Retain Bound default/my-pvc 8s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Bound my-pv 5Gi RWX 126m
创建完成pv之后发现pv为Bound状态,pvc从Pending变成Bound状态,此时pod也从Pending状态变为running状态。
此时pv与pvc是一一对应的。每个pvc对应一个pv,pvc有开发人员提供,pv由运维人员维护。
pv与pvc的匹配条件:
存储容量限制:
PV静态供给明显的缺点是维护成本太高了!
因此,K8s开始支持PV动态供给,使用StorageClass对象实现(StorageClass帮助我们自动创建pv)
# ls -l
total 12
-rw-r--r-- 1 root root 225 Oct 30 2020 class.yaml # 创建存储类(StorageClass)
-rw-r--r-- 1 root root 994 Oct 30 2020 deployment.yaml # 部署nfs插件,需修改里面NFS服务器地址与共享目录
-rw-r--r-- 1 root root 1526 Oct 30 2020 rbac.yaml # 授权访问apiserver
修改nfs插件deployment,需要修改部分(25、33、35、39、40)
22 serviceAccountName: nfs-client-provisioner
23 containers:
24 - name: nfs-client-provisioner
25 image: nfs-client-provisioner:latest
26 volumeMounts:
27 - name: nfs-client-root
28 mountPath: /persistentvolumes
29 env:
30 - name: PROVISIONER_NAME
31 value: fuseim.pri/ifs
32 - name: NFS_SERVER
33 value: 10.7.7.222
34 - name: NFS_PATH
35 value: /ifs/nfsdir
36 volumes:
37 - name: nfs-client-root
38 nfs:
39 server: 10.7.7.222
40 path: /ifs/nfsdir
class.yaml文件
# cat class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage # 创建pvc时需要指定这个name
provisioner: fuseim.pri/ifs # 接口fuseim.pri/ifs,与插件deployment中"env.name (PROVISIONER_NAME)"保持一致,无需改动
parameters:
archiveOnDelete: "true" # 是否归档,true为删除pv并备份nfs-server储存的文件
自动pv供给示例
# cat autopv示例.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-autopvc
spec:
selector:
matchLabels:
app: nginx-nfs-autopvc
replicas: 2
template:
metadata:
labels:
app: nginx-nfs-autopvc
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-autopvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-autopvc
spec:
storageClassName: "managed-nfs-storage"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 30Gi
# kubectl get pods |grep auto
web-autopvc-dd9f7bc78-bwq46 1/1 Running 0 42s
web-autopvc-dd9f7bc78-vdjqm 1/1 Running 0 42s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-autopvc Bound pvc-b5b27e9a-8741-497f-a1a0-cda57de73421 30Gi RWX managed-nfs-storage 46s
my-pvc Bound my-pv 5Gi RWX 178m
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 5Gi RWX Retain Bound default/my-pvc 52m
pvc-b5b27e9a-8741-497f-a1a0-cda57de73421 30Gi RWX Delete Bound default/my-autopvc managed-nfs-storage 50s
在nfs-server机器查看nfs目录,可知自动创建一个目录对应pv
ls -l /ifs/nfsdir/
total 4
drwxrwxrwx 2 root root 6 Feb 14 21:16 default-my-autopvc-pvc-b5b27e9a-8741-497f-a1a0-cda57de73421
-rw-r--r-- 1 root root 20 Feb 14 17:53 index.html
总结:
唯一与手动创建pv不同的时,这里pvc申请pv需要指定存储类名称storageClassName: “managed-nfs-storage”
存储类用调用nfs-client-pod(nfs存储插件)去创建pv,自动创建出来的pv为Delete回收策略。
部分存储插件已经内置k8s:https://kubernetes.io/zh/docs/concepts/storage/storage-classes
如果没有内置k8s中,可使用外部插件:https://github.com/kubernetes-retired/external-storage
当删除pvc时,pv会直接删除(回收策略),nfs-server使用的存储目录会备份一份(class.yaml中定义的归档)
AccessModes(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
STATUS(状态):
一个 PV 的生命周期中,可能会处于4中不同的阶段: