kubernetes之volume卷

目录

 

1. volume

 1.1 名词解释

 1.2 volume的类型:

1.2.1 emptyDir

1.2.2 hostPath

1.2.3 nfs

1.2.4 configMap

1.2.5 persistentVolumeClaim

2. PV/PVC/StorageClass

2.1 名词解释

2.2 卷和声明的生命周期

2.3 示例

2.3.1 pv示例:

2.3.2 pvc示例:

2.3.3 pod使用pv、pvc示例:

2.4 StorageClass 

2.4.1 使用StorageClass 自动创建pv示例:

2.4.2 使用StorageClass 绑定自定义pv示例:


 

1. volume

 1.1 名词解释

       容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题,第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态,第二,当很多容器在同一Pod中运行的时候,很多时候需要数据文件的共享。Kubernete Volume解决了这个问题。

       Docker有一个Volumes的概念,虽然这个Volume有点宽松和管理性比较小。在Docker中,一个 Volume 是一个简单的所在主机的一个目录或者其它容器中的。生命周期是没有办法管理,直到最近才有 local-disk-backed 磁盘。Docker现在提供了磁盘驱动,但是功能非常有限(例如Docker1.7只能挂在一个磁盘每个容器,并且无法传递参数)

从另外一个方面讲,一个Kubernetes volume,拥有明确的生命周期,与所在的Pod的生命周期相同。因此,Kubernetes volume独立与任何容器,与Pod相关,所以数据在重启的过程中还会保留,当然,如果这个Pod被删除了,那么这些数据也会被删除。更重要的是,Kubernetes volume 支持多种类型,任何容器都可以使用多个Kubernetes volume。

它的核心,一个 volume 就是一个目录,可能包含一些数据,这些数据对pod中的所有容器都是可用的,这个目录怎么使用,什么类型,由什么组成都是由特殊的volume 类型决定的

想要使用一个volume,Pod必须指明Pod提供了那些磁盘,并且说明如何挂在到容器中

A process in a container sees a filesystem view composed from their Docker image and volumes. The Docker image is at the root of the filesystem hierarchy, and any volumes are mounted at the specified paths within the image. Volumes can not mount onto other volumes or have hard links to other volumes. Each container in the Pod must independently specify where to mount each volume.

容器中的一个进程看到文件系统由Docker镜像和磁盘构成,Docker镜像是文件系统的最底层,所有的磁盘都是挂在在这个镜像的特殊路径上。磁盘不能被挂在到被的磁盘或者创建硬链接。每个Pod中的容器必须是独立指定的取挂在这些磁盘

 1.2 volume的类型:

 折叠源码

1

2

3

4

5

6

7

8

9

10

11

12

emptyDir

hostPath

gcePersistentDisk

awsElasticBlockStore

nfs

iscsi

glusterfs

rbd

gitRepo

secret

persistentVolumeClaim

configMap

1.2.1 emptyDir

当 Pod 被分配给节点时,首先创建 emptyDir 卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir 中的数据将被永久删除。

注意:容器崩溃不会从节点中移除 pod,因此 emptyDir 卷中的数据在容器崩溃时是安全的。

emptyDir 的用法有:

  • 暂存空间,例如用于基于磁盘的合并排序
  • 用作长时间计算崩溃恢复时的检查点
  • Web服务器容器提供数据时,保存内容管理器容器提取的文件

示例1:

 折叠源码

apiVersion: v1

kind: Pod

metadata:

  name: mypod1

spec:

  containers:

  - name: nginx

    image: harbor.k2software.com.cn/library/nginx:alpine

    ports:

      - name: http

        containerPort: 80

        protocol: TCP

    volumeMounts:

    - name: cache-volume

      mountPath: /cache

  volumes:

  - name: cache-volume

    emptyDir: {}

示例2:

 折叠源码

apiVersion: v1

kind: Pod

metadata:

  name: mypod2

