pv和pvc

pv和pvc

pv: Persistent volume

是k8s虚拟化的存储资源,实际上就是存储,例如本地的硬盘,网络文件系统(nfs)

lvm RAID oss(ceph) 云存储。

pvc: Persistent volume claim

用户对存储资源的请求,定义了需要存储的空间大小,以及对存储空间的访问模式。

有了pvc请求之后,再和pv进行匹配,匹配到了之后绑定。绑定成功之后,就可以使用pv的存储空间。

pv和pvc的生命周期:

1、配置 定义pvc的请求的详细情况————匹配pv————绑定————使用————释放————pv回收

pv的状态有四种:

1、Available 可用 可以被pvc匹配。未绑定状态

2、bound 已绑定 pv已经被pvc绑定,正在使用

3、released 已释放 pvc请求已经被删除,但是pv的资源还没有被回收,pv是不可用的状态。

4、failed 失败 pv自动回收失败

pvc在请求的过程中支持的权限控制选项:

RWO ReadWriteOnce 存储目录的权限是可读,可写,但是这个目录只能被一个pod挂载

ROX ReadOnlyMany 存储可以以只读的方式被多个pod挂载

RWX ReadWriteMany 存储目录可以以读写的方式被多个pod挂载

NFS支持以上三种所有模式

Hostpath只支持ReadWriteOnce

云存储(对象存储可以支持动态扩缩容)

ISCSI不支持ReadWriteMany

ISCSI是一种在网络上运行的ISCSI协议的网络存储技术

pv的回收策略

Retain:保留 虽然pvc被删除了,但是pv还是处于released的状态,即使恢复到available状态,上一个挂载的数据也不会丢失

Delete:删除 虽然pvc被删除了,但是pv还是处于released的状态,即使恢复到available状态,数据全部删除

Recycle:回收 虽然pvc被删除了,但是pv还是处于released的状态,pv会自动的对资源进行回收,删除数据,然后pv自动回到available状态

[root@master01 k8s-yaml]# kubectl explain pv

我们使用的文件系统是nfs

[root@k8s4 data]# vim /etc/exports
​
/data/v1 192.168.60.0/24(rw,no_root_squash)
/data/v2 192.168.60.0/24(rw,no_root_squash)
/data/v3 192.168.60.0/24(rw,no_root_squash)
​
[root@k8s4 data]# mkdir -p /data/v{1,2,3}
[root@k8s4 data]# ls
v1  v2  v3
[root@k8s4 data]# systemctl restart rpcbind
[root@k8s4 data]# systemctl restart nfs
[root@master01 k8s-yaml]# vim pv.yaml
​
#我们定义3个pv,定义目录的路径,访问模式,pv的大小
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
#定义pv使用的文件系统
    server: 192.168.60.140
    path: /data/v1
#如果请求匹配到这个pv。使用的是目标主机的/data/v1
  accessModes: ["ReadWriteOnce"]
#定义访问模式
  capacity:
    storage: 1Gi
