k8s+nfs高可用集群

文章目录

    • @[toc]
      • 一、环境规划
        • 1)思路
        • 2)环境准备
        • 3)技术要求
      • 二、部署nfs服务
        • 1)安装nfs
        • 2)客户端测试
      • 三、部署keepalived
        • 1)安装keepalived
        • 2)Master节点的keepalived.conf配置
        • 3)Slave节点的keepalived.conf配置
        • 4)编辑nfs_check.sh监控脚本
        • 5)加入定时任务
        • 6)启动keepalived服务
        • 7)检查vip是否存在
        • 8)keepalived故障测试
      • 四、安装Rsync+Inofity
        • 1)安装rsync和inotify
          • 1、配置文件详解
        • 2)Master节点机器配置rsyncd.conf
        • 3)Slave节点机器配置rsyncd.conf
        • 4)验证是否同步
          • 1、master端检测
          • 2、salve端检测
      • 五、设置Rsync+Inotify自动同步
        • 1)Master节点服务器操作
          • 1、master数据同步脚本
          • 2、编写VIP监控脚本
          • 3、编写持续执行脚本
          • 4、后台运行脚本
          • 5、加入开机启动
        • 2)Slave节点服务器操作
          • 1、slave节点数据同步脚本
          • 2、编写VIP监控脚本
          • 3、编写持续执行脚本
          • 4、后台运行脚本
          • 5、加入开机启动
        • 3)验证下自动同步
      • 六、Client 端挂载
      • 七、结合k8s使用
          • 1)部署
          • 2)使用
      • 八、参考网址

一、环境规划

1)思路

  • NFS + Keepalived 实现高可用,防止单点故障。
  • Rsync+Inotify 实现主备间共享数据进行同步。

2)环境准备

IP 服务
192.168.4.114 nfs1
192.168.4.116 nfs2
192.168.4.118 client
192.168.4.100 VIP
  • 通过在k8s部署nfs-client-provisioner连接NFS服务器的VIP使用NAS存储

3)技术要求

  • 两个NFS节点机器的配置要一致
  • keepalived监控nfs进程,master的nfs主进程宕掉无法启动时由slave的nfs接管继续工作。
  • k8s数据备份到slave,同时master和slave数据用rsync+inotify实时同步,保证数据完整性。
  • 生产环境下,最好给NFS共享目录单独挂载一块硬盘或单独的磁盘分区。

二、部署nfs服务

1)安装nfs

#关闭 Client 、Master 和 Slave 服务器上的防火墙
systemctl stop firewalld;systemctl disable firewalld

#在 Client 、Master 和 Slave 服务器上安装 NFS 服务
yum -y install nfs-utils rpcbind

#创建nfs共享目录
mkdir /data/k8s_storage

#编辑export文件
echo " /data/k8s_storage 192.168.4.0/24(rw,sync,no_root_squash) " >>/etc/exports

##配置生效
exportfs -r

#查看生效
exportfs

#启动rpcbind、nfs服务
systemctl restart rpcbind && systemctl enable rpcbind
systemctl restart nfs && systemctl enable nfs 

#查看 RPC 服务的注册状况
rpcinfo -p localhost

#showmount测试,Master节点测试
showmount -e 192.168.4.master

#showmount测试,Slave节点测试
showmount -e 192.168.4.salve

2)客户端测试

#在 Client 上创建挂载目录
mkdir -p  /data/jiawenchao

#挂载192.168.4.116
[root@localhost ~]# mount -t nfs 192.168.4.116:/data/k8s_storage /data/jiawenchao/
[root@localhost ~]# df -Th|grep jiawenchao
192.168.4.116:/data/k8s_storage nfs4       20G   32M   20G    1% /data/jiawenchao
[root@localhost ~]# umount /data/jiawenchao

