NFS 服务需要依赖 RPC 服务,所以这里 NFS 服务端需要安装 rpcbind 和 nfs-utils,由于我选用的为 CentOS 系统,所以可以使用 yum 快速的安装。
输入
rpm -qa nfs-utils
输出
nfs-utils-1.3.0-0.54.el7.x86_64
rpcbind-0.2.0-38.el7.x86_64
若输出为空,则说明未安装
yum install -y nfs-utils rpcbind
mkdir -p /data/share
chmod 777 /data/share
vim /etc/exports
写入以下内容
/data/share 192.168.179.137/24(rw,sync,insecure,no_subtree_check,no_root_squash)
目录 ip(权限)
我配置了将 /data/share 文件目录设置为允许 IP 为该 10.222.77.0/24 区间的客户端挂载,当然,如果客户端 IP 不在该区间也想要挂载的话,可以设置 IP 区间更大或者设置为 * 即允许所有客户端挂载,例如:/home (ro,sync,insecure,no_root_squash) 设置 /home 目录允许所有客户端只读挂载
权限参数 | 说明 |
---|---|
ro | 只读访问 |
rw | 读写访问 |
sync | 所有数据在请求时写入共享 |
async | nfs 在写入数据前可以响应请求 |
secure | nfs 通过 1024 以下的安全 TCP/IP 端口发送 |
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 |
service rpcbind start
查看 NFS 服务项 rpc 服务器注册的端口列表
rpcinfo -p localhost
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
注意:此时我们还没有启动 NFS 服务,只监听了 111 端口,接着我们来启动 NFS 服务,再来看下注册的端口列表。
启动 NFS 服务
service nfs start
启动 NFS 服务后 rpc 服务已经启用了对 NFS 的端口映射列表
rpcinfo -p localhost
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 33745 status
100024 1 tcp 36980 status
100005 1 udp 20048 mountd
100005 1 tcp 20048 mountd
100005 2 udp 20048 mountd
100005 2 tcp 20048 mountd
100005 3 udp 20048 mountd
100005 3 tcp 20048 mountd
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl
100021 1 udp 38960 nlockmgr
100021 3 udp 38960 nlockmgr
100021 4 udp 38960 nlockmgr
100021 1 tcp 38362 nlockmgr
100021 3 tcp 38362 nlockmgr
100021 4 tcp 38362 nlockmgr
启动了 NFS 服务后,rpc 注册的端口列表明显增多。OK 现在服务端都启动起来了,在服务端看下是否正确加载了设置的 /etc/exports 配置。
showmount -e localhost
Export list for localhost:
/data/share 192.168.179.137/24
yum install -y nfs-utils
showmount -e 192.168.179.137
Export list for 192.168.179.137:
/data/share 192.168.179.137/24
注意: 如果出现
clnt_create:RPC:Port mapper failure-Unable to receive: errno 113(No route to host)
需要关闭被访问的NFS服务器上的防火墙和selinux
systemctl stop firewalld; iptables -F ;setenforce 0
在客户端创建挂在目录 /share
mkdir -p /share
chmod -R 777 /share
载远端目录到本地 /share 目录
mount 10.222.77.86:/data/share /share
我们在 NFS 服务端 /data/share 目录下创建一个文件,看下客户端是否能够正确读取并修改。
$ echo "This is NFS server." > /data/share/nfs.txt
# ll /data/share/
total 4
-rw-r--r-- 1 root root 20 Nov 5 16:49 nfs.txt
# 客户端读取
$ ll /share/
total 4
-rw-r--r-- 1 root root 20 Nov 5 16:49 nfs.txt
$ cat /share/nfs.txt
This is NFS server.
# 客户端写入
$ echo "This is NFS client." >> /share/nfs.txt
# 服务端读取
$ cat /data/share/nfs.txt
This is NFS server.
This is NFS client.
创建一个名为 nfs-pv-mysql.yml 的配置文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-mysql
spec:
# 设置容量
capacity:
storage: 5Gi
# 访问模式
accessModes:
# 该卷能够以读写模式被多个节点同时加载
- ReadWriteMany
# 回收策略,这里是基础擦除 `rm-rf/thevolume/*`
persistentVolumeReclaimPolicy: Recycle
nfs:
# NFS 服务端配置的路径
path: "/data/share/"
# NFS 服务端地址
server: 192.168.0.49
readOnly: false
# 部署
kubectl create -f nfs-pv-mysql.yml
# 删除
kubectl delete -f nfs-pv-mysql.yml
# 查看
kubectl get pv
一般来说,PV 会指定存储容量。这里需要使用 PV 的 capcity 属性。目前存储大小是唯一一个能够被申请的指标,今后会加入更多属性,例如 IOPS,吞吐能力等。
只要资源提供者支持,持久卷能够被用任何方式加载到主机上。每种存储都会有不同的能力,每个 PV 的访问模式也会被设置成为该卷所支持的特定模式。例如 NFS 能够支持多个读写客户端,但是某个 NFS PV 可能会在服务器上以只读方式使用。每个 PV 都有自己的一系列的访问模式,这些访问模式取决于 PV 的能力。访问模式的可选范围如下:
在 CLI 下,访问模式缩写为:
另外,一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。例如一个 GCE Persistent Disk 既能支持 ReadWriteOnce,也能支持 ReadOnlyMany。
只有 NFS 和 HostPath 支持 Recycle 策略,AWS EBS、GCE PD 以及 Cinder 卷支持 Delete 策略
一个卷会处于如下阶段之一:
创建一个名为 nfs-pvc-mysql-myshop.yml 的配置文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc-mysql-myshop
spec:
accessModes:
# 需要使用和 PV 一致的访问模式
- ReadWriteMany
# 按需分配资源
resources:
requests:
storage: 1Gi
# 部署
kubectl create -f nfs-pvc-mysql-myshop.yml
# 删除
kubectl delete -f nfs-pvc-mysql-myshop.yml
# 查看
kubectl get pvc
注意: 要确保每台 Node 都安装了 NFS 客户端
创建一个名为 mysql.yml 的配置文件
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-myshop-config
data:
# 这里是键值对数据
mysqld.cnf: |
[client]
port=3306
[mysql]
no-auto-rehash
[mysqld]
skip-host-cache
skip-name-resolve
default-authentication-plugin=mysql_native_password
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
explicit_defaults_for_timestamp=true
lower_case_table_names=1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-myshop
spec:
selector:
matchLabels:
app: mysql-myshop
replicas: 1
template:
metadata:
labels:
app: mysql-myshop
spec:
containers:
- name: mysql-myshop
image: mysql
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
volumeMounts:
# 以数据卷的形式挂载 MySQL 配置文件目录
- name: cm-vol-myshop
mountPath: /etc/mysql/conf.d
- name: nfs-vol-myshop
mountPath: /var/lib/mysql
volumes:
# 将 ConfigMap 中的内容以文件形式挂载进数据卷
- name: cm-vol-myshop
configMap:
name: mysql-myshop-config
items:
# ConfigMap 中的 Key
- key: mysqld.cnf
# ConfigMap Key 匹配的 Value 写入名为 mysqld.cnf 的文件中
path: mysqld.cnf
- name: nfs-vol-myshop
persistentVolumeClaim:
claimName: nfs-pvc-mysql-myshop
---
apiVersion: v1
kind: Service
metadata:
name: mysql-myshop
spec:
ports:
- port: 3306
targetPort: 3306
nodePort: 32036
type: LoadBalancer
selector:
app: mysql-myshop
kubectl create -f mysql.yml
kubectl get pods (查看是否启动成功)