k8s中的Volume

目录

emptyDir

hostPath

存储PV-PVC


emptyDir

emptyDir用法:

        - 暂存空间,例如用于基于磁盘的合并排序

        - 用作长时间计算崩溃恢复时的检查点

        - Web服务器容器需要提供一些固定数据,保存内容管理器的容器提取的文件

例子:

vim emptyVolume-demo-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: empty-volume
spec:
  containers:
  - image: nginx:1.16
    name: nginx-empty-demo
    volumeMounts:
    - mountPath: /cache     # 容器里的挂载地址
      name: cache-volume    # 指定volume,即通过哪个目录进行挂载的
  volumes:
  - name: cache-volume
    emptyDir: {}

运行并查看

kubectl apply -f emptyVolume-demo-pod.yaml

 也可以查看pod的描述进行确认

kubectl describe pod empty-volume

注意:当创建的Pod中存在两个或者多个container的时候,所有的container共享emptyDir,进入一个container在挂载目录下创建一个文件,其他container查看时,都会看到文件变化了。

想做实验的可以copy如下配置文件,直接apply即可。

apiVersion: v1
kind: Pod
metadata:
  name: empty-volume2
spec:
  containers:
  - image: nginx:1.16
    name: nginx-empty-demo
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - image: busybox:latest
    name: busybox-empty-demo
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","sleep 6000s"]
    volumeMounts:
    - mountPath: /test          # cahnge mount dir
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {} 

hostPath

hostPath卷是将主机节点中的文件系统中的文件或者目录挂载到集群中

hostPath用途如下:

        - 运行需要访问Docker内部的容器;使用/var/lib/docker的hostPath

        - 在容器中运行cAdvisor; 使用/dev/cgroups的hostPath

除了所需path之外,用户还可以为hostPath指定type

行为
空字符串(默认)用于向后兼容,这意味着在挂载hostPath卷之前不会执行任何检查
DirectoryOrCreate如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为0755,与kubectl具有相同的组合所有权
Directory给定的路径下必须存在目录
FireOrCreate如果给定的路径没有东西,则创建一个空文件,权限设置为0644,与kubectl 具有相同的组和所有权
File给定的路径下必须存在文件
socket给定的路径下必须存在 unix套接字
charDevice给定的路径下必须存在字符设备
BlockDevice给定的路径下必须存在块设备

例子:

vim hostpath-demo-01.yaml

apiVersion: v1
kind: Pod
metadata:
  # 这里注意,pod name的命名规则是小写
  name: hostpath-demo
spec:
  containers:
  - image: nginx:1.16
    name: nginx-container
    volumeMounts:
    - mountPath: /test-hp
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /opt/data
      # this field is optional
      type: Directory

        运行并查看,在运行起来后,可以进入创建的容器,并在容器中/test-hp挂载目录下创建一个文件,这时候可以看到Node物理机的/opt/data目录下也会出现该文件。

        试着删除该pod,宿主机上的文件并不会被删除,重启启动pod后,可以继续使用该文件,但是不同的宿主机都在各自的目录下,有一份自己的文件,并没有做到唯一性。如果想要做到统一存储,就要用到PV-PVC。

kubectl apply -f hostpath-demo-01.yaml

存储PV-PVC

PersistentVolume(PV)

        是由管理员设置的存储,是集群的一部分,就像 节点是集群的资源一样,pv也是集群的资源。PV是Volume之类的卷插件,但具有独立于使用PV的Pod的声明周期。此API对象包含存储实现的细节,即NFS、iSCSI或特定于云供应商的存储系统。

PersistentVolumeClaim(PVC)

        是用户存储的请求,它与Pod相似。Pod消耗节点资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以读/写一次或只读多次模式挂载)

静态PV

        集群管理员创建一些PV,他们带有可供集群用户使用的实际存储的细节。他们存在于Kubernetes API 中,可用于消费。

动态

        当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses:PVC必须请求(存储类),并且管理员必须创建并配置该类才能进行动态地创建。声明该类为“”可以有效的禁用其动态配置。

        要启动基于存储级别的动态存储配置,集群管理员需要启用API server上的DefaultStorageClass[准入控制器]。例如,通过确保[DefaultStorageClass]位于API server组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作。