#挂载192.168.4.114
[root@localhost ~]# mount -t nfs 192.168.4.114:/data/k8s_storage /data/jiawenchao/
[root@localhost ~]# df -Th|grep jiawenchao
192.168.4.116:/data/k8s_storage nfs4       20G   32M   20G    1% /data/jiawenchao
[root@localhost ~]# umount /data/jiawenchao

三、部署keepalived

1)安装keepalived

#安装keepalived
yum -y install keepalived 

#查看网卡
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 |grep DEVICE
DEVICE=ens33

2)Master节点的keepalived.conf配置

  • 一定要设置keepalived为非抢占模式,如果设置成抢占模式会在不断的切换主备时容易造成NFS数据丢失。
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cat > /etc/keepalived/keepalived.conf<

3)Slave节点的keepalived.conf配置

  • 只需将priority参数项修改为80,其他配置的和master节点一样,脚本也一样。
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cat > /etc/keepalived/keepalived.conf<

4)编辑nfs_check.sh监控脚本

$ vim /etc/keepalived/nfs_check.sh
#!/bin/bash
A=`ps -C nfsd --no-header | wc -l`
if [ $A -eq 0 ];then
        systemctl restart nfs-server.service
        sleep 2
        if [ `ps -C nfsd --no-header| wc -l` -eq 0 ];then
            pkill keepalived
        fi
fi 

#设置脚本执行权限
chmod 755 /etc/keepalived/nfs_check.sh

5)加入定时任务

chmod 755 /etc/keepalived/nfs_check.sh
crontab -e

# 输入定时任务
* * * * *  /etc/keepalived/nfs_check.sh &> /dev/null

6)启动keepalived服务

#启动keepalived服务
systemctl restart keepalived.service 
systemctl enable keepalived.service

#查看服务进程是否启动
ps -ef|grep keepalived

7)检查vip是否存在

  • 在两台节点机器上执行"ip addr"命令查看vip,其中会在一台机器上产生vip地址.
#查看VIP
[root@localhost ~]# ip addr|grep 192.168.4.100
    inet 192.168.4.100/32 scope global ens33
   
#测试vip地址要能被ping通 
[root@localhost ~]# ping -c 3  192.168.4.100
PING 192.168.4.100 (192.168.4.100) 56(84) bytes of data.
64 bytes from 192.168.4.100: icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from 192.168.4.100: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 192.168.4.100: icmp_seq=3 ttl=64 time=0.087 ms

--- 192.168.4.100 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.021/0.059/0.087/0.029 ms

8)keepalived故障测试

  • 停掉vip所在的Master节点机器上的keepalived服务后,发现vip会自动飘移到另一台Backup机器上才算测试成功。
  • 当该Master节点的keepalived服务重新启动后,vip不会重新飘移回来。因为keepalived采用了非抢占模式。
  • 如果keepalived设置为抢占模式,vip会在Master节点的keepalived重启恢复后自动飘回去,但是这样一直来回切换可能会造成NFS数据不完整,因为这里必须设置成非抢占模式。
  • 由于配置了nfs的nfs_check.sh监控脚本,所以当其中一台节点机器上的NFS服务宕停后会自动重启NFS。
  • 如果NFS服务重启失败,则会自动关闭该节点机器上的keepalived服务,如果该节点有vip则会自动飘移到另外一台节点上。

四、安装Rsync+Inofity

1)安装rsync和inotify

