Kubernetes集群实践(四)如何在集群中使用网络存储系统NFS

由于需要在Pods中共享文件,直接挂载到宿主机肯定不行的。因此需要有一套网络存储系统。

本文主要介绍如何在K8s中使用网络存储系统NFS。

关键词:k8s

准备工作

  • 安装好Kubernetes的集群
  • Ubuntu 20.04 LTS

安装服务端

一般在集群外部安装服务端,这样可以降低集群的负载。这里只是测试用,因此在master节点上安装服务端。

安装

1
sudo apt-get install nfs-kernel-server

创建要共享的目录

1
mkdir /data/nfsshare -p

编辑nfs配置

1
sudo vim /etc/exports

其中IP是允许访问的网段,

  • rw:访问到此目录的服务器都具备读写权限
  • sync:数据同步写入内存和硬盘,与其相对的是async(只在必要的时候写入内存和硬盘)
  • all_squash:共享文件的UID和GID映射匿名用户anonymous,适合公用目录
  • no_subtree_check:不检查父目录的权限
  • anonuid=1000:指定nfs服务器/etc/passwd文件中匿名用户的UID
  • anongid=1000:指定nfs服务器/etc/passwd文件中匿名用户的GID

使用映射匿名用户UID和GID,同时设置匿名用户的UID和GID,可以避免NFS服务器的权限问题。

载入配置

1
sudo exportfs -rv

启动服务

1
sudo systemctl enable nfs-kernel-server --now 

服务检查

1
cat /var/lib/nfs/etab

查看NFS共享情况

1
2
$showmount -e 192.168.15.201
/home/wf09/nfsfiles 192.168.15.0/24

其中IP是nfs-server的IP。

安装客户端

集群中需要使用NFS存储的机器都需要安装客户端!不然使用NFS作为存储的Pod就会一直提示Init:0/1

这里使用之前配置好的xcall脚本去进行调用。

1
sudo apt install nfs-common -y"

使用nfs作为存储卷

使用NFS作为存储方式有以下几种

在deployment/statefulset中直接使用

创建一个deployment资源清单
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
31
32
33
34
35
36
37
38
39
40
41
42
43
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-deployment
spec:
selector:
matchLabels:
app: backend
replicas: 3
template:
metadata:
labels:
app: backend
spec:
volumes:
- name: jar
emptyDir: {}
- name: nfsfiles # 卷名称
nfs: # 使用NFS作为存储卷
server: 192.168.15.201 # NFS服务地址
path: /home/wf09/nfsfiles # NFS服务器共享的目录
readOnly: false # 是否为只读
initContainers:
- name: tool
image: harbor.local/zheshiyou/backend
command: ["cp", "/app.jar", "/jar"]
volumeMounts:
- name: jar
mountPath: /jar
containers:
- name: backend
image: harbor.local/zheshiyou/jre:latest
command: ["java", "-jar", "/jar/app.jar"]
#command: ["bash","-c", "while true ; do continue ; done"]
imagePullPolicy: Always
ports:
- name: server
containerPort: 8080
volumeMounts:
- name: jar
mountPath: /jar
- name: nfsfiles # 卷挂载到容器中的目录
mountPath: /share # 卷名称

上面的示例定义在资源配置文件deployment.yaml中,其中的Pod资源拥有一个关联至NFS服务器192.168.15.201的存储卷,backend容器将其挂载到容器中的/share目录上,它是backend容器中的需要持久化的目录。

创建deployment并查看配置信息
1
kubectl apply -f deployment.yml

查看配置信息

1
kubectl get pods -o wide -l app=backend

查看deployment中某一个pod的调度信息

1
kubectl describe pods/backend-deployment-7b44ccc689-bvdm6

可知调度成功

查看容器挂载情况

1
kubectl exec -it backend-deployment-7b44ccc689-bvdm6 -- df -hT

测试数据持久化访问

模拟正常资源调度情况:在某一Pod存放文件,然后登录到其他的Pod查看文件是否共享成功。

  1. 登录到某一Pod

    1
    kubectl exec -ti backend-deployment-7b44ccc689-bvdm6 bash
  2. 生成10M文件,模拟正常PDF大小

    1
    dd if=/dev/zero of=test bs=1M count=10
  3. 登录到其他Pod,查看文件是否存在

    1
    kubectl exec backend-deployment-7b44ccc689-l949v -- ls -lh /share

附录

NFS共享参数说明

参数 说明
ro 只读访问
rw 读写访问
sync 同步写入,同时将数据写入内存和硬盘中,保证不丢失数据
async 异步写入,优先将数据写入内存,然后再写入到硬盘,可能会丢失数据
secure nfs通过1024以下的安全TCP端口发送
insecure nfs通过1024以上的端口发送
wdelay 如果多个用户要写入NFS目录,则归组写入(默认)
no_wdelay 如果多个用户要写入NFS目录,则立即写入。当使用async时,无需此设置
hide 不共享nfs目录的子目录
no_hide 共享nfs目录的子目录
subtree_check 如果共享/usr/bin之类的子目录时,强制nfs检查父目录的权限(默认)
no_subtree_check 不检查父目录的权限
all_squash 共享文件的UID和GID映射匿名用户anonymous,适合公用目录
no_all_squash 保留共享文件的UID和GID(默认)
root_squash root用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squash root用户具有根目录的完全管理访问权限
anonuid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的UID
anongid=xxx 指定nfs服务器/etc/passwd文件中匿名用户的GID