1. 概述
Volumn定义在Pod上,然后被该Pod里面的多个容器挂载到具体的文件目录下。实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命周期不和Pod中的单个容器的生命周期有关。Volume的生命周期和Pod的生命周期关系需要根据储存类型来定
kubernetes支持的常见Volume类型如下:
- 基本存储:EmptyDir、HostPath、NFS
- 高级存储:PV、PVC
- 配置存储:ConfigMap、Secret
2. EmptyDir
2.1 概述
EmptyDir在Pod被分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为kubernetes会自动分配一个目录,当Pod销毁时,EmptyDir中的数据也会被永久删除
2.2 EmptyDir使用实战
- 先声明一个EmptyDir储存类型的volume
- 在一个Pod中准备两个容器nginx和busybox
- 将volume分别挂载到两个容器的目录中
- 然后nginx容器负责向volume中写日志,busybox中通过命令从volume读取日志文件内容到控制台
2.2.1 创建pod
新建volume-emptydir.yaml文件,内容如下。然后运行pod
[root@k8s-master ~]# cat volume-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-emptydir
namespace: dev
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
volumeMounts: # 将logs-volume挂载到nginx容器的/var/log/nginx目录, nginx会将用户的访问日志写入到该目录的access.log文件中
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
volumeMounts: # 将logs-volume挂载到busybox容器中的/logs目录
- name: logs-volume
mountPath: /logs
volumes: # 声明volume
- name: logs-volume
emptyDir: {}
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl apply -f volume-emptydir.yaml
pod/volume-emptydir created
[root@k8s-master ~]#
2.2.2 查看pod
[root@k8s-master ~]# kubectl get pod volume-emptydir -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-emptydir 2/2 Running 0 56s 10.244.169.181 k8s-node2 <none> <none>
[root@k8s-master ~]#
2.2.3 访问Pod中的Nginx:
[root@k8s-master ~]# curl 10.244.169.181
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master ~]#
2.3.4 查看busybox容器的标准输出
[root@k8s-master ~]# kubectl logs volume-emptydir -c busybox -f -n dev
10.244.235.192 - - [23/May/2022:08:04:45 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
3. HostPath
3.1 概述
HostPath就是将Node主机中的一个实际目录挂载到Pod中,以供容器使用。即使Pod销毁,数据依旧可以保存在Node主机上
3.2 HostPath使用实战
- 先声明一个HostPath储存类型的volume,数据储存在Node主机的目录中
- 在一个Pod中准备两个容器nginx和busybox
- 将volume分别挂载到两个容器的目录中
- 然后nginx容器负责向volume中写日志,busybox中通过命令从volume读取日志文件内容到控制台
3.2.1 创建pod
新建volume-hostpath.yaml文件,内容如下。然后运行pod
[root@k8s-master ~]# cat volume-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-hostpath
namespace: dev
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
volumeMounts: # 将logs-volume挂载到nginx容器的/var/log/nginx目录, nginx会将用户的访问日志写入到该目录的access.log文件中
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
volumeMounts: # 将logs-volume挂载到busybox容器中的/logs目录
- name: logs-volume
mountPath: /logs
volumes: # 声明volume
- name: logs-volume
hostPath:
path: /root/logs
type: DirectoryOrCreate
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl apply -f volume-hostpath.yaml
pod/volume-hostpath created
[root@k8s-master ~]#
type的值说明:
- DirectoryOrCreate:目录存在就使用,不存在就先创建
- Directory:目录必须存在
- FileOrCreate:文件存在就使用,不存在就先创建
- File:文件必须存在
- Socket:unix socket必须存在
- CharDevice:字符设备必须存在
- BlockDevice:块设备必须存在
3.2.2 查看pod
[root@k8s-master ~]# kubectl get pod volume-hostpath -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-hostpath 2/2 Running 0 2m47s 10.244.169.180 k8s-node2 <none> <none>
[root@k8s-master ~]#
3.2.3 访问Pod中的Nginx:
[root@k8s-master ~]# curl 10.244.169.180
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master ~]#
3.3.4 查看Pod所在node节点的日志
[root@k8s-node2 ~]# ll logs/
总用量 8
-rw-r--r--. 1 root root 95 5月 23 16:24 access.log
-rw-r--r--. 1 root root 510 5月 23 16:20 error.log
[root@k8s-node2 ~]#
如果在此目录中创建文件,到容器中也是可以看到的
4. NFS
4.1 概述
HostPath虽然可以解决数据持久化的问题,但是一旦Node节点故障了,Pod如果转移到别的Node节点上,又会出现问题。此时需要准备单独的网络存储系统,比较常用的是NFS和CIFS
NFS是一个网络文件存储系统,可以搭建NFS服务器,然后将Pod中的存储直接连接到NFS系统上。无论Pod在节点上怎么转移,只要Node和NFS的对接没有问题,数据就可以成功访问
4.2 搭建NFS服务器
生产环境可以使用nfs + keepalived做高可用防止单点故障,rsync + inotify实现主备间共享数据同步
我们这里测试环境只搭建一台NFS服务器
- 安装NFS服务(客户端只需安装NFS服务即可,用于客户端驱动NFS设备)
[root@nfs ~]# yum install -y nfs-utils
- 准备共享目录
[root@nfs ~]# mkdir -p /root/data/nfs
- 将共享目录以读写权限暴露给192.168.23.0/24网段中的所有主机
[root@nfs ~]# cat /etc/exports
/root/data/nfs 192.168.23.0/24(rw,no_root_squash)
[root@nfs ~]#
其中no_root_squash表示:NFS客户端连接服务端时如果使用的是root的话,那么对服务端共享目录也拥有root权限
- 启动NFS服务
[root@nfs ~]# systemctl start nfs
4.3 NFS使用实战
- 先声明一个NFS储存类型的volume,数据储存在远程主机的目录中
- 在一个Pod中准备两个容器nginx和busybox
- 将volume分别挂载到两个容器的目录中
- 然后nginx容器负责向volume中写日志,busybox中通过命令从volume读取日志文件内容到控制台
4.3.1 创建pod
新建volume-nfs.yaml文件,内容如下。然后运行pod
[root@k8s-master ~]# cat volume-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: volume-nfs
namespace: dev
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
volumeMounts: # 将logs-volume挂载到nginx容器的/var/log/nginx目录, nginx会将用户的访问日志写入到该目录的access.log文件中
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
volumeMounts: # 将logs-volume挂载到busybox容器中的/logs目录
- name: logs-volume
mountPath: /logs
volumes: # 声明volume
- name: logs-volume
nfs:
server: 192.168.23.31 # NFS服务器地址
path: /root/data/nfs # NFS服务器的共享目录
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl apply -f volume-hostpath.yaml
pod/volume-nfs created
[root@k8s-master ~]#
4.3.2 查看pod
[root@k8s-master ~]# kubectl get pod volume-nfs -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-nfs 2/2 Running 0 65s 10.244.169.182 k8s-node2 <none> <none>
[root@k8s-master ~]#
4.3.3 访问Pod中的Nginx:
[root@k8s-master ~]# curl 10.244.169.182
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@k8s-master ~]#
4.3.4 查看NFS远程主机的目录
[root@nfs ~]# ll data/nfs
总用量 8
-rw-r--r--. 1 root root 95 5月 23 17:09 access.log
-rw-r--r--. 1 root root 510 5月 23 17:08 error.log
[root@nfs ~]#
如果在此目录中创建文件,到容器中也是可以看到的