Fork me on GitHub

kubernetes系列之《Volume》

1、了解k8s的Volume

官网:https://kubernetes.io/docs/concepts/storage/volumes/

kubernetes中的Volume提供了在容器中挂载外部存储的能力,Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)良哥信息后才可以使用相应的Volume

volume根据使用可以分为以下三类:

  1. Volume本地和网络数据卷
  2. Persistent Volume 持久数据卷
  3. Persistent Volume 动态供给 数据卷

本地数据卷:emptrDir、hostPath
网络数据卷:NFS

2、emptyDir(空目录)

kubectl explain pod.spec.volumes.emptyDir 指定emptyDir存储卷

  • medium 指定媒介类型 disk Memory 两种
  • sizeLimit 现在资源使用情况

kubectl explain pod.spec.containers.volumeMounts 指定挂载哪些存储卷

  • mountPath 挂载那个路径
  • name 指定挂载的volumes名称
  • readOnly 是否只读挂载
  • subPath 是否挂载子路径

创建一个空卷,挂载到Pod中的容器。Pod删除该卷也不会被删除。应用场景:Pod中容器之间数据共享,
我们可以创建2个容器,一个写,一个读,来测试我们数据是否共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@k8s-master-128 ~]# mkdir volume && cd volume/
[root@k8s-master-128 volume]# vim empty.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
# 根据下面的数据卷名字使用名为data的数据卷,挂载在/data下面
- name: data
mountPath: /data

- name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
# 根据下面的数据卷名字使用名为data的数据卷,挂载在/data下面
- name: data
mountPath: /data

# 定义一个数据卷来源
volumes:
# 定义数据卷名字
- name: data
emptyDir: {}

这样,我们2个容器都将名为data的数据卷挂载在/data目录下

创建:

1
2
3
4
5
[root@k8s-master-128 volume]# kubectl create -f empty.yaml
pod/my-pod created
[root@k8s-master-128 volume]# kubectl get pods my-pod
NAME READY STATUS RESTARTS AGE
my-pod 2/2 Running 1 3m4s

检测:

1
2
3
4
[root@k8s-master-128 volume]# kubectl logs -f my-pod read
1
2
3

因为我们是每隔一秒写入,所以我们能够不停的看见打印的数据。

3、hostPath(本地挂载)

kubectl explain pod.spec.volumes.hostPath

  • path 指定宿主机的路径
  • type DirectoryOrCreate 宿主机上不存在创建此目录 Directory 必须存在挂载目录 FileOrCreate 宿主机上不存在挂载文件就创建 File 必须存在文件

挂载Node文件系统上的文件或目录到Pod中的容器。应用场景:Pod中容器需要访问宿主机文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@k8s-master-128 volume]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 36000
# 挂载点
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
#挂载来源,宿主机的/tmp目录
hostPath:
path: /tmp
type: Directory

创建:

1
2
3
4
5
[root@k8s-master-128 volume]# kubectl create -f hostpath.yaml
pod/hostpath-pod created
[root@k8s-master-128 volume]# kubectl get pods hostpath-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath-pod 1/1 Running 0 97s 172.17.4.3 172.16.194.129 <none> <none>

使用-o wide参数知道hostpath-pod运行在172.16.194.129这个节点上,我们可以查看该节点的/tmp目录是否被挂载到容器中:

先查看172.16.194.129的/tmp目录所存在的文件:

1
2
3
4
5
6
7
8
9
10
[root@k8s-node-129 ~]# ls -lha /tmp/
总用量 0
drwxrwxrwt. 8 root root 172 5月 23 20:25 .
dr-xr-xr-x. 17 root root 224 4月 26 01:10 ..
drwxrwxrwt. 2 root root 6 4月 26 01:06 .font-unix
drwxrwxrwt. 2 root root 6 4月 26 01:06 .ICE-unix
drwx------ 3 root root 17 5月 23 10:40 systemd-private-e3f8a01e9f24475b9544ebbb9406fe01-chronyd.service-vzW5qS
drwxrwxrwt. 2 root root 6 4月 26 01:06 .Test-unix
drwxrwxrwt. 2 root root 6 4月 26 01:06 .X11-unix
drwxrwxrwt. 2 root root 6 4月 26 01:06 .XIM-unix

