keepalived 未檢測到虛擬 IP 失去
我正在使用 keepalived 在兩個虛擬機之間切換浮動 IP。
/etc/keepalived/keepalived.conf
在虛擬機 1 上:vrrp_instance VI_1 { state MASTER interface ens160 virtual_router_id 101 priority 150 advert_int 1 authentication { auth_type PASS auth_pass secret } virtual_ipaddress { 1.2.3.4 } }
/etc/keepalived/keepalived.conf
在虛擬機 2 上:vrrp_instance VI_1 { state MASTER interface ens160 virtual_router_id 101 priority 100 advert_int 1 authentication { auth_type PASS auth_pass secret } virtual_ipaddress { 1.2.3.4 } }
這基本上可以正常工作,但有一個例外:每次 systemd 更新(它執行的是 Ubuntu 18.04)時,它都會重新載入它的網路組件,導致浮動 IP 失去,因為它沒有在系統中配置。由於兩個 keepalived 實例仍然可以相互 ping 通,因此它們都沒有發現任何問題,也沒有對此做出反應,導致浮動 IP 保持關閉。
我發現您可以使用如下簡單腳本檢查 IP:
vrrp_script chk_proxyip { script "/sbin/ip addr |/bin/grep 1.2.3.4" } vrrp_instance VI_1 { # [...] track_script { chk_proxyip } }
但我不確定這是否是一種可行的方法。
如果我理解正確,如果我在 VM1 上配置此腳本,則會發生以下情況:
- 由於 systemd 重新啟動,VM1 失去了 IP
- VM1 上的 keepalived 檢測到 IP 失去
- keepalived 切換到
FAULT
狀態並停止廣播 vrrp 包- VM2 上的 keepalived 檢測到 VM1 上的 keepalived 失去並將浮動 IP
此時 IP 再次在 VM2 上工作,但 VM1 將保持此狀態,因為 IP 再也不會在 VM1 上出現。如果 VM2 出現故障(無論出於何種原因),VM1 不會接管它,因為它仍處於
FAULT
狀態。如何確保浮動 IP 始終在其中一個 VM 上執行?
進一步測試:
我嘗試 ping 浮動 IP,而不是檢查它是否在 check_script 中的特定主機上處於活動狀態:
vrrp_script chk_proxyip { script "/bin/ping -c 1 -w 1 1.2.3.4" interval 2 }
在節點 2 上配置此腳本會導致以下結果:
- 刪除節點 1 上的 IP 進行測試
- 節點 2 檢測到 IP 失去並從 更改
BACKUP
為FAULT
- 節點 1 忽略狀態變化並停留
MASTER
結果:IP 保持不變。
在節點 1 上配置腳本會導致以下結果:
- 刪除節點 1 上的 IP
- 節點 1 檢測到 IP 失去並從 更改
MASTER
為FAULT
- 節點 2 檢測到節點 1 上的狀態變化並從 更改
BACKUP
為MASTER
,在節點 2 上配置浮動 IP嗯,然後……
Feb 13 10:11:26 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE Feb 13 10:11:27 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE Feb 13 10:11:29 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100 Feb 13 10:11:29 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE Feb 13 10:11:32 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE Feb 13 10:11:33 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE Feb 13 10:11:36 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100 Feb 13 10:11:36 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE Feb 13 10:11:38 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE Feb 13 10:11:39 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE Feb 13 10:11:41 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100 Feb 13 10:11:41 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering BACKUP STATE Feb 13 10:11:44 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Transition to MASTER STATE Feb 13 10:11:45 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Entering MASTER STATE Feb 13 10:11:47 node2 Keepalived_vrrp[3486]: VRRP_Instance(VI_1) Received advert with higher priority 150, ours 100 ...
我不得不在 node1 上重新啟動 keepalived 以停止節點之間的乒乓球比賽。
我們遇到了這個問題,並認為這是現在使用 netplan 的 ubuntu 18.04 中的 systemd-networkd 的問題。更新版本的 keepalived 應該可以解決此問題,因為它可以檢測導致故障轉移的浮動 IP 的刪除,請參閱https://github.com/acassen/keepalived/issues/836。
更新版本的 keepalived 在 18.04 中不可用,我們沒有嘗試向後移植,而是決定留在 ubuntu 16.04 並等到 ubuntu 20.04 用於我們使用 keepalived 的伺服器。
此問題已在 2018-05-26 的 keepalived 2.0.0 中修復,請參閱keepalived 的更新日誌
- 監控 VIP/eVIP 刪除並在 VIP/eVIP 被刪除時轉換為備份,除非它被配置為 no-track 選項。