#Mi Gi Ti
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    server: 192.168.60.140
    path: /data/v2
  accessModes: ["ReadOnlyMany"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    server: 192.168.60.140
    path: /data/v3
  accessModes: ["ReadWriteMany"]
  capacity:
    storage: 3Gi
    
[root@master01 k8s-yaml]# kubectl apply -f pv.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
[root@master01 k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWO            Retain           Available                                   5s
pv002   2Gi        ROX            Retain           Available                                   5s
pv003   3Gi        RWX            Retain           Available                                   5s
​
创建pvc和pod
#定义好pvc的请求:
[root@master01 k8s-yaml]# vim pvc-pod.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes: ["ReadOnlyMany"]
  resources:
    requests:
      storage: 2Gi
#我需要pv,权限ReadWriteMany,空间是2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx1
  labels:
    app: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - name: nginx1
        image: nginx:1.22
        volumeMounts:
        - name: xy102
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: xy102
        persistentVolumeClaim:
#直接使用pvc的请求把容器内目录挂载pv请求对应的目录。
          claimName: mypvc
          
          [root@master01 k8s-yaml]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   1Gi        RWO            Retain           Available                                           44s
pv002   2Gi        ROX            Retain           Bound       default/mypvc                           44s
pv003   3Gi        RWX            Retain           Available                                           44s
​
[root@master01 k8s-yaml]# kubectl expose deployment nginx1 --port=80 --target-port=80 --type=NodePort
service/nginx1 exposed
[root@master01 k8s-yaml]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        2d20h
nginx1       NodePort    10.96.93.168   <none>        80:30565/TCP   2s
[root@master01 k8s-yaml]# curl 192.168.60.120:30565
123
[root@master01 k8s-yaml]# curl 192.168.60.120:30565
123
[root@master01 k8s-yaml]# curl 192.168.60.120:30565
123
[root@master01 k8s-yaml]# curl 192.168.60.130:30565
123
[root@master01 k8s-yaml]# curl 192.168.60.130:30565
123
[root@master01 k8s-yaml]# kubectl edit pv pv002 
  claimRef:                 #将这个字段中的命令全部删除即可
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    server: 192.168.60.140
    path: /data/v2
  accessModes: ["ReadOnlyMany"]
  persistentVolumeReclaimPolicy: Recycle        #加入这一行字段指定pv的回收策略
  capacity:
    storage: 2Gi

动态pv

不需要人工创建pv,根据pvc的请求自动创建pv然后实现挂载和使用。

k8s创建动态pv的机制是根据StorageClass,相当于提供pv的模板。

StorageClass+NFS 实现动态创建NFS的pv

k8s本身不支持nfs创建动态pv。使用外部的插件

Provisioner 存储分配器,自动使用配置好的NFS自动创建pv。

k8s当中,都使用Provisioner来创建动态pv

配合storageclass一起使用。

Provisioner配置信息,以及pvc的相关配置

stroageclass在根据配置信息调用模块创建pv。

pod————>provisioner————>storageclass————>pv

provisioner:

nfs-client:实现于nfs网络共享的协作用的最多的

aws-ebs:亚马逊云服务的动态卷,进行协作。

local-storage:k8s节点本地创建pv,一般是内部测试用的

external-Storage:云平台支持的对象存储协作。

[root@k8s4 opt]# vim /etc/exports
​
/data/v1 192.168.60.0/24(rw,no_root_squash)
/data/v2 192.168.60.0/24(rw,no_root_squash)
/data/v3 192.168.60.0/24(rw,no_root_squash)
/opt/k8s 192.168.60.0/24(rw,no_root_squash)
​
[root@k8s4 v2]# cd /opt/
[root@k8s4 opt]# mkdir k8s
[root@k8s4 opt]# chmod 777 k8s/
[root@k8s4 opt]# systemctl restart rpcbind
[root@k8s4 opt]# systemctl restart nfs
[root@k8s4 opt]# showmount -e
Export list for k8s4:
/opt/k8s 192.168.60.0/24
/data/v3 192.168.60.0/24
/data/v2 192.168.60.0/24
/data/v1 192.168.60.0/24

1、创建server ACCOUNT NFS-CLINET provisioner 账户

2、设定集群的角色,赋权

3、设定的权限和server account进行绑定,

4、NFS provisioner创建,depolyment方式创建

声明:存储节点,提供nfs服务的服务器

存储路径 共享目录

挂载点

5、创建storageclass,作为pv的模板,和NFS provisioner关联

6、创建pvc请求和业务pod进行测试1

具体操作:
1、创建server ACCOUNT NFS-CLINET provisioner 账户
2、设定集群的角色,赋权
3、设定的权限和server account进行绑定,

#创建角色:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
​
---
#赋权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-client-provisioner-clusterrole
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"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
#rules规则,包含nfs provisioner权限可以新建和删除pv,以及更新pv,监听pod的变化,实现更新挂载点的变化
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nfs-client-provisioner-clusterrolebinging
subjects:
- kind: ServiceAccount
  name: nfs-client-provisioner
  namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-clusterrole
  apiGroup: rbac.authorization.k8s.io
​
[root@master01 k8s-yaml]# kubectl apply -f nfs-client-rbac.yml 
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/nfs-client-provisioner-clusterrolebinging created
​
[root@master01 k8s-yaml]# vim /etc/kubernetes/manifests/kube-apiserver.yaml 
 15     - kube-apiserver
 16     - --feature-gates=RemoveSelfLink=false
#在15行后面加上16行
​
[root@master01 k8s-yaml]# kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
pod/kube-apiserver created
​
[root@master01 k8s-yaml]# kubectl get pod -n kube-system 
NAME                               READY   STATUS    RESTARTS   AGE
coredns-7f89b7bc75-52csh           1/1     Running   0          27h
coredns-7f89b7bc75-wrr7s           1/1     Running   0          27h
etcd-master01                      1/1     Running   1          2d23h
kube-apiserver                     0/1     Error     2          28s
kube-apiserver-master01            1/1     Running   0          64s
kube-controller-manager-master01   0/1     Running   2          2d23h
kube-flannel-ds-6hftg              1/1     Running   1          2d23h
kube-flannel-ds-82fg9              1/1     Running   0          27h
kube-flannel-ds-l4hvt              1/1     Running   0          27h
kube-proxy-bzvt5                   1/1     Running   0          2d23h
kube-proxy-jzmd4                   1/1     Running   1          2d23h
kube-proxy-mpr4s                   1/1     Running   0          2d23h
kube-scheduler-master01            0/1     Running   2          2d23h
#将kube-apiserver这个pod删除
[root@master01 k8s-yaml]# kubectl delete pod -n kube-system kube-apiserver
pod "kube-apiserver" deleted
4、NFS provisioner创建,depolyment方式创建

声明:存储节点,提供nfs服务的服务器

存储路径 共享目录

挂载点

[root@master01 k8s-yaml]# vim nfs-client-provisioner.yml
#创建provisioner的pod,声明路径和挂载点
#前面的账户使用在这个pod里面
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs1
  strategy:
    type: Recreate
#Recreate,每次升级容器或者更新都会将所有的旧的pod停止,然后再启动新的pod。
#会导致服务暂时中断。
  template:
    metadata:
      labels:
        app: nfs1
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
      - name: nfs1
        image: quay.io/external_storage/nfs-client-provisioner:latest
        volumeMounts:
        - name: nfs1
          mountPath: /persistentvolumes
        env:
        - name: PROVISIONER_NAME
          value: nfs-storage
#配置prosisioner的名称
        - name: NFS_SERVER
          value: 192.168.60.140
#在容器内设一个nfs服务器的IP地址变量
        - name: NFS_PATH
          value: /opt/k8s
#绑定nfs服务器的目录
      volumes:
#声明nfs数据卷的类型
      - name: nfs1
        nfs:
          server: 192.168.60.140
          path: /opt/k8s
          
[root@master01 k8s-yaml]# kubectl apply -f nfs-client-provisioner.yml 
deployment.apps/nfs1 created
[root@master01 k8s-yaml]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
nfs1-754c8b9fdb-t8nvn   1/1     Running   0          2m25s
​
5、创建storageclass,作为pv的模板,和NFS provisioner关联
[root@master01 k8s-yaml]# vim nfs-clint-storageclass.yml
​
#定义模板
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
provisioner: nfs-storage
parameters:
  archiveOnDelete: "false"
#true,表示删除pv时要进行存档。会把pv的状态标记为Archived。数据
依然可用,但是不再对新的pvc进行绑定。
#false,删除pvc,pv的状态先进入released,然后变成可用。
reclaimPolicy: Retain
#pv的回收策略
allowVolumeExpansion: true
#要想pv支持动态扩容,必须是true。
[root@master01 k8s-yaml]# kubectl apply -f nfs-clint-storageclass.yml 
storageclass.storage.k8s.io/nfs-clinet-storageclass created
6、创建pvc请求和业务pod进行测试1
[root@master01 k8s-yaml]# vim pvc-pod.yml
#定义好pvc的请求:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-mypvc
spec:
  accessModes: ["ReadOnlyMany"]
  storageClassName: nfs-client-storageclass
  resources:
    requests:
      storage: 2Gi
#我需要pv,权限ReadWriteMany,空间是2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx1
  labels:
    app: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - name: nginx1
        image: nginx:1.22
        volumeMounts:
        - name: xy102
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: xy102
        persistentVolumeClaim:
#直接使用pvc的请求把容器内目录挂载pv请求对应的目录。
          claimName: nfs-mypvc
[root@master01 k8s-yaml]# kubectl apply -f pvc-pod.yml
最后结果:
[root@master01 k8s-yaml]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nfs1-754c8b9fdb-t8nvn     1/1     Running   0          22m   10.244.1.214   node01   <none>           <none>
nginx1-74ddb78f7d-7z2pr   1/1     Running   0          25s   10.244.2.248   node02   <none>           <none>
nginx1-74ddb78f7d-l5hgw   1/1     Running   0          25s   10.244.2.247   node02   <none>           <none>
nginx1-74ddb78f7d-q8q7d   1/1     Running   0          25s   10.244.1.215   node01   <none>           <none>
​
[root@master01 k8s-yaml]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS              REASON   AGE
pvc-e3fc373b-b371-4121-b8ed-c05f184ce472   2Gi        ROX            Retain           Bound    default/nfs-mypvc   nfs-clinet-storageclass            57s
​

pv的默认策略,如果没有特殊需求,一律设置Retain。

就是说定义stroageclass的时候,设置pv的回收策略,只能是Retain,Delete的话,一旦删除pvc挂载点也一起删除了。数据没了会出大事。Recycle不能做动态的回收策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值