在进入Pod中查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s-master-128 volume]# kubectl exec -it hostpath-pod /bin/sh
/ # ls # 能看到挂载的data目录
bin data dev etc home proc root sys tmp usr var
/ # ls -lha data/
total 0
drwxrwxrwt 8 root root 172 May 23 12:26 .
drwxr-xr-x 1 root root 41 May 23 12:10 ..
drwxrwxrwt 2 root root 6 Apr 25 17:06 .ICE-unix
drwxrwxrwt 2 root root 6 Apr 25 17:06 .Test-unix
drwxrwxrwt 2 root root 6 Apr 25 17:06 .X11-unix
drwxrwxrwt 2 root root 6 Apr 25 17:06 .XIM-unix
drwxrwxrwt 2 root root 6 Apr 25 17:06 .font-unix
drwx------ 3 root root 17 May 23 02:40 systemd-private-e3f8a01e9f24475b9544ebbb9406fe01-chronyd.service-vzW5qS
/ #

上面信息证明Pod中容器的/data挂载目录与172.16.194.129的/tmp目录一致,挂载成功。
当然,你也可以创建一个文件试试看,Node节点的挂载目录也会同步。

4、NFS(文件共享存储,网络卷)

kubectl explain pod.spec.volumes.nfs

  • path 源目录
  • readOnly 是否只读 默认false
  • server NFS服务地址

安装NFS:(需要使用nfs服务,每台Node节点都需要安装)

1
$ yum install -y nfs-utils

我们设置172.16.194.130为服务端,配置/opt/container_data/共享目录出来,并且具有读写权限

1
2
[root@k8s-node-130 ~]# cat /etc/exports
/opt/container_data 172.16.194.0/24(rw,no_root_squash)

然后启动服务

1
2
$ systemctl start rpcbind
$ systemctl start nfs

在客户端节点上查看共享目录:

1
2
3
[root@k8s-node-129 ~]# showmount -e k8s-node-130
Export list for k8s-node-130:
/opt/container_data 172.16.194.0/24

如果能看到共享目录信息,则表明NFS配置完成,接下来创建Pod使用之。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@k8s-master-128 volume]# vim nfs.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
# 启用数据卷的名字为wwwroot,并挂载到nginx的html目录下
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
# 定义数据卷名字为wwwroot,类型为nfs
volumes:
- name: wwwroot
nfs:
server: 172.16.194.130
path: /opt/container_data

创建:

1
2
3
4
5
6
7
[root@k8s-master-128 volume]# kubectl create -f nfs.yaml
deployment.apps/nginx-deployment created
[root@k8s-master-128 volume]# kubectl get deploy|grep nginx-
nginx-deployment 0/2 2 0 12s
[root@k8s-master-128 volume]# kubectl get pods |grep nginx-deploy
nginx-deployment-668db478c9-fj9np 1/1 Running 0 61s
nginx-deployment-668db478c9-wsc5n 1/1 Running 0 61s

查看挂载点下的文件:

1
2
3
4
[root@k8s-node-130 container_data]# echo "hello world" >index.html
[root@k8s-node-130 container_data]# ls -lh
总用量 4.0K
-rw-r--r-- 1 root root 12 5月 23 20:54 index.html

进入Pod的容器中,查看/usr/share/nginx/html 挂载文件数据:

1
2
3
4
5
6
[root@k8s-master-128 volume]# kubectl exec -it nginx-deployment-668db478c9-wsc5n bash
root@nginx-deployment-668db478c9-wsc5n:/# ls -lh /usr/share/nginx/html/
total 4.0K
-rw-r--r-- 1 root root 12 May 23 12:54 index.html
root@nginx-deployment-668db478c9-wsc5n:/# cat /usr/share/nginx/html/index.html
hello world

访问测试:
找到容器的IP地址

1
$ kubectl get pods -o wide|grep nginx-deploy

在Node上测试:

1
2
[root@k8s-node-129 ~]# curl 172.17.34.7
hello world

至此,使用NFS挂载网站根目录完成,今后类似需求可采用此方案。

参考文章:

-------------本文结束感谢您的阅读-------------