绑定

        master中的控制环路监视新的PVC,寻找匹配的PV,并将他们绑定在一起,如果为新的PVC动态调配PV,则该环路将时钟将该PV绑定到PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数据,一旦PV和PVC绑定后,PersistentVolumeClaim绑定是排他性的,不管他们是如何绑定的,PVC跟PV绑定是一对一的映射。

持久化卷声明的保护

        PVC保护的目的是确保由Pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失。

        当pod状态为pending并且pod已经分配给节点或pod为running状态时,PVC处于活动状态。

        当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何pod所使用。

PV的访问模式

每个pv都有一套自己的用来描述特定功能的访问模式

  1. ReadWriteOnce 该卷可以被单个节点以读写的模式挂载
  2. ReadOnlyMany 该卷可以被多个节点以只读模式挂载
  3. ReadWriteMany 该卷可以被多个节点以读写模式挂载

回收策略 persistentVolumeReclaimPolicy

  1. retain(保留) 手动回收
  2. Recycle (回收) 基本擦除 (rm -rf /volume/*)
  3. delete(删除) 关联的存储资产将被删除

pv卷支持的多种状态

  1. available 一块空闲资源还没有被任何声明绑定
  2. bound 卷已经被绑定了
  3. released 声明被删除,但是资源还未被集群重新声明
  4. failed 自动回收失败

原理图

 

示例:

远程的nfs已经创建完成,并且在k8s的node节点可以正常挂载。

vim pv-volume-demo.yaml 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv1
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce     # only one role can read or write
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs        
  nfs:
    path: /data/syn         # 远程nfs创建的目录
    server: 188.2.139.31    # 远程nfs的IP地址

创建PV

kubectl create -f pv-volume-demo.yaml 

删除PV时,在pod未占用PV的情况下,通过删除PVC可以自动删除PV,注意创建完成PV后,并不会自动创建PVC,只有创建pod时,k8s才会创建PVC绑定pod跟相关的PV

kubectl delete pvc --all

# 也可以指定PVC进行删除

kubectl get pvc

kubectl delete pvc [pvc-name]

查看:

[root@aa /home/k8s_config/volume/pv]# kubectl get pv -o wide     
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE     VOLUMEMODE
nfspv1   1Gi        RWO            Retain           Available           nfs                     4m10s   Filesystem
[root@aa /home/k8s_config/volume/pv]# kubectl describe pv nfspv1 
Name:            nfspv1
Labels:          <none>
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    nfs
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    188.2.139.31
    Path:      /data/syn
    ReadOnly:  false
Events:        <none>

创建一个StatefulSet

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]     # 前面创建的PV也要时rwo
      storageClassName: "nfs"            # 要与前面创建的PV保持一致
      resources:
        requests:
          storage: 1Gi

查看,发现第一个pod已经绑定了,第二个pod状态时pending,第三个pod还未创建,前一个pod运行成功后,才创建下一个pod。

可以创建多个PV来实现同类型的不同pod绑定。

 再创建两个PV,可以看到三个pod运行均正常了

 再查看PV,可以看到三个PV都绑定到对应的PVC上了

         注意:StatefulSet创建的pod删除后,k8s会自动重建,并且创建后的pod name不会变,但是cluster IP会变,并且保存在nfs存储中的文件并不会丢失。这是因为服务间是通过域名来通信的而非Pod IP,当Pod所在Node发生故障时,Pod会漂移到其他的Node上,Pod IP会发生变化,但是Pod域名不会发生变化。

想做上面的实现的话,执行下面的配置文件即可    

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      - image: busybox:latest
        name: busybox-empty-demo
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh","-c","sleep 6000s"]
        volumeMounts:
        - mountPath: /test          # cahnge mount dir
          name: www
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 1Gi

        删除Pod并不会删除其PVC,手动删除PVC将会自动释放PV。删除顺序是,删除StatefulSet-->删除PVC-->系统会自动释放PV。所有的资源需要手动删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值