Contents
网络存储卷¶
由于Kubernetes是分布式容器集群,因此如何在多个Pod之间或多个Node之间进行数据存储和共享是非常重要的问题。为了解决这个问 题,Kubernetes引入了网络存储卷,它支持为数众多的云提供商的产品和网络存储方案例如:
NFS/iSCSI/GlusterFS/RDB/azureDisk/flocker等。
网络存储卷还能够满足持久化数据的要求,这些数据将永久保存。
因为大部分网络存储卷是集成各种第三方的存储系统,所以在配置上各有差别,如果要一一讲解会占用非常大的篇幅。
为了简化案例,展示核心原理,本章主要以NFS为例讲解网络存储卷的使用。
1.安装NFS¶
网络文件系统(Network File System,NFS)允许网络中的计算机通过TCP/IP网络共享资源。
通过NFS,本地NFS的客户端应用可以直接读写NFS服务器上的文件,就像访问本地文件一样。
NFS可以通过网络让不同主机之间或不同的操作系统之间进行数据存储和共享。 因为NFS是第三方系统,所以先安装NFS
1.1 安装NFS服务器端¶
在Debian/Ubuntu系统上,执行以下命令,安装NFS服务器端应用。
$ apt install nfs-kernel-server
在CentOS/RHEL/Fedora系统上,请执行以下命令,安装NFS服务器端应用。
$ yum install -y nfs-utils rpcbind
服务端应用安装完毕后,创建一个目录,将其作为NFS共享目录,以便客户端可以访问共享目录中的内容。
$ mkdir -p /data/k8snfs
然后,编辑NFS配置文件,执行以下命令。
$ vim /etc/exports
# 在文件中填入如下内容并保存。
/data/k8snfs * (rw,sync,insecure,no_subtree_check,no_root_squash)
第一个参数是NFS共享目录的路径;
第二个参数是允许共享目录的网段,这里设置的是本书中的Kubernetes集群机器网段,也可以设置为“*”以表示不限制。
最后小括号中的参数为权限设置,
[ ] rw表示允许读写访问,
[ ] sync表示所有数据在请求时写入共享目录,
[ ] insecure表示NFS通过1024以上的端口进行发送,
[ ] no_root_squash表示root用户对根目录具有完全的管理访问权限,
[ ] no_subtree_check表示不检查父目录的权限。
保存完毕后,重启相关服务。
在Debian/Ubuntu系统上安装后,请执行以下命令以重启服务。
$ service rpcbind restart
$ service nfs-kernel-server restart
在CentOS/RHEL/Fedora系统上安装后,请执行以下命令以重启服务。
$ service rpcbind restart
$ service nfs restart
最后,通过以下命令,检查服务器端是否正常加载了/etc/exports的配置。
$ sudo showmount -e localhost
或者
$ exportfs
可以发现服务器已成功启动,共享目录已成功配置。
1.2 安装NFS客户端¶
每台需要使用NFS的Node都需要安装NFS。
在Debian/Ubuntu系统上,请执行以下命令,安装NFS客户端应用。
$ apt install nfs-common
在CentOS/RHEL/Fedora系统上,请执行以下命令,安装NFS客户端应用。
$ yum install -y nfs-utils
$ systemctl restart nfs
安装成功后,可以输入以下命令,检查是否能访问远端的NFS服务器。
$ sudo showmount -e {NFS服务器IP地址}
在本例中执行命令 sudo showmount -e 192.168.1.60
1.3 使用NFS¶
安装完成后可以使用NFS作为存储卷。只需要简单地配置就可以将NFS挂载到Pod当中,NFS中的数据可以永久保存,且可以被多个Pod同时读写。
为了演示NFS存储卷的使用方式,首先,创建exampledeployfornfs.yml文件。
apiVersion: apps/v1
kind: Deployment
metadata:
name: exampledeployfornfs
spec:
replicas: 2
selector:
matchLabels:
example: examplefornfs
template:
metadata:
labels:
example: examplefornfs
spec:
containers:
- name: containerfornfs
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c']
args: ['echo "The host is $(hostname)" >> /dir/data; sleep 3600']
volumeMounts:
- name: nfsdata
mountPath: /dir
volumes:
- name: nfsdata
nfs:
path: /nfstest
server: 192.168.1.60
本例中创建的存储卷名称为nfsdata,这个名称会被容器设置中的volumeMounts所引用。
存储卷的类型是nfs,其server和path属性分别对应之前在安装时配置的NFS机器IP地址与共享目录。
本例中创建的名为containerfornfs的容器用于向存储卷写入数据,容器内的存储卷映射地址为/dir,它引用的存储卷为nfsdata。
容器启动后会以追加方式(使用echo …>>…命令)向/dir/data文件写入文本,这段代码中使用$(hostname)环境变量获取主机名 称,对于Pod中的容器,获取到的是Pod名称。
因为Deployment控制器拥有多个Pod,所以通过这种方式,在同一个文件下会由多个Pod写入多行信息。
接下来,执行以下命令,创建Deployment控制器。
$ kubectl apply -f exampledeployfornfs.yml
创建后可以通过$ kubectl get deploy命令查看启动状态
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
exampledeployfornfs 2/2 2 2 28s
接下来,执行$ kubectl get pod -o wide命令,如图所示。可以看到Deployment控制器一共创建了两个Pod,分别位于不同的
机器上。
使用以下命令进入Pod内部的命令界面
$ kubectl exec -it pod/exampledeployfornfs-64cbf74f77-q6t7m -- sh
/ # cat /dir/data
The host is exampledeployfornfs-64cbf74f77-shjsr
The host is exampledeployfornfs-64cbf74f77-q6t7m
此时可以进行修改,看看其他Pod是否能读取修改后的文件。通过vim /dir/data进行编辑,将文件内容修改为以下内容并保存。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
exampledeployfornfs-64cbf74f77-q6t7m 1/1 Running 0 40s
exampledeployfornfs-64cbf74f77-shjsr 1/1 Running 0 40s
$ kubectl exec -it pod/exampledeployfornfs-64cbf74f77-q6t7m -- sh
/ # vim /dir/data
/ # cat /dir/data
The host is exampledeployfornfs-64cbf74f77-shjsr
The host is exampledeployfornfs-64cbf74f77-q6t7m
my name is hujianli
$ kubectl exec -it pod/exampledeployfornfs-64cbf74f77-shjsr -- sh
kubectl exec -it pod/exampledeployfornfs-64cbf74f77-shjsr -- sh
/ # cat /dir/data
The host is exampledeployfornfs-64cbf74f77-shjsr
The host is exampledeployfornfs-64cbf74f77-q6t7m
my name is hujianli
可以看到第二个Pod已读取修改后的文件。
在本例中,NFS服务器的共享目录为/data/nfs/nfstest。执行exit命令退出Pod的命令行界面,然后执行以下命令,输出NFS共享目录下的文件内容。
$ cat /data/nfs/nfstest/data
The host is exampledeployfornfs-64cbf74f77-shjsr
The host is exampledeployfornfs-64cbf74f77-q6t7m
my name is hujianli
其实不管哪个Pod,它们都直接引用NFS服务器上的文件,在所有的编辑操作中也都直接处理NFS服务器上的文件。
由于网络存储卷使用的是不同于Kubernetes的额外系统,因此从使用角度来说,网络存储卷存在两个问题。
存储卷数据清理问题,需要人工清理。
在Pod模板中需要配置所使用存储的细节参数,于是与所使用的存储方案产生高度耦合。若基础设施和应用配置之间没有分离,则 不利于维护。
要解决以上两个问题,就需要用到持久存储卷。
2. 参考文献¶
K8S 部署nfs服务器