返回 导航

Docker / K8s

hangge.com

K8s - Kubernetes使用详解8(使用Volume存储实现数据持久化)

作者:hangge | 2019-08-06 08:10
    我们知道容器和 Pod 的生命周期可能很短,会被频繁地销毁和创建。当容器销毁时,保存在容器内部文件系统中的数据都会被清除。为了持久化保存容器的数据,我们可以使用 Kubernetes Volume 
    除此之外,有一些场景可能一个 pod 里面的多个容器需要共享数据。同样可以借助 Volume 来实现。

八、Volume 存储

1,什么是 Volume?

(1)Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。
(2)本质上,Kubernetes Volume 是一个目录,这一点与 Docker Volume 类似。当 VolumemountPodPod 中的所有容器都可以访问这个 Volume
(3)Volume 也支持多种 mount 类型,包括: emptyDirhostPathGCE Persistent DiskAWS Elastic Block StoreNFSCeph 等。

2,emptyDir

(1)基本介绍

(2)emptyDir 常用于一个 pod 内多个容器共享临时数据(如日志收集),首先我创建 app.yml 文件,内容如下:
(1)该 pod 中有两个容器:
  • app 容器:模拟实际场景中的应用,负责把日志写到日志文件中。
  • log-collector 容器:模拟实际场景中的日志收集,负责从日志文件中读取日志。
(2)文件最底部 volumes 定义了一个 emptyDir 类型的 Volume shared-dirapp log-collector 都是共享这个 Volume
apiVersion: v1
kind: Pod
metadata:
  name: emptydir-test
spec:
  containers:
  - image: busybox
    name: app
    volumeMounts:
    - mountPath: /logs # 将 shared-dir mount 到 /logs 目录。
      name: shared-dir 
    args:
    - /bin/sh
    - -c
    - echo `date '+%H:%M:%S'` >> /logs/app.log; sleep 60 #通过echo将数据写到文件app.log里(60秒一次)
  - image: busybox
    name: log-collector
    volumeMounts:
    - mountPath: /app_logs # 将 shared-dir mount 到 /app_logs 目录。
      name: shared-dir
    args:
    - /bin/sh
    - -c
    - cat /app_logs/app.log; sleep 60 # 通过cat从文件app.log读数据(60秒一次)
  volumes:
  - name: shared-dir #定义了一个 emptyDir 类型的 Volume shared-dir
    emptyDir: {} 

(3)接着执行如下命令创建 pod
kubectl apply -f app.yml

(4)过个几分钟,通过 kubectl logs 命令查看 log-collector 容器日志,可以发现该容器成功读到了 app 写入的数据,验证了两个容器共享 emptyDir Volume
kubectl logs emptydir-test log-collector

(5)通过 docker inspect 查看容器的详细配置信息,我们发现两个容器都 mount 了同一个目录:
因为 emptyDir Docker Host 文件系统里的目录,其效果相当于执行了 docker run -v /logs docker run -v /app_logs


(6)由于 emptyDirHost 上创建的临时目录,它不具备持久性。如果 Pod 不存在了,emptyDir 也就没有了。下面我们把 pod 删除再重新创建,可以发现前的数据已经被清除了。
kubectl delete -f app.yml
kubectl apply -f app.yml
kubectl logs emptydir-test log-collector

3,hostPath

(1)基本介绍
  • hostPath 类型的 volume,是将主机上的目录 mountpod 的容器。
  • emptyDir 不同的是,即使 pod 被销毁了,hostPath 对应的目录数据也还会被保留。
注意:大部分应用都不会使用 hostPath Volume,因为这实际上增加了 Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问 KubernetesDocker 内部数据(配置文件和二进制库)的应用则需要使用 hostPath

(2)这里我们同样以前面的日志写入、读取为例。只不过这次我们不再使用临时目录作为共享目录,而是用用主机上 /mylogs 这个目录。
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-test
spec:
  containers:
  - image: busybox
    name: app
    volumeMounts:
    - mountPath: /logs
      name: shared-dir 
    args:
    - /bin/sh
    - -c
    - echo `date '+%H:%M:%S'` >> /logs/app.log; sleep 60
  - image: busybox
    name: log-collector
    volumeMounts:
    - mountPath: /app_logs
      name: shared-dir
    args:
    - /bin/sh
    - -c
    - cat /app_logs/app.log; sleep 60
  volumes:
  - name: shared-dir
    hostPath:
      path: /mylogs

(3)创建 pod 后可以看到 /mylogs 这个目录下确实已经生成了日志文件:

4,NFS

(1)我们也可以 mount 一个NFS(网络数据卷)类型的 volume。即允许一块现有的网络硬盘在同一个 pod 内的容器间共享。
(2)还是以上面的日志写入、读取为例。只不过这次我们使用 NFS 目录作为为共享目录。
apiVersion: v1
kind: Pod
metadata:
  name: nft-test
spec:
  containers:
  - image: busybox
    name: app
    volumeMounts:
    - mountPath: /logs
      name: shared-dir 
    args:
    - /bin/sh
    - -c
    - echo `date '+%H:%M:%S'` >> /logs/app.log; sleep 60
  - image: busybox
    name: log-collector
    volumeMounts:
    - mountPath: /app_logs
      name: shared-dir
    args:
    - /bin/sh
    - -c
    - cat /app_logs/app.log; sleep 60
  volumes:
  - name: shared-dir
    nfs:
     server: 192.168.20.47
     path: "/data/disk1"

5,外部存储

(1)如果 Kubernetes 部署在诸如 AWSGCEAzure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子:
要在 Pod 中使用 ESB volume,必须先在 AWS 中创建,然后通过 volume-id 引用。其他云硬盘的使用方法可参考各公有云厂商的官方文档。

(2)Kubernetes Volume 也可以使用主流的分布式存,比如 CephGlusterFS 等。下面是一个 Ceph 例子:将 Ceph 文件系统的 /some/path/in/side/cephfs 目录被 mount 到容器路径 /test-ceph
评论

全部评论(0)

回到顶部