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

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-09-11 22:09  顶风少年  阅读(267)  评论(0编辑  收藏  举报
返回顶部