#安装rsync和inotify
yum -y install rsync inotify-tools
1、配置文件详解
# 设置进行数据传输时所使用的账户名称或ID号,默认使用nobody 
uid=rsync
# 设置进行数据传输时所使用的组名称或GID号,默认使用nobody 
gid=rsync
# 设置user chroot为yes后,rsync会首先进行chroot设置,将根映射到path参数路径下,对客户端而言,系统的根就是path参数所指定的路径。但这样做需要root权限,并且在同步符号连接资料时仅会同步名称,而内容将不会同步。
use chroot=no
# 设置服务器所监听网卡接口的IP地址
# address=192.168.4.本机
# 设置服务器监听的端口号,默认为873
port=873
# 设置日志文件名称,可以通过log format参数设置日志格式
log file=/var/log/rsyncd.log
# 设置Rsync进程号保存文件名称
pid file=/var/run/rsyncd.pid
# 设置服务器信息提示文件名称,在该文件中编写提示信息
motd file=/etc/rsyncd.motd
# 开启Rsync数据传输日志功能
transfer logging=yes
# 设置锁文件名称
lock file=/var/run/rsync.lock
# 设置并发连接数,0代表无限制。超出并发数后,如果依然有客户端连接请求,则将会收到稍后重试的提示消息
max connections=10
# 模块,rsync通过模块定义同步的目录,模块以[name]的形式定义,可以定义多个模块
[common]
# comment定义注释说明字串
# comment=Web content
# 同步目录的真实路径通过path指定
path=/data/k8s_storage/
# 是否允许客户端上传数据
read only=false
# 忽略一些IO错误
ignore errors=true
# exclude可以指定例外的目录,即将common目录下的某个目录设置为不同步数据
# exclude=test/
# 设置允许连接服务器的账户,账户可以是系统中不存在的用户
auth users=rsync
# 设置密码验证文件名称,注意该文件的权限要求为只读,建议权限为600,仅在设置auth users参数后有效
secrets file=/etc/rsyncd.password
# 设置允许哪些主机可以同步数据,可以是单个IP,也可以是网段,多个IP与网段之间使用逗号分隔
hosts allow=192.168.4.114,192.168.4.115
#设置拒绝所有(除hosts allow定义的主机外)
hosts deny=*
# 客户端请求显示模块列表时,本模块名称是否显示,默认为true
list=false

2)Master节点机器配置rsyncd.conf

cp /etc/rsyncd.conf /etc/rsyncd.conf_bak
cat > /etc/rsyncd.conf<
#编辑密码和用户文件(格式为"用户名:密码")
cat >/etc/rsyncd.passwd<
#编辑同步密码
cat  >/opt/rsyncd.passwd<
  • 注意这个文件和上面的密码和用户文件路径不一样
  • 该文件内容只需要填写从服务器的密码
  • 例如这里从服务器配的用户名密码都是rsync:123456,则主服务器则写123456一个就可以了
#设置文件执行权限
chmod 600 /etc/rsyncd.passwd &&  chmod 600 /opt/rsyncd.passwd
# 修改 文件夹权限
chown -R nfsnobody:nfsnobody /data/k8s_storage/

#启动服务
systemctl enable rsyncd && systemctl restart rsyncd

#检查rsync服务进程是否启动
ps -ef|grep rsync
netstat -tnlp|grep 873
tailf -n 100  /var/log/rsyncd.log

3)Slave节点机器配置rsyncd.conf

  • 就把master主机/etc/rsyncd.conf配置文件里的[master_web]改成[slave_web]其他都一样,密码文件也设为一样
cp /etc/rsyncd.conf /etc/rsyncd.conf_bak
cat >/etc/rsyncd.conf<
#编辑密码和用户文件(格式为"用户名:密码")
cat >/etc/rsyncd.passwd</opt/rsyncd.passwd<

【权限说明】

  • 将rsyncd.passwd这个密码文件的文件属性设为root拥有, 且权限要设为600, 否则无法备份成功!出于安全目的,文件的属性必需是只有属主可读。

  • 客户端推到服务端时,文件的属主和属组是配置文件中指定的uid和gid。但是客户端从服务端拉的时候,文件的属主和属组是客户端正在操作rsync的用户身份,因为执行rsync程序的用户为当前用户。

  • auth users和secrets file这两行不是一定需要的,省略它们时将默认使用匿名连接。但是如果使用了它们,则secrets file的权限必须是600。客户端的密码文件也必须是600。

  • 关于secrets file的权限,实际上并非一定是600,只要满足除了运行rsync daemon的用户可读即可。是否检查权限的设定是通过选项strict mode设置的,如果设置为false,则无需关注文件的权限。但默认是yes,即需要设置权限。

