目录
?
在此前我们所看到的service、pod等的演示实验中的其资源经常被删除重建,数据经常清除,那么我们需要一个东西去解决持久化保存容器数据的问题。
Volume创建出来是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下,k8s通过Volume实现在同一个Pod中不同容器之间的数据共享以及数据的持久化存储。
pod中容器的生命状态和volume数据保持独立,这篇文章先主要介绍emptydir、hostpath、nfs三种基本存储类型,当然基本存储类型不止这三种。
(1)emptydir是volume中最基础的类型,表示一个空目录,在关联的pod被删除后,emptydir也跟着被删除了(永久)。
(2)当使用EmptyDir类型的volume时,工作区域是在pod内,Kubernetes会为每个Pod创建一个空目录,并将该目录挂载到Pod的每个容器中。这意味着所有在同一Pod中运行的容器都可以访问该卷,并在其中读取和写入数据。
(3)像下面这个两个容器共享目录的例子或者那种不需要永久存储数据的环境下可以使用。
如下,创建一个关于nginx和busybox的pod,指定volumes类型为emptydir,并进行访问测试,手动将获取的日志文件拷贝到主机
[root@k8s-master volume]# cat testemptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-emptydir
namespace: myns
spec:
containers:
- name: nginx ? #nginx分配来产生日志
? image: nginx
? ports:
? - name: nginx-port
? ? containerPort: 80
? volumeMounts:
? - name: myvolume ? ?
? #将名为myvolume的volume挂载到/var/log/nginx
? ? mountPath: /var/log/nginx
- name: busybox ? #busybox分配来输出日志
? image: busybox
? command: ["/bin/sh","-c","tail -f /logs/access.log"] ? ?
? #持续监控访问日志情况,因为已经挂载到一起,所以应该是挂载后的/logs/access.log
? volumeMounts:
? - name: myvolume ?
? #将名为myvolume的volume挂载到/logs,这样在busybox容器中的/logs下就可以看到/var/log/nginx下的日志文件
? ? mountPath: /logs
volumes:
- name: myvolume ? #指定volume名称
? emptyDir: {} ? #指定volume类型
?
[root@k8s-master volume]# kubectl apply -f testemptydir.yaml
pod/my-nginx-emptydir created
?
[root@k8s-master volume]# kubectl get pods -n myns -o wide ? #在集群其他节点访问几次podIP,
NAME ? ? ? ? ? ? ? READY ? STATUS ? RESTARTS ? AGE ? IP ? ? ? ? ? ? NODE ? ? ? NOMINATED NODE ? READINESS GATES
my-nginx-emptydir ? 2/2 ? ? Running ? 0 ? ? ? ? 80s ? 10.244.36.65 ? k8s-node1 ? <none> ? ? ? ? ? <none>
?
[root@k8s-master volume]# kubectl logs -f my-nginx-emptydir -n myns -c busybox
#通过logs命令来观测busybox日志变化
#-f持续监控变化,-c指定容器名称
192.168.2.151 - - [12/Dec/2023:13:47:31 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.169.128 - - [12/Dec/2023:13:47:38 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [12/Dec/2023:13:48:14 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [12/Dec/2023:13:48:15 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
?
[root@k8s-master volume]# kubectl cp my-nginx-emptydir:logs/access.log -n myns -c busybox /root/volume/access1
#可以使用cp命令将容器内挂载的日志文件拷贝到主机,如上
[root@k8s-master volume]# ll
total 8
-rw-r--r-- 1 root root 377 Dec 12 22:06 access1
-rw-r--r-- 1 root root 464 Dec 12 21:44 testemptydir.yaml
[root@k8s-master volume]# cat access1
192.168.2.151 - - [12/Dec/2023:13:47:31 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.169.128 - - [12/Dec/2023:13:47:38 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [12/Dec/2023:13:48:14 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [12/Dec/2023:13:48:15 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
(1)hostpath是将node上实际目录挂载到pod中提供给容器使用,工作区域是在node上,pod丢失但数据还在主机上,就可以解决emptydir中pod和数据一起被销毁的问题。
(2)同时在容器中的挂载的目录和主机上的这个实际目录是同步的。
DirectoryOrCreate:目录存在就使用,不存在就先创建后使用
FileOrCreate:文件存在就使用,不存在就先创建后使用
Directory:目录必须存在,否则运行不成功
File:文件必须存在,否则运行不成功
Socket:unix套接字必须存在,否则运行不成功
CharDevice:字符设备必须存在,否则运行不成功
BlockDevice:块设备必须存在,否则运行不成功
如下,创建了一个关于nginx和busybox的pod,指定运行在node1(我已经label该node的标签为“name=node1”),将共享目录内的日志文件同步到运行pod的主机上
[root@k8s-master volume]# cat testemptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-hostpath
namespace: myns
spec:
nodeSelector:
? name: node1
containers:
- name: nginx
? image: nginx
? ports:
? - name: nginx-port
? ? containerPort: 80
? volumeMounts:
? - name: myvolume
? ? mountPath: /var/log/nginx
- name: busybox
? image: busybox
? command: ["/bin/sh","-c","tail -f /logs/access.log"]
? volumeMounts:
? - name: myvolume
? ? mountPath: /logs
volumes:
- name: myvolume
? hostPath:
? ? path: /root/volumes/logs
? ? type: DirectoryOrCreate ? #使用DirectoryOrCreate类型
?
[root@k8s-master volume]# kubectl get pods -n myns -o wide
NAME ? ? ? ? ? ? ? READY ? STATUS ? RESTARTS ? AGE ? IP ? ? ? ? ? ? NODE ? ? ? NOMINATED NODE ? READINESS GATES
my-nginx-hostpath ? 2/2 ? ? Running ? 0 ? ? ? ? 57s ? 10.244.36.66 ? k8s-node1 ? <none> ? ? ? ? ? <none>
?
[root@k8s-master volume]# kubectl logs -f my-nginx-hostpath -c busybox -n myns #在node1上curl后查看pod日志
192.168.2.151 - - [13/Dec/2023:12:52:06 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [13/Dec/2023:12:52:35 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [13/Dec/2023:12:52:36 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
?
[root@k8s-node1 ~]# ls /root/volumes/logs/ ? #我本没有此目录,查看是否新建了该目录
access.log error.log
?
在主机的实际目录中新建文件,查看容器中是否新建
[root@k8s-node1 ~]# cat /root/volumes/logs/access.log ? #如下是目录文件同步情况测试,正常
192.168.2.151 - - [13/Dec/2023:12:52:06 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [13/Dec/2023:12:52:35 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [13/Dec/2023:12:52:36 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
[root@k8s-master volume]# kubectl exec my-nginx-hostpath -it -c busybox -n myns -- /bin/sh -c "ls /logs"
access.log error.log
[root@k8s-node1 logs]# touch su.txt
[root@k8s-master volume]# kubectl exec my-nginx-hostpath -it -c busybox -n myns -- /bin/sh -c "ls /logs"
access.log error.log ? su.txt
[root@k8s-node1 logs]# pwd
/root/volumes/logs
[root@k8s-node1 logs]# ll
total 8
-rw-r--r-- 1 root root 282 Dec 13 20:52 access.log
-rw-r--r-- 1 root root 2555 Dec 13 22:00 error.log
-rw-r--r-- 1 root root ? 0 Dec 13 20:55 su.txt
(1)NFS作为一个网络文件系统,将pod中存储的数据存储连接到nfs系统,在nfs和主机的关联性不故障情况下数据就不会丢失
(2)工作在运行pod的node之外,需要这个pod和node上的nfs有关联。顺利解决hostpath存储类型node故障时数据异常的问题
如上创建了一个关于nginx和busybox的pod,指定volumes类型为nfs,在所有节点上安装了nfs-utils(没有部署ansible的可以手动下载nfs),且在master节点上把实际目录共享了出来
[root@k8s-master volume]# cat testemptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-nfs
namespace: myns
spec:
containers:
- name: nginx
? image: nginx
? ports:
? - name: nginx-port
? ? containerPort: 80
? volumeMounts:
? - name: myvolume
? ? mountPath: /var/log/nginx
- name: busybox
? image: busybox
? command: ["/bin/sh","-c","tail -f /logs/access.log"]
? volumeMounts:
? - name: myvolume
? ? mountPath: /logs
volumes:
- name: myvolume
? nfs:
? ? server: 192.168.2.150 ? #指定nfs服务器的IP地址,在/etc/hosts做了host解析的可以直接写主机名
? ? path: /root/volume/share ? #nfs服务器上共享出来的目录
?
[root@k8s-master volume]# yum install -y nfs-utils
[root@k8s-master volume]# ansible all -m yum -a "name=nfs-utils" ? #所有节点安装nfs-utils
k8s-node2 | SUCCESS => {
? "ansible_facts": {
? ? ? "discovered_interpreter_python": "/usr/bin/python"
? },
? "changed": false,
? "msg": "",
? "rc": 0,
? "results": [
? ? ? "1:nfs-utils-1.3.0-0.68.el7.2.x86_64 providing nfs-utils is already installed"
? ]
}
k8s-node1 | SUCCESS => {
? "ansible_facts": {
? ? ? "discovered_interpreter_python": "/usr/bin/python"
? },
? "changed": false,
? "msg": "",
? "rc": 0,
? "results": [
? ? ? "1:nfs-utils-1.3.0-0.68.el7.2.x86_64 providing nfs-utils is already installed"
? ]
}
?
[root@k8s-master volume]# mkdir share ? #在当前路径下创建一个共享目录
[root@k8s-master volume]# vim /etc/exports ? #编辑/etc/exports文件,允许网段内主机进行访问
/root/volume/share 192.168.2.0/24(rw,no_root_squash)
[root@k8s-master volume]# systemctl start nfs
[root@k8s-master volume]# systemctl enable nfs
?
?
[root@k8s-master volume]# kubectl get pods -n myns -o wide ? #到node2上测试后查看pod日志
NAME ? ? ? ? ? READY ? STATUS ? RESTARTS ? AGE ? IP ? ? ? ? ? ? ? NODE ? ? ? NOMINATED NODE ? READINESS GATES
my-nginx-nfs ? 2/2 ? ? Running ? 0 ? ? ? ? 8s ? 10.244.169.131 ? k8s-node2 ? <none> ? ? ? ? ? <none>
?
[root@k8s-master volume]# kubectl logs -f my-nginx-nfs -c busybox -n myns
192.168.2.152 - - [13/Dec/2023:13:40:08 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.152 - - [13/Dec/2023:13:40:10 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.152 - - [13/Dec/2023:13:40:11 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
?
[root@k8s-master volume]# ll share/ ? #查看当前该目录下已经有文件
total 8
-rw-r--r-- 1 root root 282 Dec 13 21:40 access.log
-rw-r--r-- 1 root root 618 Dec 13 21:39 error.log
[root@k8s-master volume]# cat share/access.log
192.168.2.152 - - [13/Dec/2023:13:40:08 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.152 - - [13/Dec/2023:13:40:10 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.152 - - [13/Dec/2023:13:40:11 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
在主机nfs共享目录中新建文件,查看容器中是否新建
[root@k8s-master share]# ll ? #同步功能正常
total 8
-rw-r--r-- 1 root root 282 Dec 13 21:40 access.log
-rw-r--r-- 1 root root 618 Dec 13 21:39 error.log
[root@k8s-master share]# touch a.txt
[root@k8s-master share]# kubectl exec -it my-nginx-nfs -c busybox -n myns -- /bin/sh -c "ls /logs"
a.txt ? ? ? access.log error.log
?