目录
之前我们讲的configMap、Secret、Downward API都是将metadata元数据或配置数据注入到容器内部,那么对于我们的真实数据该用怎样的方式存储并让pod可见可用呢?
这就是数据持久化方案-Volume。
通过Volume卷的方式将外部存储挂载到我们的pod内部,pod可以对卷进行访问操作,完成数据的读取或写入等;同时在外部存储对文件的更新,同步在pod内部也可见。
存储卷是Kubernetes中的一个重要概念,它为容器提供了持久化存储或其他类型的存储的能力。Pod中的容器可以通过存储卷来访问文件系统,存储数据。存储卷的类型有很多,如emptyDir、hostPath、NFS等。这些存储卷类型都有其特定的用途和限制。
一、Volume-存在的意义
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在‘Pod’中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的‘Volume’抽象就很好的解决了这些问题。
目前官方给我们准备了可以直接使用的自带的卷方案:
csi:container storage interface。容器存储接口。它与awsElasticBlockStore和azureDisk不同,pod本身集成了csi,可以通过pod暴露csi接口,其他外部的文件系统,可以去对接csi接口,最终完成对接给到pod使用。
hostPath:hostPath类型的存储卷是指将工作节点上某文件系统的目录或文件挂载于Pod中的一种存储卷,它可独立于Pod资源的生命周期,因而具有持久性。但它是工作节点本地的存储空间,仅适用于特定情况下的存储卷使用需求,例如,将工作节点上的文件系统关联为Pod的存储卷,从而使得容器访问接待您文件系统上的数据。这一点在运行有管理任务的系统级Pod资源需要访问节点上的文件时比较有用。
当然如果工作节点挂载了外部文件系统,比如MFS文件系统,一种分布式文件存储系统,挂载到了本节点的/mfs目录,这个时候,Pod可再通过hostPath将/mfs绑定到Pod内部使用。
Volume存储卷的作用
1.数据持久化
当Pod中的容器因为各种原因(如升级、故障等)被销毁或重启时,存储在容器内的数据通常会丢失。通过使用存储卷,可以将数据存储在Pod生命周期之外的位置,确保数据即使在容器或Pod重启后仍然可用。
2.数据共享
存储卷允许多个容器在Pod内部共享数据。这对于需要共享配置、日志或其他数据的容器来说非常有用。通过挂载相同的存储卷,不同的容器可以访问并修改其中的数据。
3.解耦
通过将数据存储在存储卷中,而不是直接存储在容器内部,可以实现应用与数据之间的解耦。这意味着应用的代码和数据可以分开管理,从而简化应用的部署、升级和备份过程。
4.灵活性
Kubernetes支持多种类型的存储卷,包括emptyDir、hostPath、NFS等。这为用户提供了很大的灵活性,可以根据应用的需求选择最适合的存储解决方案。
5.其它的特性
安全性:通过使用只读存储卷,可以限制容器对数据的修改权限,从而提高数据的安全性。此外,一些存储卷类型(如加密云存储)还可以提供额外的数据保护功能。
可移植性:存储卷的使用使得应用在不同Kubernetes集群之间的迁移变得更加容易。只要目标集群支持相同的存储卷类型,并且已经配置了相应的存储资源,就可以轻松地将应用及其数据迁移到新的环境中。
日志和监控:存储卷可以用于存储应用的日志和监控数据。通过将日志和监控数据写入存储卷中,可以长期保存这些数据,并使用专门的日志和监控工具进行分析和警报。
二、Volume-emptyDir
1、概念
emptyDir卷的生命周期是跟着Pod关联的,跟Pod内部容器是不相关的,Pod删除的话emptyDir卷中数据被删除。
暂存空间:这个检查点具体怎么做,比如在Pod第一次启动的时候通过emptyDir卷中是否有一个标志文件,如果有表示是第一次启动的。如果没有这个文件的话,就代表之前Pod崩溃重启了导致了empthDir卷中的文件被删除,然后Pod重建之后,应用程序可以通过判断emptyDir卷中标志文件不存在了,应用程序就判定这次启动不是第一次启动了。通过这个区分,可以实现诸如存储数据的恢复等操作。
保存数据:这种方式在实际案例中用的挺多的。比如我们在将远程仓库git中的代码下载到本地pod中运行。可以通过emptyDir卷来实现。
2、emptyDir-Disk共享
我们接下来做个验证。具体如下:
我们创建一个pod,包括两个容器,两个容器分别都挂载基于emptyDir的卷。其中一个容器是nginx的,它用来提供访问服务,当被访问的时候,nginx会把访问日志记录在access.log文件里面,我们可以把它的目录映射到emptyDir卷里面,然后我们在另外一个容器busybox里面将emptyDir卷挂载到某一个目录下面,我们访问这个目录文件,看是否:当访问nginx服务后,在busybox容器的挂载目录文件里面是否可以实时看到访问日志。
注意:nginx里面的access.log文件存放需要看我们的容器里面nginx配置文件配置的路径在哪里,我的存放在:/var/log/nginx/access.log。有的nginx配置文件配置的是:/usr/local/nginx/logs/access.log。需要注意,不要弄错,否则会看不到日志。
1)创建pod
vim 1.pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-emptydir-disk-pod
namespace: default
spec:
containers:
- name: myapp
image: nginx:v1
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx #需要根据实际nginx配置文件中配置的日志存放路径而定。
- name: busybox
image: flyinlinux/tools:maqingpythonv1
command: ["/bin/sh","-c","touch /logs/access.log && tail -f /logs/access.log"]
volumeMounts:
- name: logs-volume
mountPath: /logs
volumes:
- name: logs-volume
emptyDir: {} #logs-volume这个卷是基于emptyDir而来,这个花括号必须要添加,里面为空表示以空的方式初始化
[root@k8s-master01 4.volume]# kubectl get pod
NAME READY STATUS RESTARTS AGE
cm-command-pod 0/1 Completed 0