Kubernetes数据持久化

在k8s中,Volume(数据卷)存在明确的生命周期(与包含该数据卷的容器组(pod)相同)。因此Volume的生命周期比同一容器组(pod)中任意容器的生命周期要更长,不管容器重启了多少次,数据都被保留下来。当然,如果pod不存在了,数据卷自然退出了。此时,根据pod所使用的数据卷类型不同,数据可能随着数据卷的退出而删除,也可能被真正持久化,并在下次容器组重启时仍然可以使用。

从根本上来说,一个数据卷仅仅是一个可以被pod访问的目录或文件。这个目录是怎么来的,取决于该数据卷的类型(不同类型的数据卷使用不同的存储介质)。同一个pod中的两个容器可以将一个数据卷挂载到不同的目录下。

k8s数据卷主要解决了以下两方面问题:

  1. 数据持久性:通常情况下,容器运行起来后,写入到其文件系统的文件时暂时性的。当容器崩溃后,kebelet将这个容器kill掉,然后生成一个新的容器,此时,新运行的容器将没有原来容器内的文件,因为容器是重新从镜像创建的。
  2. 数据共享:同一个pod中运行的容器之间,经常会存在共享文件/文件夹的需求。

一、数据卷类型

k8s目前支持28种数据卷类型(其中大多数特定于云环境),这里将写下在k8s中常用的几种数据卷类型。

1、emptyDir
emptyDir类型的数据卷在创建pod时分配给该pod,并且直到pod被移除,该数据卷才被释放。该数据卷初始分配时,始终是一个空目录。同一个pod中的不同容器都可以对该目录执行读写操作,并且共享其中的数据(尽管不同容器可能将该数据卷挂载到容器中的不同路径)。当pod被删除后,emptyDir数据卷中的数据将被永久删除。(PS:容器奔溃时,kubelet并不会删除pod,而仅仅是将容器重启,因此emptyDir中的数据在容器崩溃并重启后,仍然是存在的)。
emptyDir的使用场景如下:

空白的初始空间,例如合并/排序算法中,临时将数据保存在磁盘上。
长时间计算中存储检查点(中间结果),以便容器崩溃时,可以从上一次存储的检查点(中间结果)继续进行,而不是从头开始。
作为两个容器的共享存储,使得第一个内容管理的容器可以将生成的数据存入其中,同时由一个webserver容器对外提供这些页面。
默认情况下,emptyDir数据卷存储在node节点的存储介质(机械硬盘、SSD或网络存储)上。

emptyDir的使用示例

[root@master ~]# vim emtydir.yaml     #pod的yaml文件如下

apiVersion: v1
kind: Pod
metadata:
  name: read-write
spec:
  containers:
  - name: write         #定义一个名为write的容器
    image: busybox
    volumeMounts:
    - mountPath: /write    #当数据持久化类型为emtydir时,这里的路径指的是容器内的路径
      name: share-volume     #指定本地的目录名
    args:        #容器运行后,进行写操作
    - /bin/sh
    - -c
    - echo "emtydir test" > /write/hello;sleep 30000

  - name: read           #定义一个名为read的容器
    image: busybox
    volumeMounts:
    - mountPath: /read
      name: share-volume      #指定本地的目录名
    args:                #容器运行后,进行读操作
    - /bin/sh
    - -c
    - cat /read/hello; sleep 30000
  volumes:               #这里的volumes是指对上面挂载的进行解释
  - name: share-volume    #这里的名字必须和上面pod的mountPath下的name值对应
    emptyDir: {}            #这里表示是个空目录,主要是定义了一个数据持久化的类型
[root@master ~]# kubectl apply -f emtydir.yaml    #执行yaml文件
[root@master ~]# kubectl exec -it read-write -c write /bin/sh  #进入第一个pod
/ # cat /write/hello        #确认yaml文件执行的命令是否生效
emtydir test

[root@master ~]# kubectl exec -it read-write -c read /bin/sh  #进入第二个容器名为read的容器查看
/ # cat /read/hello        #查看指定挂载的目录下是否和write容器中的内容一致
emtydir test
#至此,起码可以确认这两个pod是挂载了同一个本地目录,文件内容都一致。
#那么,现在看看具体挂载的是本地哪个目录?
[root@master ~]# kubectl get pod -o wide    #先通过此命令查看pod是运行在哪个节点上的
#我这里是运行在node01节点的,所以接下来需要到node01节点上进行查看

#node01节点操作如下:
[root@node01 ~]# docker ps             #通过此命令查看出运行的容器ID号
CONTAINER ID        IMAGE              #省略部分内容
6186a08c6d5f        busybox              
5f19986f0879        busybox             
[root@node01 ~]# docker inspect 6186a08c6d5f      #查看第一个容器的详细信息
 "Mounts": [          #找到mount字段
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/86b67ff4-9ca0-4f40-86d8-6778cfe949ec/volumes/kubernetes.io~empty-dir/share-volume",
#上面的source就是指定的本地目录
                "Destination": "/read",
                "Mode": "

你可能感兴趣的:(kubernetes(k8s),emptyDir,HostPath,pv,pvc,kubernetes)