使用 NFS 同步 K8s 配置

介绍

在 K8s 中,可以使用 NFS 网络文件系统服务,来共享与备份发布有关的 YAML 文件和部分服务配置文件。

本地环境中,需要用到 NFS 服务的有:

  • k8s-101、k8s-102、k8s-103:K8s 主节点,同步 /hxz393 目录。用于存放集群发布文件和配置。
  • k8s-106:专职备份节点,共享 /backup 目录。

如果生产环境使用的云服务商,可以直接购买云服务商提供的 NFS 服务,价格便宜且稳定。购买之后,只需要将其挂载并开机挂载到本地指定目录即可。

安装

在 4 个节点上使用 yum 安装并启动相关服务:

[root@k8s-101 ~]# yum install nfs-utils rpcbind -y
[root@k8s-101 ~]# systemctl enable --now rpcbind
[root@k8s-101 ~]# systemctl enable --now nfs

优化

增加 NFS 最大连接客户端数量,默认为 2:

[root@k8s-101 ~]# echo "options sunrpc tcp_slot_table_entries=128" >> /etc/modprobe.d/sunrpc.conf
[root@k8s-101 ~]# echo "options sunrpc tcp_max_slot_table_entries=128" >>  /etc/modprobe.d/sunrpc.conf
[root@k8s-101 ~]# sysctl -w sunrpc.tcp_slot_table_entries=128
sunrpc.tcp_slot_table_entries = 128
[root@k8s-101 ~]# systemctl restart rpcbind && systemctl restart nfs-server

配置

在主节点上新建目录 /hxz393,配置成共享并立即生效:

[root@k8s-102 ~]# mkdir /hxz393
[root@k8s-102 ~]# echo -e "/hxz393 *(rw,no_root_squash,sync,no_subtree_check)">>/etc/exports
[root@k8s-102 ~]# exportfs -r

同样在备份节点上新建并共享目录 /backup

[root@k8s-106 ~]# mkdir /backup
[root@k8s-102 ~]# echo -e "/backup *(rw,no_root_squash,sync,no_subtree_check)">>/etc/exports
[root@k8s-102 ~]# exportfs -r

查看

查询挂载目录,验证配置:

[root@k8s-101 ~]# showmount -e k8s-101
Export list for k8s-101:
/hxz393 *
[root@k8s-101 ~]# showmount -e 192.168.1.106
Export list for 192.168.1.106:
/backup *

挂载

挂载命令为 mount 后面接远程目录和本地目录。本地目录需要事先建立好:

[root@k8s-101 ~]# mkdir /backup
[root@k8s-101 ~]# mount 192.168.1.106:/backup /backup

可以按需求,将 NFS 共享目录设为开机挂载。只需要将挂载命令写入到 /etc/rc.d/rc.local 文件中:

[root@k8s-101 ~]# echo "mount 192.168.1.106:/backup /backup" >>/etc/rc.d/rc.local
[root@k8s-101 ~]# chmod ug+x /etc/rc.d/rc.local

但这样做会有个风险:如果在开机时网络未就绪或 NFS 服务器无法访问,那么在等待很长一段时间后会挂载失败。之后在系统中任何对挂载目录的操作,都会卡成僵尸。

所以保守点还是在需要用的时候挂载,不需要用了及时卸载:

[root@k8s-101 ~]# umount /backup

同步

对主节点上关键目录 /hxz393rsync + inotify 做同步。先安装工具:

[root@k8s-101 ~]# yum -y install rsync inotify-tools

修改 k8s-101 上 rsync 配置文件如下。节点 k8s-102 和 k8s-103 只能从 k8s-101 单向同步,因此配置文件中将 master_web 改为 slave_web。具体配置说明可见注释:

[root@k8s-101 ~]# tee /etc/rsyncd.conf<<EOF
#rsync通用配置文件,配置的注释不要写在配置后面
uid = root
gid = root
use chroot = 0
port = 873
##允许ip访问设置
hosts allow = 192.168.1.0/24
max connections = 0
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
log format = %t %a %m %f %b
transfer logging = yes
syslog facility = local3
#方括号中为模块声明,这里master_web对应了主web机配置,从服务器可都为[slave_web],方便inotify脚本配置
[master_web]
#指定当前模块在rsync服务器上的同步路径,该参数是必须指定的
path = /hxz393/
#注释,可以同模块名一样,从服务器可都为slave_web
comment = master_web
ignore errors
##是否允许客户端上传文件
read only = no
list = no
##指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块
auth users = rsync
##保存密码和用户名文件,需要自己生成
secrets file = /etc/rsyncd.passwd
EOF

生成密码文件:

[root@k8s-101 ~]# echo "rsync:kKWA.J2V3tq3" > /etc/rsyncd.passwd
[root@k8s-101 ~]# mkdir -p /hxz393/local/nfs/config
[root@k8s-101 ~]# echo "kKWA.J2V3tq3" > /hxz393/local/nfs/config/rsyncd.passwd
[root@k8s-101 ~]# chmod 600 /etc/rsyncd.passwd /hxz393/local/nfs/config/rsyncd.passwd

启动服务:

[root@k8s-101 ~]# systemctl restart rsyncd
[root@k8s-101 ~]# systemctl enable rsyncd

在 k8s-101 上测试下同步 /hxz393 到 k8s-102:

[root@k8s-101 ~]# rsync -avzp --delete  /hxz393/ rsync@192.168.1.102::slave_web --password-file=/hxz393/local/nfs/config/rsyncd.passwd
sending incremental file list
./
local/
local/k8s/
local/k8s/apply/
local/k8s/apply/kube-flannel.yml
local/k8s/apply/kube-namespaces.yml
local/k8s/config/
local/k8s/config/admin.conf
local/k8s/config/kubeadm-config.yaml
local/nfs/
local/nfs/config/
local/nfs/config/rsyncd.passwd

sent 6,380 bytes  received 156 bytes  13,072.00 bytes/sec
total size is 11,704  speedup is 1.79

同步测试没问题后,在 k8s-101 上写入开机自启动脚本:

[root@k8s-101 ~]# vi /hxz393/local/nfs/rsync.sh
#!/bin/bash
set -e

host1="192.168.1.102"
host2="192.168.1.103"
src="/hxz393/"
des="slave_web"
password="/hxz393/local/nfs/config/rsyncd.passwd"
user="rsync"
inotifywait="/usr/bin/inotifywait"
log="/tmp/rsync.log"

if [ ! -f "${inotifywait}" ]; then
    echo "inotifywait tool does not exist."
    exit 1
fi

${inotifywait} -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib ${src} \
| while read files ;do
 rsync -avzP --delete --timeout=100 --password-file=${password} ${src} ${user}@${host1}::${des} >>${log} 2>&1
 echo "${files} 同步到${host1}" >>${log}
 rsync -avzP --delete --timeout=100 --password-file=${password} ${src} ${user}@${host2}::${des} >>${log} 2>&1
 echo "${files} 同步到${host2}" >>${log}
done
[root@k8s-101 ~]# bash -n /hxz393/local/nfs/rsync.sh
[root@k8s-101 ~]# chmod 755 /hxz393/local/nfs/rsync.sh
[root@k8s-101 ~]# echo "nohup bash /hxz393/local/nfs/rsync.sh > /tmp/rsync.sh.log 2>&1 &" >> /etc/rc.d/rc.local
[root@k8s-101 ~]# chmod 744 /etc/rc.d/rc.local