spec:

  containers:

  - name: nginx

    image: harbor.k2software.com.cn/library/nginx:alpine

    ports:

      - name: http

        containerPort: 80

        protocol: TCP

    volumeMounts:

    - name: html

      mountPath: /usr/share/nginx/html/

  - name: busybox

    image: harbor.dev.k2paas.com/library/busybox:1.25.0

    command:

      - "/bin/sh"

    args:

      - "-c"

      - "while true; do echo $(date) >> /data/index.html; sleep 2; done"

    volumeMounts:

    - name: html

      mountPath: /data/

  volumes:

  - name: html

    emptyDir: {}


1.2.2 hostPath

hostPath 卷将主机节点的文件系统中的文件或目录挂载到集群中。该功能大多数 Pod 都用不到,但它为某些应用程序提供了一个强大的解决方法。

例如,hostPath 的用途如下:

  • 运行需要访问 Docker 内部的容器;使用 /var/lib/docker 的 hostPath
  • 在容器中运行 cAdvisor;使用 /dev/cgroups 的 hostPath
  • 允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在

除了所需的 path 属性之外,用户还可以为 hostPath 卷指定 type。

type 字段支持以下值:

行为

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

当我们使用hostPath的时候要注意:

  • 由于每个节点上的文件都不同,具有相同配置(例如从 podTemplate 创建的)的 pod 在不同节点上的行为可能会有所不同
  • Kubernetes 规划一些资源相关的维护的时候,它不能根据此种类型的资源进行判断(这句没太看懂阿,这个应该得先要知道具体的维护类型才好….)

示例:

 折叠源码

apiVersion: v1

kind: Pod

metadata:

  name: mypod2

spec:

  containers:

  - name: nginx

    image: harbor.k2software.com.cn/library/nginx:alpine

    ports:

      - name: http

        containerPort: 80

        protocol: TCP

    volumeMounts:

    - name: time

      mountPath: /etc/localtime

  volumes:

  - name: time

    hostPath:

      path: /etc/localtime

 

1.2.3 nfs

直接使用共享存储

示例:

 折叠源码

apiVersion: v1

kind: Pod

metadata:

  name: mypod3

spec:

  containers:

  - name: nginx

    image: harbor.k2software.com.cn/library/nginx:alpine

    ports:

      - name: http

        containerPort: 80

        protocol: TCP

    volumeMounts:

    - name: nfs-nginx

      mountPath: /usr/share/nginx/html/

  volumes:

  - name: nfs-nginx

    nfs:

      path: /data/nfs1

      server: 172.18.10.61



1.2.4 configMap

将configMap的data里面的内容挂载到容器中

示例:

 折叠源码

apiVersion: v1

kind: Pod

metadata:

  name: mypod4

spec:

  containers:

  - name: nginx

    image: harbor.k2software.com.cn/library/nginx:alpine

    ports:

      - name: http

        containerPort: 80

        protocol: TCP

    volumeMounts:

    - name: kubeconfig

      mountPath: /etc/kubeconfig

  volumes:

  - name: kubeconfig

    configMap:

      name: kubeconfig


1.2.5 persistentVolumeClaim

persistentVolumeClaim 卷用于将 PersistentVolume 挂载到容器中。PersistentVolumes 是在用户不知道特定云环境的细节的情况下“声明”持久化存储(例如 GCE PersistentDisk 或 iSCSI 卷)的一种方式.

使用方法下面会说到。

 

2. PV/PVC/StorageClass

2.1 名词解释

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

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

     虽然 PersistentVolumeClaims 允许用户使用抽象存储资源,但用户需要具有不同性质(例如性能)的 PersistentVolume 来解决不同的问题。集群管理员需要能够提供各种各样的 PersistentVolume,这些PersistentVolume 的大小和访问模式可以各有不同,但不需要向用户公开实现这些卷的细节。对于这些需求,StorageClass 资源可以实现。

     StorageClass为管理员提供了一种描述他们提供的存储的“类”的方法。 不同的类可能映射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。 Kubernetes本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为“配置文件”.

 

2.2 卷和声明的生命周期

PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索赔检查。 PV和PVC之间的相互作用遵循这个生命周期:

Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling

Provisioning(配置)

这里有两种PV的提供方式: 静态或者动态

静态:

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

动态:

当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试动态地为 PVC 创建卷。此配置基于 StorageClasses:PVC 必须请求存储类,并且管理员必须创建并配置该类才能进行动态创建。声明该类为 "" 可以有效地禁用其动态配置。要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的 DefaultStorageClass 准入控制器。例如,通过确保 DefaultStorageClass 位于 API server 组件的 --admission-control 标志,使用逗号分隔的有序值列表中,可以完成此操作。有关 API server 命令行标志的更多信息,请检查 kube-apiserver 文档。

绑定

再动态配置的情况下,用户创建或已经创建了具有特定存储量的 PersistentVolumeClaim 以及某些访问模式。master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射。

如果没有匹配的卷,声明将无限期地保持未绑定状态。随着匹配卷的可用,声明将被绑定。例如,配置了许多 50Gi PV的集群将不会匹配请求 100Gi 的PVC。将100Gi PV 添加到群集时,可以绑定 PVC。

使用

Pod 使用声明作为卷。集群检查声明以查找绑定的卷并为集群挂载该卷。对于支持多种访问模式的卷,用户指定在使用声明作为容器中的卷时所需的模式。

用户进行了声明,并且该声明是绑定的,则只要用户需要,绑定的 PV 就属于该用户。用户通过在 Pod 的 volume 配置中包含 persistentVolumeClaim 来调度 Pod 并访问用户声明的 PV。

回收

用户用完 volume 后,可以从允许回收资源的 API 中删除 PVC 对象。PersistentVolume 的回收策略告诉集群在存储卷声明释放后应如何处理该卷。目前,volume 的处理策略有保留(Retain)、回收(Recycle)或删除(Delete)。

2.3 示例

2.3.1 pv示例:

 折叠源码

apiVersion: v1

kind: PersistentVolume

metadata:

  labels:

    name: mypv1

  name: mypv1

spec:

  accessModes:

  - ReadWriteOnce

  capacity:

    storage: 20Gi

  hostPath:

    path: /opt/nginx

    type: DirectoryOrCreate

  persistentVolumeReclaimPolicy: Recycle

2.3.2 pvc示例:

 折叠源码

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: mypvc1

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 8Gi

  selector:

    matchLabels:

      name: mypv1

  volumeName: mypv1

 

2.3.3 pod使用pv、pvc示例:

 折叠源码

apiVersion: apps/v1

kind: Deployment

metadata:

  name: mydeploy1

spec:

  selector:

    matchLabels:

      app: nginx1

  template:

    metadata:

      labels:

        app: nginx1

    spec:

      containers:

      - name: nginx

        image: harbor.k2software.com.cn/library/nginx:alpine

        ports:

          - name: http

            containerPort: 80

            protocol: TCP

        volumeMounts:

        - name: pvc-volume

          mountPath: /usr/share/nginx/html/

      volumes:

      - name: pvc-volume

        persistentVolumeClaim:

          claimName: nginx-pvc1

 

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: nginx-pvc1

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 8Gi

  volumeName: nginx-pv1

 

---

apiVersion: v1

kind: PersistentVolume

metadata:

  labels:

    name: nginx-pv1

  name: nginx-pv1

spec:

  accessModes:

  - ReadWriteOnce

  capacity:

    storage: 20Gi

  hostPath:

    path: /opt/nginx

    type: DirectoryOrCreate

  persistentVolumeReclaimPolicy: Recycle

 

2.4 StorageClass 

      声明可以通过使用属性 storageClassName 指定 StorageClass 的名称来请求特定的类。只有所请求的类与 PVC 具有相同 storageClassName 的 PV 才能绑定到 PVC。

