NFS高可用目的
部署NFS雙機熱備高可用環境,用作K8S容器集群的遠程存儲,實現K8S數據持久化。
NFS高可用思路
NFS + Keepalived 實現高可用,防止單點故障。
Rsync+Inotify 實現主備間共享數據進行同步。
環境准備

技術要求
- 兩個NFS節點機器的配置要一致
- keepalived監控nfs進程,master的nfs主進程宕掉無法啟動時由slave的nfs接管繼續工作。
- k8s數據備份到slave,同時master和slave數據用rsync+inotify實時同步,保證數據完整性。
- 生產環境下,最好給NFS共享目錄單獨掛載一塊硬盤或單獨的磁盤分區。
關閉兩台節點機的防火牆和Selinux
關閉防火牆 # systemctl stop firewalld.service # systemctl disable firewalld.service # firewall-cmd --state not running 關閉selinux # cat /etc/sysconfig/selinux SELINUX=disabled # setenforce 0 # getenforce Disabled # reboot
NFS高可用部署記錄
一、安裝部署NFS服務(Master和Slave兩機器同樣操作)
1)安裝nfs # yum -y install nfs-utils 2)創建nfs共享目錄 # mkdir /data/k8s_storage 3)編輯export文件,運行k8s的node節點掛載nfs共享目錄 這里可以使用node節點的ip網段進行掛載配置 也可以直接使用node節點的具體ip(一個ip配置一行)進行掛載配置 # vim /etc/exports /data/k8s_storage 172.16.60.0/24(rw,sync,no_root_squash) 4)配置生效 # exportfs -r 5)查看生效 # exportfs 6)啟動rpcbind、nfs服務 # systemctl restart rpcbind && systemctl enable rpcbind # systemctl restart nfs && systemctl enable nfs 7)查看 RPC 服務的注冊狀況 # rpcinfo -p localhost 8)showmount測試 Master節點測試 # showmount -e 172.16.60.235 Export list for 172.16.60.235: /data/k8s_storage 172.16.60.0/24 Slave節點測試 # showmount -e 172.16.60.236 Export list for 172.16.60.236: /data/k8s_storage 172.16.60.0/24 ############################################################################# 或者到ks的任意一個node節點上手動嘗試掛載NFS,看是否掛載成功: [root@k8s-node01 ~]# mkdir /haha [root@k8s-node01 ~]# mount -t nfs 172.16.60.235:/data/k8s_storage /haha [root@k8s-node01 ~]# umount /haha [root@k8s-node01 ~]# mount -t nfs 172.16.60.236:/data/k8s_storage /haha [root@k8s-node01 ~]# umount /haha [root@k8s-node01 ~]# rm -rf /haha #############################################################################
二、安裝部署keepalived(Master和Slave兩機器同樣操作)
1)安裝keepalived # yum -y install keepalived 2)Master節點的keepalived.conf配置 這里特別需要注意: 一定要設置keepalived為非搶占模式,如果設置成搶占模式會在不斷的切換主備時容易造成NFS數據丟失。 # cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak # >/etc/keepalived/keepalived.conf # vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id master #id可以隨便設 } vrrp_script chk_nfs { script "/etc/keepalived/nfs_check.sh" #監控腳本 interval 2 weight -20 #keepalived部署了兩台,所以設為20,如果三台就設為30 } vrrp_instance VI_1 { state BACKUP #兩台主機都設為backup非搶占模式 interface eth0 #網卡名寫自己的,不要照抄 virtual_router_id 51 priority 100 #master設為100,backup設為80,反正要比100小 advert_int 1 nopreempt #設置為非搶占模式必須要該參數 authentication { auth_type PASS auth_pass 1111 } track_script { chk_nfs } virtual_ipaddress { 172.16.60.244 #虛擬ip } } 3)Slave節點的keepalived.conf配置 只需將priority參數項修改為80,其他配置的和master節點一樣,腳本也一樣。 # cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak # >/etc/keepalived/keepalived.conf # vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id master } vrrp_script chk_nfs { script "/etc/keepalived/nfs_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 80 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } track_script { chk_nfs } virtual_ipaddress { 172.16.60.244 } } 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)啟動keepalived服務 # systemctl restart keepalived.service && systemctl enable keepalived.service 查看服務進程是否啟動 # ps -ef|grep keepalived 6)檢查vip是否存在 在兩台節點機器上執行"ip addr"命令查看vip,其中會在一台機器上產生vip地址。 # ip addr|grep 172.16.60.244 inet 172.16.60.244/32 scope global eth0 測試vip地址要能被ping通 # ping 172.16.60.244 PING 172.16.60.244 (172.16.60.244) 56(84) bytes of data. 64 bytes from 172.16.60.244: icmp_seq=1 ttl=64 time=0.063 ms 64 bytes from 172.16.60.244: icmp_seq=2 ttl=64 time=0.042 ms 64 bytes from 172.16.60.244: icmp_seq=3 ttl=64 time=0.077 ms 7)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(Master和Slave兩機器都要操作)
1)安裝rsync和inotify # yum -y install rsync inotify-tools 2)Master節點機器配置rsyncd.conf # cp /etc/rsyncd.conf /etc/rsyncd.conf_bak # >/etc/rsyncd.conf # vim /etc/rsyncd.conf uid = root gid = root use chroot = 0 port = 873 hosts allow = 172.16.60.0/24 #允許ip訪問設置,可以指定ip或ip段 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] path = /data/k8s_storage comment = master_web ignore errors read only = no #是否允許客戶端上傳文件 list = no auth users = rsync #指定由空格或逗號分隔的用戶名列表,只有這些用戶才允許連接該模塊 secrets file = /etc/rsyncd.passwd #保存密碼和用戶名文件,需要自己生成 編輯密碼和用戶文件(格式為"用戶名:密碼") # vim /etc/rsyncd.passwd rsync:123456 編輯同步密碼(注意這個文件和上面的密碼和用戶文件路徑不一樣) 該文件內容只需要填寫從服務器的密碼,例如這里從服務器配的用戶名密碼都是rsync:123456,則主服務器則寫123456一個就可以了 # vim /opt/rsyncd.passwd 123456 設置文件執行權限 # chmod 600 /etc/rsyncd.passwd # chmod 600 /opt/rsyncd.passwd 啟動服務 # systemctl enable rsyncd && systemctl restart rsyncd 檢查rsync服務進程是否啟動 # ps -ef|grep rsync 3)Slave節點機器配置rsyncd.conf 就把master主機/etc/rsyncd.conf配置文件里的[master_web]改成[slave_web] 其他都一樣,密碼文件也設為一樣 # cp /etc/rsyncd.conf /etc/rsyncd.conf_bak # >/etc/rsyncd.conf # vim /etc/rsyncd.conf uid = root gid = root use chroot = 0 port = 873 hosts allow = 172.16.60.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 [slave_web] path = /data/k8s_storage comment = master_web ignore errors read only = no list = no auth users = rsync secrets file = /etc/rsyncd.passwd 編輯密碼和用戶文件(格式為"用戶名:密碼") # vim /etc/rsyncd.passwd rsync:123456 編輯同步密碼 # vim /opt/rsyncd.passwd 123456 設置文件執行權限 # chmod 600 /etc/rsyncd.passwd # chmod 600 /opt/rsyncd.passwd 啟動服務 # systemctl enable rsyncd && systemctl restart rsyncd 檢查rsync服務進程是否啟動 # ps -ef|grep rsync
4)手動驗證下Master節點NFS數據同步到Slave節點
在Master節點的NFS共享目錄下創建測試數據 # ls /data/k8s_storage/ # mkdir /data/k8s_storage/test # touch /data/k8s_storage/{a,b} # ls /data/k8s_storage/ a b test 手動同步Master節點的NFS共享目錄數據到Slave節點的NFS共享目錄下 # rsync -avzp --delete /data/k8s_storage/ rsync@172.16.60.236::slave_web --password-file=/opt/rsyncd.passwd 到Slave節點查看 # ls /data/k8s_storage/ a b test
上面rsync同步命令說明:
- /data/k8s_storage/ 是同步的NFS共享目錄
- rsync@172.16.60.236::slave_web
- rsync 是Slave節點服務器的/etc/rsyncd.passwd文件中配置的用戶名
- 172.16.60.236為Slave節點服務ip
- slave_web 為Slave服務器的rsyncd.conf中配置的同步模塊名
- --password-file=/opt/rsyncd.passwd 是Master節點同步到Slave節點使用的密碼文件,文件中配置的是Slave節點服務器的/etc/rsyncd.passwd文件中配置的密碼
5)設置Rsync+Inotify自動同步
這里需要注意:不能設置Master和Slave節點同時執行rsync自動同步,即不能同時設置雙向同步。因為Master節點將數據同步到Slave節點,如果Slave節點再將數據同步回到Master節點,這個就矛盾了。所以需要確保只有一方在執行自動同步到另一方的操作。方式就是判斷當前節點服務器是否存在VIP,如存在VIP則自動同步數據到另一台節點上。如不存在VIP則不執行自動同步操作。
+++++++ Master節點服務器操作 +++++++
編寫自動同步腳本/opt/rsync_inotify.sh
#!/bin/bash host=172.16.60.236 src=/data/k8s_storage/ des=slave_web 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
編寫VIP監控腳本/opt/vip_monitor.sh
#!/bin/bash VIP_NUM=`ip addr|grep 244|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
編寫持續執行腳本/opt/rsync_monit.sh
#!/bin/bash while [ "1" = "1" ] do /bin/bash -x /opt/vip_monitor.sh >/dev/null 2>&1 done
后台運行腳本
# chmod 755 /opt/rsync_inotify.sh # chmod 755 /opt/vip_monitor.sh # chmod 755 /opt/rsync_monit.sh # nohup sh /opt/rsync_inotify.sh & # nohup sh /opt/rsync_monit.sh &
設置rsync_monit.sh腳本的開機啟動
# chmod +x /etc/rc.d/rc.local # echo "nohup sh /opt/rsync_monit.sh & " >> /etc/rc.d/rc.local
+++++++ Slave節點服務器操作 +++++++
腳本名為/opt/rsync_inotify.sh,內容如下:
#!/bin/bash host=172.16.60.235 src=/data/k8s_storage/ des=master_web 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
編寫VIP監控腳本/opt/vip_monitor.sh
#!/bin/bash VIP_NUM=`ip addr|grep 244|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
編寫持續執行腳本/opt/rsync_monit.sh
#!/bin/bash while [ "1" = "1" ] do /bin/bash -x /opt/vip_monitor.sh >/dev/null 2>&1 done
后台運行腳本 (只執行rsync_monit.sh)
# chmod 755 /opt/rsync_inotify.sh # chmod 755 /opt/vip_monitor.sh # chmod 755 /opt/rsync_monit.sh # nohup sh /opt/rsync_monit.sh &
設置rsync_monit.sh腳本的開機啟動
# chmod +x /etc/rc.d/rc.local # echo "nohup sh /opt/rsync_monit.sh & " >> /etc/rc.d/rc.local
6)最后驗證下自動同步
1)比如當前VIP在Master節點,在Master節點創建測試數據,觀察是否自動同步到Slave節點 # ip addr|grep 172.16.60.244 inet 172.16.60.244/32 scope global eth0 # rm -rf /data/k8s_storage/* # echo "test" > /data/k8s_storage/haha # ls /data/k8s_storage/ haha 到Slave節點上查看,已自動同步過來 # ls /data/k8s_storage/ haha # cat /data/k8s_storage/haha test 2)接着關閉Master節點的keeplived,將VIP飄移到Slave節點 # systemctl stop keepalived # ip addr|grep 172.16.60.244 到Slave節點上查看,發現VIP已經飄移過來了 # ip addr|grep 172.16.60.244 inet 172.16.60.244/32 scope global eth0 在Slave節點創建測試數據,觀察是否自動同步到Master節點 # rm -rf /data/k8s_storage/* # mkdir /data/k8s_storage/cha # echo "heihei" > /data/k8s_storage/you 到Master節點查看,發現數據已經同步過來了 # ls /data/k8s_storage/ cha heihei 3)模擬Master節點和Slave節點關機,觀察開機后: /opt/rsync_monit.sh腳本會實現開機自啟動。 按照上面Master和Slave節點的自動同步驗證OK。