k8s-持久卷存储
作者:互联网
第一个Demo
PV与PVC概念
存储容量
访问模式
PV回收策略
PVC选择PV
第一个Demo
PV关联后端存储,PVC关联PV,Pod关联PVC。这里的后端存储使用的是NFS网络文件系统。这个类型的存储需要一台Server,client就是我们的k8s集群。
服务端安装NFS,需要另外找一台主机。
#关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service #创建共享目录和权限设置 mkdir -p /data/k8s chown -R 777 /data/k8s/ #通过yum进行安装 yum -y install nfs-utils rpcbind #配置 nfs,nfs 的默认配置文件在 /etc/exports 文件下,在该文件中添加下面的配置信息 vim /etc/exports /data/k8s *(rw,sync,no_root_squash) #备注相关配置说明 /data/k8s:是共享的数据目录 *:表示任何人都有权限连接,当然也可以是一个网段,一个 IP,也可以是域名 rw:读写的权限 sync:表示文件同时写入硬盘和内存 no_root_squash:当登录 NFS 主机使用共享目录的使用者是 root 时,其权限将被转换成为匿名使用者,通常它的 UID 与 GID,都会变成 nobody 身份 #启动顺序,先启动rpc,在启动nfs systemctl enable rpcbind systemctl start rpcbind systemctl status rpcbind systemctl enable nfs systemctl start nfs systemctl status nfs #查看挂载信息 cat /var/lib/nfs/etab
客户端安装NFS注意,这里的客户端是k8s集群。
#关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service #安装nfs yum -y install nfs-utils rpcbind #创建自启动服务 systemctl enable rpcbind systemctl start rpcbind systemctl enable nfs systemctl start nfs #查看可以登录的nfs地址 ip就是NFS服务端的IP showmount -e 127.0.0.1
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 2Gi accessModes: - ReadWriteOnce nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
apiVersion: v1 kind: Pod metadata: name: pod1 spec: restartPolicy: Never hostNetwork: true volumes: - name: path1 persistentVolumeClaim: claimName: pvc1 containers: - name: c1 image: myapp imagePullPolicy: IfNotPresent ports: - name: tomcatport containerPort: 8080 command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"] volumeMounts: - name: path1 mountPath: "/home/"
容器中有个接口,访问接口则会创建一个文件。
@GetMapping("test") public String test() { String s = "~~~~~~~~~~"; try { InetAddress localHost = InetAddress.getLocalHost(); String hostAddress = localHost.getHostAddress(); String hostName = localHost.getHostName(); s = s + "--------" + hostAddress + "-------" + hostName; long l = System.currentTimeMillis(); FileOutputStream fileOutputStream = new FileOutputStream("/home/"+l+".txt"); s = l + s; fileOutputStream.write(s.getBytes()); } catch (Exception e) { throw new RuntimeException(e); } return s; }
进入容器内查看文件存在
到NFS服务端也可以查到文件。
PV与PVC概念
PV是对存储资源的抽象,将存储定义为一种容器应用可以使用的资源,PV由管理员创建和配置。PV的种类有很多,如上边例子NFS,GlusterFS等。PV的生命周期独立于使用它的Pod。
PVC则是用户对存储资源的申请,就像Pod消耗Node资源一样,PVC消耗PV资源。
简单说,PV是资源的抽象,PVC是使用资源的抽象。
资源供应
k8s支持两种资源供应模式:静态模式和动态模式,资源供应的结果就是将合适的PV与PVC成功绑定。
静态模式:集群管理员预先创建许多PV,在PV的定义中能够体现存储资源的特性。第一个demo就是静态模式。
动态模式:集群管理员无须预先创建PV,而是通过StorageClass的设置对后端存储资源进行描述,标记存储的类型和特性。用户通过创建PVC对存储类型进行申请,
系统将自动完成PV的创建及与PVC的绑定。
资源绑定
在用户定义好PVC后,系统将根据PVC对存储资源的请求(存储空间,访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将PV于用户定义的PVC绑定,
用户的应用就可以使用这个PVC了。如果在系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到系统管理员创建了一个符合要求的PV。
PV一旦与某个PVC完成绑定,就会被这个PVC独占,不能在于其他的PVC绑定了,PVC与PV的绑定关系是一对一的,不会出现一对多的情况。如果PVC申请的存储空间比PV拥有的空间少,
则整个PV空间也会被这个PVC所用,可能造成资源浪费。
如果资源供应使用是动态模式,则系统会为PVC找到合适的StorageClass后,将自动创建PV并完成与PVC的绑定。
资源使用
Pod需要使用存储资源时,需要在Volume的定义中引用PVC类型的存储卷,将PVC挂载到容器内的某个路径下镜像使用。Pod在挂载PVC后,就能使用存储资源了。同一个PVC还可以被多个Pod
同事挂载使用。存储资源PV,PVC相对于容器应用Pod是独立的管理的资源,可以单独删除。在做删除操作时,系统会检测存储资源当前是否正在被使用,如果仍被使用,则不会立刻删除。例如删除PVC时
如果有Pod正在使用PVC则不会立刻删除,删除PV时如果有PVC正在使用PV则也不会立刻删除。在资源被占用的情况下PV和PVC的状态为Terminating。
资源回收
用户在使用存储资源完毕后,可以删除PVC。与该PVC绑定的PV将被标记为已释放,但还不能立刻与其他的PVC绑定。因为之前使用PV时产生的数据还在存储设备上,只有清除这些数据后,该PV才可以再次使用。
管理员可以对PV设置资源回收策略,有三种策略选择。
Retain(保留数据)
Retain策略表示在删除PVC之后,与只绑定的PV不会被删除,仅仅被标记为已释放。需要手动清理后才能够继续使用。
Delete(删除数据)
Delete策略表示自动删除PV资源对象和后端资产,但是并不是所有的后端存储都支持这种类型。
Recyle
目前只有HostPort和NFS类型的Volume支持Recycle策略,其实现机制为运行 rm -rf /volume 目录下的全部文件,使得PV可以被新的PVC使用。
PV生命周期
Available:可用状态,还未与某个PVC绑定。
Bound:已与某个PVC绑定。
Released:与之绑定的PVC已经被删除,但未完成资源回收,不能被其他PVC使用。
Failed:自动资源回收失败。
存储容量
PV和PVC都可以设置capacity,但如果PV的容量小于PVC申请的容量,PVC则会一直处于Pending状态,PV则处于Available状态。
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 10Mi accessModes: - ReadWriteOnce nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Mi
访问模式
PV和PVC的访问模式分为RWO,ROX,RWX三种,PVC的访问模式需要和PV相同,一个PV只能指定一种访问模式,并且PV具体支持哪些访问模式由存储提供商支持,例如NFS存储支持以上三种模式。
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 10Mi accessModes: - ReadWriteMany nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: accessModes: - ReadOnlyMany resources: requests: storage: 5Mi
ReadWriteMany(RWX)
读写权限,允许被多个Node挂载。以下案例通过DaemonSet在Node1,Node2上发布两个pod,每个pod都对外暴露端口。分别访问两个pod中的容器,发现都可以创建文件。
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 10Mi accessModes: - ReadWriteMany nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: accessModes: - ReadWriteMany resources: requests: storage: 5Mi
apiVersion: apps/v1 kind: DaemonSet metadata: name: d1 spec: selector: matchLabels: app: v1 template: metadata: labels: app: v1 spec: hostNetwork: true volumes: - name: path1 persistentVolumeClaim: claimName: pvc1 containers: - name: myapp01 image: myapp imagePullPolicy: IfNotPresent ports: - name: tomcatport containerPort: 8080 command: ["nohup","java","-jar","/usr/local/test/dockerdemo.jar","&"] volumeMounts: - name: path1 mountPath: "/home/"
ReadOnlyMany(rox)
只读权限,允许被多个Node挂载。但是,我这边做了实验,PV,PVC都是只读的,但写文件也可以。
ReadWriteOnce(RWO)
读写权限,并且只能被单个Node挂载。但我用DaemonSet创建在两个Node上也可以读写。
PV回收策略
Retain
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 10Mi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/k8s/ server: 192.168.180.135
保留数据,需要手动处理。
Released状态下的PV不能在被PVC使用,手动处理的意思就是删掉PV然后再重新创建,或者修改PV。删掉 claimRef 配置。PV的状态就回到 Available 状态了。
[root@k8s-master01 home]# kubectl edit pv pv1 # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: PersistentVolume metadata: annotations: pv.kubernetes.io/bound-by-controller: "yes" creationTimestamp: "2022-09-05T07:50:12Z" finalizers: - kubernetes.io/pv-protection name: pv1 resourceVersion: "65785" selfLink: /api/v1/persistentvolumes/pv1 uid: 76d24589-89ba-4a1f-aa84-bdf813f29804 spec: accessModes: - ReadWriteOnce capacity: storage: 10Mi claimRef: apiVersion: v1 kind: PersistentVolumeClaim name: pvc1 namespace: default resourceVersion: "64728" uid: 6e5cbe1b-4202-4928-9c5e-c03a0ca91ffe nfs: path: /data/k8s/ server: 192.168.180.135 persistentVolumeReclaimPolicy: Retain volumeMode: Filesystem status: phase: Released
Recycle
目前只有HostPort和NFS类型的Volume支持Recycle策略,其实现机制为运行 rm -rf/thevolume/* 命令,删除Volume目录下的全部文件。已经弃用!
Delete
表示自动删除PV资源对象和相关后端存储资产,并不是所有的存储提供商都支持Delete策略。目前支持Delete策略的提供商包括AWSElasticBlockStore等。
PVC选择PV
PVC通过 selector.matchLabels与有对应标签的PV绑定。以下案例先创建PV2,PVC1也不会跟他绑定,因为标签不匹配。等到PV1创建后,PVC1与之绑定。
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 labels: pvname: opv spec: capacity: storage: 10Mi accessModes: - ReadWriteMany nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolume metadata: name: pv2 labels: pvname: tpv spec: capacity: storage: 10Mi accessModes: - ReadWriteMany nfs: path: /data/k8s/ server: 192.168.180.135
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc1 spec: accessModes: - ReadWriteMany resources: requests: storage: 5Mi selector: matchLabels: pvname: opv
标签:存储,PV,name,v1,PVC,nfs,持久,k8s 来源: https://www.cnblogs.com/zumengjie/p/16655821.html