PVC 不一定要请求类。其 storageClassName 设置为 "" 的 PVC 始终被解释为没有请求类的 PV,因此只能绑定到没有类的 PV(没有注解或 "")。没有 storageClassName 的 PVC 根据是否打开DefaultStorageClass 准入控制插件,集群对其进行不同处理。

  • 如果打开了准入控制插件,管理员可以指定一个默认的 StorageClass。所有没有 StorageClassName 的 PVC 将被绑定到该默认的 PV。通过在 StorageClass 对象中将注解 storageclassclass.ubernetes.io/is-default-class 设置为 “true” 来指定默认的 StorageClass。如果管理员没有指定缺省值,那么集群会响应 PVC 创建,就好像关闭了准入控制插件一样。如果指定了多个默认值,则准入控制插件将禁止所有 PVC 创建。
  • 如果准入控制插件被关闭,则没有默认 StorageClass 的概念。所有没有 storageClassName 的 PVC 只能绑定到没有类的 PV。在这种情况下,没有 storageClassName 的 PVC 的处理方式与 storageClassName 设置为 "" 的 PVC 的处理方式相同。

根据安装方法的不同,默认的 StorageClass 可以在安装过程中通过插件管理器部署到 Kubernetes 集群。

当 PVC 指定了 selector,除了请求一个 StorageClass 之外,这些需求被“与”在一起:只有被请求的类的 PV 具有和被请求的标签才可以被绑定到 PVC。

注意:目前,具有非空 selector 的 PVC 不能为其动态配置 PV。

过去,使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 属性。这个注解仍然有效,但是在未来的 Kubernetes 版本中不会支持。

创建StorageClass:

 折叠源码

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

  name: nfs-sc

provisioner: nfs-provisioner-01

reclaimPolicy: Delete

volumeBindingMode: Immediate

 

2.4.1 使用StorageClass 自动创建pv示例:

 折叠源码

apiVersion: apps/v1

kind: Deployment

metadata:

  name: mydeploy2

spec:

  selector:

    matchLabels:

      app: nginx2

  template:

    metadata:

      labels:

        app: nginx2

    spec:

      containers:

      - name: nginx

        image: harbor.k2software.com.cn/library/nginx:alpine

        ports:

          - name: http

            containerPort: 80

            protocol: TCP

        volumeMounts:

        - name: pvc-volume

          mountPath: /usr/share/nginx/html/

      volumes:

      - name: pvc-volume

        persistentVolumeClaim:

          claimName: nginx-pvc2

 

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: nginx-pvc2

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 8Gi

  storageClassName: nfs-sc

 

2.4.2 使用StorageClass 绑定自定义pv示例:

 折叠源码

apiVersion: apps/v1

kind: Deployment

metadata:

  name: mydeploy

spec:

  selector:

    matchLabels:

      app: nginx3

  template:

    metadata:

      labels:

        app: nginx3

    spec:

      containers:

      - name: nginx

        image: harbor.k2software.com.cn/library/nginx:alpine

        ports:

          - name: http

            containerPort: 80

            protocol: TCP

        volumeMounts:

        - name: pvc-volume

          mountPath: /usr/share/nginx/html/

      volumes:

      - name: pvc-volume

        persistentVolumeClaim:

          claimName: nginx-pvc3

 

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: nginx-pvc3

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 8Gi

  storageClassName: nfs-sc

 

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: nginx-pv3

  labels:

    name: nginx-pv3

spec:

  accessModes:

  - ReadWriteOnce

  capacity:

    storage: 8Gi

  nfs:

    path: /data/nfs1/nginx-pv3

    server: 172.18.10.61

  persistentVolumeReclaimPolicy: Delete

  storageClassName: nfs-sc

  volumeMode: Filesystem

 

 

参考文档:

  1.  https://www.kubernetes.org.cn/kubernetes-volumes
  2.  https://www.kubernetes.org.cn/pvpvcstorageclass
  3.  https://www.bookstack.cn/read/kubernetes-handbook/concepts-volume.md
  4.  https://www.bookstack.cn/read/kubernetes-handbook/concepts-persistent-volume.md
  5.  https://kubernetes.io/docs/concepts/storage/volumes/

你可能感兴趣的:(k8s)