4)验证是否同步

1、master端检测
#在Master节点的NFS共享目录下创建测试数据
ls /data/k8s_storage/
mkdir /data/k8s_storage/test
touch /data/k8s_storage/{a,b}
ls /data/k8s_storage/


#Master节点的NFS共享目录数据到Slave节点的NFS共享目录下(master端操作)
[root@localhost ~]# rsync -avzp --delete /data/k8s_storage/ [email protected]::data --password-file=/opt/rsyncd.passwd
sending incremental file list
./
a
b
test/

#到Slave节点查看(slave查看)
[root@localhost ~]# ls /data/k8s_storage/
a  b  test
2、salve端检测
#在Master节点的NFS共享目录下创建测试数据
ls /data/k8s_storage/
mkdir /data/k8s_storage/chao
touch /data/k8s_storage/{c,d}
ls /data/k8s_storage/


#Master节点的NFS共享目录数据到Slave节点的NFS共享目录下(master端操作)
[root@localhost ~]# rm -rf /data/k8s_storage/*
[root@localhost ~]# rsync -avzp --delete /data/k8s_storage/ [email protected]::data --password-file=/opt/rsyncd.passwd
sending incremental file list
./
c
d
chao/

#到Slave节点查看(slave查看)
[root@localhost ~]# ls /data/k8s_storage/
a  b  test

【rsync同步命令说明】

- /data/k8s_storage/                        #是同步的NFS共享目录
- [email protected]::data                 #是被同步主机IP和slave同步模块名
- rsync                                     #是Slave节点服务器的/etc/rsyncd.passwd文件中配置的用户名
- --password-file=/opt/rsyncd.passwd        #是Master节点同步到Slave节点使用的密码文件,文件中配置的是Slave节点服务器的/etc/rsyncd.passwd文件中配置的密码
【报错】
[root@localhost data]#  rsync -avzp --delete /data/k8s_storage/ [email protected]::slave_web --password-file=/opt/rsyncd.passwd
@ERROR: auth failed on module slave_web
rsync error: error starting client-server protocol (code 5) at main.c(1656) [sender=3.1.2]

【解决】
1、查看/opt/rsyncd.passwd同步密码
2、查看 /etc/rsyncd.conf配置是否正确

五、设置Rsync+Inotify自动同步

  • 能设置Master和Slave节点同时执行rsync自动同步,即不能同时设置双向同步。因为Master节点将数据同步到Slave节点,如果Slave节点再将数据同步回到Master节点,这个就矛盾了。所以需要确保只有一方在执行自动同步到另一方的操作。方式就是判断当前节点服务器是否存在VIP,如存在VIP则自动同步数据到另一台节点上。如不存在VIP则不执行自动同步操作。

1)Master节点服务器操作

1、master数据同步脚本
$ vim /opt/rsync_inotify.sh
#!/bin/bash
host=192.168.4.116      #被同步主机的IP
src=/data/k8s_storage/
des=data           #slave的模块名称
password=/opt/rsyncd.passwd
user=rsync
inotifywait=/usr/bin/inotifywait
$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@$host::$des
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done
2、编写VIP监控脚本
$ vim /opt/vip_monitor.sh
#!/bin/bash
VIP_NUM=`ip addr|grep 100|wc -l`      #注意修改100为所使用的VIP地址
RSYNC_INOTIRY_NUM=`ps -ef|grep /usr/bin/inotifywait|grep -v grep|wc -l`
    if [ ${VIP_NUM} -ne 0 ];then
    echo "VIP在当前NFS节点服务器上" >/dev/null 2>&1
        if [ ${RSYNC_INOTIRY_NUM} -ne 0 ];then
            echo "rsync_inotify.sh脚本已经在后台执行中" >/dev/null 2>&1
        else
             echo "需要在后台执行rsync_inotify.sh脚本" >/dev/null 2>&1
             nohup sh /opt/rsync_inotify.sh &
        fi
