前言
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。
首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。
其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。
一、emptyDir 存储卷
当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除。
emptyDir 可以实现pod中容器之间共享数据,但是存储卷不能持久化数据,且会随着pod 生命周结束而一起删除
示例:
apiVersion: v1
kind: Pod
metadata:
labels:
run: app-ng1
name: app-ng1
spec:
containers:
#第一个容器
- image: nginx:1.18
name: app-ng1
ports:
- containerPort: 80
volumeMounts: #定义容器挂载内容
- name: html #使用的存储卷名称,如果跟下面volume字段name值相同,
#则表示使用volume的这个存储卷
mountPath: /usr/share/nginx/html/ #挂载至容器中哪个目录
#第二个容器
- name: app-busy
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html ##在容器内定义挂载存储名称和挂载路径
mountPath: /data/
command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
#定义了容器启动时执行的命令,这里是每两秒向/data/index.html追加当前日期
volumes: #定义了Pod级别共享的存储卷
- name: html #卷名称
emptyDir: {} #定义存储卷类型
使用空目录卷(EmptyDir),这是一种临时存储,存储于节点本地,Pod中的所有容器都可以访问。
当Pod被重新调度到其他节点时,数据会丢失。
kubectl apply -f xxx.yaml
上面定义了2个容器,其中一个容器是输入日期到index.html中,然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。
二、hostPath 存储卷
hostPath卷将 node 节点的文件系统中的文件或目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失。
把Node节点上的目录/文件挂载到容器中,可实现持久化数据存储。但是存储空间会受到Node节点的单机限制,Node节点故障数据就会丢失,且Pod不能实现跨节点共享数据
示例:
//在 node01 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'hello node01' > /data/pod/volume1/index.html
//在 node02 节点上创建挂载目录
mkdir -p /data/pod/volume1
echo 'hello node02' > /data/pod/volume1/index.html
//创建 Pod 资源
apiVersion: v1
kind: Pod
metadata:
labels:
run: app-ng2
name: app-ng2
spec:
containers:
- image: nginx:1.18
name: app-ng2
ports:
- containerPort: 80
volumeMounts: #定义容器挂载内容
- name: html #使用的存储卷名称,如果跟下面volume字段name值相同,
#则表示使用volume的这个存储卷
mountPath: /usr/share/nginx/html/ #挂载至容器中哪个目录
readOnly: false #读写挂载方式,默认为读写模式false。可读可写
#volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷
volumes:
- name: html #存储卷名称
hostPath: #路径,为宿主机存储路径
path: /data/pod/volume1 #在宿主机上目录的路径
type: DirectoryOrCreate #定义类型,这表示如果宿主机没有此目录则会自动创建
kubectl apply -f xxx.yaml
与 node1 节点挂载目录的index,html内容一致
三、nfs 共享存储卷
使用nfs服务将共享存储设备空间挂载到容器中,可实现持久化数据存储,且Pod能实现跨节点共享数据
示例:
在一个新节点上安装nfs,并配置nfs服务
mkdir /data/volumes -p
#chmod 777 /data/volumes
vim /etc/exports
/data/volumes 192.168.80.0/24(rw,no_root_squash)
systemctl start rpcbind
systemctl start nfs
#exportfs -rv
hostnamectl set-hostname stor01
在所有node节点上添加域名解析
echo "192.168.80.16 stor01" >> /etc/hosts
master节点操作
apiVersion: v1
kind: Pod
metadata:
labels:
run: app-ng3
name: app-ng3
spec:
containers:
- image: nginx:1.18
name: app-ng3
ports:
- containerPort: 80
volumeMounts: #定义了容器内的挂载点
- name: html
mountPath: /usr/share/nginx/html/
#将名为html的卷挂载到容器内的/usr/share/nginx/html/路径
volumes: # 定义了一个名为html的卷,类型为NFS
- name: html
nfs:
path: /data/volumes #NFS服务器上的共享目录路径
server: stor01 #指定了NFS服务器的地址,可以是IP地址。
在nfs服务器上创建index.htm