Skip to content

1. 存储卷基础

1.1 为何需要Volumes

Container中的⽂件在磁盘上是临时存放的,这给Container中运⾏的较重要的应⽤程序带来⼀些问题。

1、当容器崩溃时,kubelet将重新启动⼀个"全新的容器",⽽容器中的此前保存的数据则会丢失。

2、当同⼀Pod运⾏多个容器时,通常需要在这些容器之间共享⽂件。

Volume 是 Kubernetes 抽象出来的对象,主要⽤于解决Pod运⾏时⽂件存放的问题,以及pod中多容器数据共享问题。

1.2 什么是Volume

Volume的核心是一个目录,其中可能存有数据,Pod中的容器可以访问该目录中的数据。使用不同的Volume类型将决定该目录如何形成,以及使用何种介质(Disk、Memory)来存储数据。当然不同的卷类型有着不同的生命周期;

临时卷:临时卷类型的生命周期与Pod 相同,当Pod 不再存在时,Kubernetes 会销毁临时卷; (一般用作缓存场景)

持久卷:持久卷可以比 Pod 的存活期长,因为Kubernetes不会销毁持久卷。

💡 说明

任何类型的卷,在容器重启期间数据都不会丢失

1.3 Volume的功能

1.Volume是Pod中能够被多个容器访问的共享目录,可以让容器的数据写到宿主机上或者写文件到网络存储中

2.可以实现容器配置文件集中化定义与管理,通过ConfigMap资源对象来实现.

1.4 Volume的特点

k8s中的Volume与Docker的Volume相似,但不完全相同。

  1. k8s上Volume定义在Pod上,然后被一个Pod中的多个容器挂载到具体的文件目录下。
  2. k8s的Volume与Pod生命周期相关而不是容器是生命周期,即容器挂掉,数据不会丢失但是Pod挂掉,数据则会丢失。
  3. k8s中的Volume支持多种类型的Volume:Ceph、GlusterFS等分布式系统

1.5 Pod配置Volume

Pod使⽤卷方式:

1、第⼀步:在pod.spec.volumes 字段中申明,申明该卷提供的卷类型以及卷名字

2、第二步:在.spec.containers[*].voLumeMounts字段中声明,将卷挂载到容器的哪个位置。

image-20240531102533666

2. Volume类型

先在Pod上声明一个Volume,然后容器引用该Volume并Mount到容器的某个目录

2.1 临时存储

官方文档,https://kubernetes.io/docs/concepts/storage/volumes/#emptydir

emptyDir定义

emptyDir是一个临时存储卷,与Pod的生命周期绑定到一起,如果Pod被删除了,这意味着数据也被随之删除.

emptyDir主要有如下两个字段

  • medium:存储介质的类型,有defaut、Memory,
    • default:表示使用节点的磁盘存储介质。 (默认)
    • Memory:表示使用基于内存临时文件系统,性能高、但整体可用空间受限于内存,一般用于缓存场景。
  • sizeLimit:存储卷的空间限额,默认nil表示不限制,如果medium为Memory时,建议配置此值。

emptyDir作用

(1)可以实现持久化;

(2)同一个Pod的多个容器可以实现数据共享,多个不同的Pod之间不能进行数据通信;

(3)随着Pod的生命周期而存在,当我们删除Pod时,其数据也会被随之删除;

emptyDir优缺点

优点:

(1)可以实现同一个Pod内多个容器之间数据共享;

(2)当Pod内的某个容器被强制删除时,数据并不会丢失,因为Pod没有删除;

缺点:

(1)当Pod被删除时,数据也会被随之删除;

(2)不同的Pod之间无法实现数据共享;

❌ 注意

启动pods后,使用emptyDir其数据存储在"/var/lib/kubelet/pods"路径下对应的POD_ID目录

如,/var/lib/kubelet/pods/${POD_ID}/volumes/kubernetes.io~empty-dir/

emptyDir场景1

yaml
[root@kube-master volumes]# cat 1.nginx-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  volumes:
  - name: my-volume
    emptyDir:
      medium: Memory
      sizeLimit: "1Gi"

  containers:
  - name: volume-container
    image: nginx:latest
    volumeMounts:
    - name: my-volume
      mountPath: /usr/share/nginx/html

  initContainers:
    - name: init-container
      image: busybox
      command: ["sh", "-c", "echo '<html><body><h1>Welcome to my website</h1></body></html>' > /data/index.html"]
      volumeMounts:
      - name: my-volume
        mountPath: /data
[root@kube-master volumes]# cat 1.nginx-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  volumes:
  - name: my-volume
    emptyDir:
      medium: Memory
      sizeLimit: "1Gi"

  containers:
  - name: volume-container
    image: nginx:latest
    volumeMounts:
    - name: my-volume
      mountPath: /usr/share/nginx/html

  initContainers:
    - name: init-container
      image: busybox
      command: ["sh", "-c", "echo '<html><body><h1>Welcome to my website</h1></body></html>' > /data/index.html"]
      volumeMounts:
      - name: my-volume
        mountPath: /data

emptyDir场景2

yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

2.2 本地存储

官方文档,https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

hostPath

会将Pod部署所在宿主机的目录或文件挂载到Pod中去

作用

  1. 容器应用日志需要持久化时,可以使用宿主机的高速文件系统进行存储
  2. 需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统
  3. 挂载时区

1.在不同的Node上具有相同配置的Pod可能会因为宿主机上的目录或文件不同导致对Volume上目录或文件的访问结果不一致。

2.如果使用了资源配额管理,则kubernetes无法将hostPath在宿主机上使用的资源纳入管理

案例

yaml
[root@kube-master volumes]# cat 2.hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
spec:
  volumes:
  - name: hostpath-volume
    hostPath:
      path: /data/hostpathdir/    # 宿主上⽬录位置
      type: Directory
  containers:
  - name: container-hostpath
    image: nginx:latest
    volumeMounts:
    - name: hostpath-volume
      mountPath: /usr/share/nginx/html/
[root@kube-master volumes]# cat 2.hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath
spec:
  volumes:
  - name: hostpath-volume
    hostPath:
      path: /data/hostpathdir/    # 宿主上⽬录位置
      type: Directory
  containers:
  - name: container-hostpath
    image: nginx:latest
    volumeMounts:
    - name: hostpath-volume
      mountPath: /usr/share/nginx/html/

2.4 gcePersistentDisk

表示使用谷歌公有云提供的永久磁盘(Persistent Disk ,PD)存放Volume的数据,它与EmptyDir不同,PD上的内容会被永久保存。当Pod被删除时,PD只是被卸载时,但不会被删除。需要先创建一个永久磁盘,才能使用gcePersistentDisk。

使用gcePersistentDisk的限制条件:

  • Node(运行kubelet的节点)需要是GCE虚拟机。
  • 虚拟机需要与PD存在于相同的GCE项目中和Zone中