else
    echo "VIP不在当前NFS节点服务器上" >/dev/null 2>&1
    if [ ${RSYNC_INOTIRY_NUM} -ne 0 ];then
        echo "需要关闭后台执行的rsync_inotify.sh脚本" >/dev/null 2>&1
        ps -ef|grep rsync_inotify.sh|grep -v grep|awk '{print $2}'|xargs kill -9
        ps -ef|grep inotifywait|grep -v grep|awk '{print $2}'|xargs kill -9
    else
        echo "rsync_inotify.sh脚本当前未执行" >/dev/null 2>&1
    fi
fi
3、编写持续执行脚本
$ vim /opt/rsync_monit.sh
#!/bin/bash
while [ "1" = "1" ]
    do
    /bin/bash -x /opt/vip_monitor.sh >/dev/null 2>&1
done
4、后台运行脚本
chmod 755 /opt/rsync_inotify.sh
chmod 755 /opt/vip_monitor.sh
chmod 755 /opt/rsync_monit.sh
nohup sh /opt/rsync_monit.sh &
5、加入开机启动
#设置rsync_monit.sh脚本的开机启动
chmod +x /etc/rc.d/rc.local
echo "nohup sh /opt/rsync_monit.sh & " >> /etc/rc.d/rc.local

2)Slave节点服务器操作

1、slave节点数据同步脚本
$ vim /opt/rsync_inotify.sh
#!/bin/bash
host=192.168.4.114               #master主机的IP
src=/data/k8s_storage/
des=data                         #修改为master模块名
password=/opt/rsyncd.passwd
user=rsync
inotifywait=/usr/bin/inotifywait
$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@$host::$des
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
done
2、编写VIP监控脚本
$ vim /opt/vip_monitor.sh
#!/bin/bash
VIP_NUM=`ip addr|grep 100|wc -l`
RSYNC_INOTIRY_NUM=`ps -ef|grep /usr/bin/inotifywait|grep -v grep|wc -l`
    if [ ${VIP_NUM} -ne 0 ];then
    echo "VIP在当前NFS节点服务器上" >/dev/null 2>&1
        if [ ${RSYNC_INOTIRY_NUM} -ne 0 ];then
            echo "rsync_inotify.sh脚本已经在后台执行中" >/dev/null 2>&1
        else
             echo "需要在后台执行rsync_inotify.sh脚本" >/dev/null 2>&1
             nohup sh /opt/rsync_inotify.sh &
        fi
else
    echo "VIP不在当前NFS节点服务器上" >/dev/null 2>&1
    if [ ${RSYNC_INOTIRY_NUM} -ne 0 ];then
        echo "需要关闭后台执行的rsync_inotify.sh脚本" >/dev/null 2>&1
        ps -ef|grep rsync_inotify.sh|grep -v grep|awk '{print $2}'|xargs kill -9
        ps -ef|grep inotifywait|grep -v grep|awk '{print $2}'|xargs kill -9
    else
        echo "rsync_inotify.sh脚本当前未执行" >/dev/null 2>&1
    fi
fi
3、编写持续执行脚本
$ vim /opt/rsync_monit.sh
#!/bin/bash
while [ "1" = "1" ]
    do
    /bin/bash -x /opt/vip_monitor.sh >/dev/null 2>&1
done
4、后台运行脚本
chmod 755 /opt/rsync_inotify.sh
chmod 755 /opt/vip_monitor.sh
chmod 755 /opt/rsync_monit.sh
nohup sh /opt/rsync_monit.sh &
#如果不设置后台运行加入定时任务
chmod 755 /opt/rsync_monit.sh
crontab -e

