K8s存储emptyDir/hostPath/pv与pvc

  • 2022-04-06 14:13:19
  • 运维
  • 35
  • shevechco

K8s存储emptyDir、hostPath、pv和pvc
pod容器组在宕机或者删除以后,数据会随着pod的销毁而消失,所以需要使用一些存储方案来做数据的持久化,目前有很多存储方案,主要有emptyDir、hostPath、NFS、云存储
我们下面就通过例子来看看上述几种存储方式的区别
1.emptyDir
emptyDir类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Pod从node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录
例:

01.
apiVersion: apps/v1
02.
kind: Deployment
03.
metadata:
04.
  name: nginx-emptydir
05.
spec:
06.
  selector:
07.
    matchLabels:
08.
      app: nginx
09.
  template:
10.
    metadata:
11.
      labels:
12.
        app: nginx
13.
    spec:
14.
      nodeName: k8s-node1  # 指定部署节点
15.
      containers:
16.
        - name: nginx
17.
          image: nginx
18.
          volumeMounts:  # 挂载容器内部目录
19.
            - mountPath: /data/empty
20.
              name: emptydir #存储卷名称
21.
      volumes:
22.
        - name: emptydir
23.
          emptyDir: {}

2.hostpath
HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用HostPath卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载
例:

01.
apiVersion: apps/v1
02.
kind: Deployment
03.
metadata:
04.
  name: nginx-hostpath
05.
spec:
06.
  selector:
07.
    matchLabels:
08.
      app: nginx
09.
  template:
10.
    metadata:
11.
      labels:
12.
        app: nginx
13.
    spec:
14.
      nodeName: k8s-node1  # 指定部署节点
15.
      containers:
16.
        - name: nginx
17.
          image: nginx
18.
          volumeMounts:  # 挂载容器内部目录
19.
            - mountPath: /data/share
20.
              name: localpath #存储卷名称
21.
      volumes:
22.
        - name: localpath
23.
          hostPath:
24.
            path: /opt/hostpath # 这里会在node节点创建目录并对应容器内部的mountPath
25.
            type:  DirectoryOrCreate # 类型:没有就创建,有就不创建

用户可以选择性地为 hostPath 卷指定 type
支持的 type 值如下:

01.
DirectoryOrCreate  宿主机上不存在创建此目录  
02.
Directory 必须存在挂载目录  
03.
FileOrCreate 宿主机上不存在挂载文件就创建  
04.
File 必须存在文件

当使用这种类型的卷时要小心,因为:
HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权 API(例如容器运行时套接字), 可用于容器逃逸或攻击集群的其他部分。
具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同 而在不同节点上有不同的行为。
下层主机上创建的文件或目录只能由 root 用户写入。你需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath卷

3.pv/pvc
PersistentVolume(PV)是群集中的一块存储(类似一块磁盘),由管理员配置或使用存储类动态配置。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统
PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建pod时可以定义这个类型的存储卷。 它类似于一个pod。 Pod消耗节点资源,PVC消耗PV资源。 Pod可以请求特定级别的资源(CPU和内存)。 pvc在申请pv的时候也可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)
PV的访问模式

01.
ReadWriteOnce(RWO)     可读可写,但只支持被单个节点挂载。
02.
ReadOnlyMany(ROX)     只读,可以被多个节点挂载。
03.
ReadWriteMany(RWX)     多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

PV的回收策略

01.
Retain     不清理, 保留 Volume(需要手动清理)
02.
Recycle     删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
03.
Delete     删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)

PVC状态

01.
Available(可用)——一块空闲资源还没有被任何声明绑定
02.
Bound(已绑定)——卷已经被声明绑定
03.
Released(已释放)——声明被删除,但是资源还未被集群重新声明
04.
Failed(失败)——该卷的自动回收失败

下面来一组例子:

01.
pv.yaml
02.
apiVersion: v1
03.
kind: PersistentVolume
04.
metadata:
05.
  name: pv-nfs-1
06.
  labels:
07.
    app: pv-nfs-1
08.
spec:
09.
  volumeMode: Filesystem
10.
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
11.
  persistentVolumeReclaimPolicy: Retain
12.
  capacity:
13.
    storage: 2Gi
14.
  volumeMode: Filesystem
15.
  mountOptions:
16.
    - hard
17.
    - nfsvers=4.1
18.
  nfs:
19.
    path: /data/nas1
20.
    server: 192.168.137.10
21.
---
22.
apiVersion: v1
23.
kind: PersistentVolume
24.
metadata:
25.
  name: pv-nfs-2
26.
  labels:
27.
    app: pv-nfs-2
28.
spec:
29.
  volumeMode: Filesystem
30.
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
31.
  persistentVolumeReclaimPolicy: Retain
32.
  capacity:
33.
    storage: 3Gi
34.
  volumeMode: Filesystem
35.
  mountOptions:
36.
    - hard
37.
    - nfsvers=4.1
38.
  nfs:
39.
    path: /data/nas2
40.
    server: 192.168.137.10
41.
---
42.
apiVersion: v1
43.
kind: PersistentVolume
44.
metadata:
45.
  name: pv-nfs-3
46.
  labels:
47.
    app: pv-nfs-3
48.
spec:
49.
  volumeMode: Filesystem
50.
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
51.
  persistentVolumeReclaimPolicy: Retain
52.
  capacity:
53.
    storage: 4Gi # 申请多大的PV,PVC会申请一个匹配或者稍大于的PV资源
54.
  volumeMode: Filesystem
55.
  mountOptions:
56.
    - hard
57.
    - nfsvers=4.1
58.
  nfs:
59.
    path: /data/nas3
60.
    server: 192.168.137.10
61.
---
62.
#pvc.yaml
63.
apiVersion: v1
64.
kind: PersistentVolumeClaim
65.
metadata:
66.
  name: pvc-nfs
67.
spec:
68.
  accessModes: ["ReadWriteMany"]
69.
  resources:
70.
    requests:
71.
      storage: 1Gi
72.
  selector:
73.
    matchLabels:
74.
      app: pv-nfs-2

我们可以用过命令查看卷状态

01.
kubectl get pv/pvc

图片.png

可以看到pvc和pv-nfs-2是bound状态
最后我们再重新编辑下deploy,挂载下这个pvc看看效果

01.
apiVersion: apps/v1
02.
kind: Deployment
03.
metadata:
04.
  name: nginx-pvc
05.
spec:
06.
  selector:
07.
    matchLabels:
08.
      app: nginx
09.
  template:
10.
    metadata:
11.
      labels:
12.
        app: nginx
13.
    spec:
14.
      #nodeName: k8s-node1  # 指定部署节点
15.
      containers:
16.
        - name: nginx
17.
          image: nginx
18.
          volumeMounts:  # 挂载容器内部目录
19.
            - mountPath: /data/nfs
20.
              name: nginx-nfs #存储卷名称
21.
      volumes:                              
22.
        - name: nginx-nfs
23.
          persistentVolumeClaim:
24.
            claimName: pvc-nfs

注意:
我们每次创建pvc的时候,需要事先有划分好的pv,这样可能不方便,那么可以在创建pvc的时候直接动态创建一个pv这个存储类,pv事先是不存在的
pvc和pv绑定,如果使用默认的回收策略retain,那么删除pvc之后,pv会处于released状态,我们想要继续使用这个pv,需要手动删除pv,kubectl delete pv pv_name,删除pv,不会删除pv里的数据,当我们重新创建pvc时还会和这个最匹配的pv绑定,数据还是原来数据,不会丢失
删除流程:POD->PVC->PV


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.sulao.cn/post/821

相关推荐