# 输入定时任务
* * * * *  /opt/rsync_monit.sh &> /dev/null
5、加入开机启动
#设置rsync_monit.sh脚本的开机启动
chmod +x /etc/rc.d/rc.local
echo "nohup sh /opt/rsync_monit.sh & " >> /etc/rc.d/rc.local

3)验证下自动同步

  • 当前VIP在Master节点,在Master节点创建测试数据,观察是否自动同步到Slave节点
#保证VIP实在master上
[root@localhost ~]# ip a|grep 192.168.4.100
    inet 192.168.4.100/32 scope global ens33
    
#在master操作
rm -rf /data/k8s_storage/*
echo "test" > /data/k8s_storage/haha
ls /data/k8s_storage/

#到salve节点上查看,已自动同步过来
[root@localhost ~]# ls /data/k8s_storage/
haha
#master端创建
[root@localhost k8s_storage]# mkdir -p /data/k8s_storage/jiawenchao
[root@localhost k8s_storage]# ls
haha  jiawenchao

#slave端查看
[root@localhost ~]# ls /data/k8s_storage/
haha  jiawenchao
  • VIP 挂载测试
#在 Client 上通过 vip 挂载测试
mount -t nfs 192.168.4.100:/data/k8s_storage/  /data/jiawenchao

# 如/data/k8s_storage/目录中有共享目录中文件则说明挂载成功
[root@localhost ~]# ls /data/jiawenchao/
haha  jiawenchao

#取消挂载
umount /data/jiawenchao/
  • 接着关闭Master节点的keeplived,将VIP飘移到Slave节点
#接着关闭Master节点的keeplived,将VIP飘移到Slave节点
systemctl stop keepalived

#到Slave节点上查看,发现VIP已经飘移过来了
[root@localhost ~]# ip addr|grep 192.168.4.100
    inet 192.168.4.100/32 scope global ens33

#在Slave节点创建测试数据,观察是否自动同步到Master节点
rm -rf /data/k8s_storage/*
mkdir /data/k8s_storage/cha
echo "heihei" > /data/k8s_storage/you
ls /data/k8s_storage/

#到Master节点查看,发现数据已经同步过来了
[root@localhost ~]#  ls /data/k8s_storage/
cha  you
  • 模拟Master节点和Slave节点关机,观察开机后
/opt/rsync_monit.sh脚本会实现开机自启动。
按照上面Master和Slave节点的自动同步验证OK。

六、Client 端挂载

$ vim /usr/local/sbin/check_mount.sh
#!/bin/sh
# 每秒执行一次
step=1 #间隔的秒数,不能大于60 
for (( i = 0; i < 60; i=(i+step) )); do 
  mount=`df -Th|grep jiawenchao`
  if [ $mount = "" ];then
     umount  /data/jiawenchao
     mount -t nfs 192.168.4.100:/data/k8s_storage/  /data/jiawenchao
  fi
  sleep $step 
done 


#给权限
chmod 777 /usr/local/sbin/check_mount.sh
#加入定时任务
crontab -e

# 输入定时任务
* * * * *  /usr/local/sbin/check_mount.sh &> /dev/null

七、结合k8s使用

1)部署
git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
cd nfs-subdir-external-provisioner/deploy/

#修改
sed -i  's/10.3.243.101/192.168.4.100/g'  deployment.yaml
sed -i  's#/ifs/kubernetes#/data/k8s_storage/#g'  deployment.yaml

#修改部署命名空间
将default改为自己业务的名空间

#部署
kubectl apply -f  class.yaml
kubectl apply -f deployment.yaml
kubectl apply -f  rbac.yaml
2)使用
#yaml中加入部分
 volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"   #managed-nfs-storage为我们创建的storage-class名称
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

八、参考网址

【参考网址】

https://blog.csdn.net/weixin_51059774/article/details/120209043

https://copyfuture.com/blogs-details/20201124153931834mm91s67ie3h8o9s

https://cloud.tencent.com/developer/article/1923614

你可能感兴趣的:(进阶篇,运维,kubernetes,linux)