Keepalived

keepalived 未檢測到虛擬 IP 失去

  • April 25, 2019

我正在使用 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 上配置此腳本,則會發生以下情況:

  1. 由於 systemd 重新啟動,VM1 失去了 IP
  2. VM1 上的 keepalived 檢測到 IP 失去
  3. keepalived 切換到FAULT狀態並停止廣播 vrrp 包
  4. 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. 刪除節點 1 上的 IP 進行測試
  2. 節點 2 檢測到 IP 失去並從 更改BACKUPFAULT
  3. 節點 1 忽略狀態變化並停留MASTER

結果:IP 保持不變。

在節點 1 上配置腳本會導致以下結果:

  1. 刪除節點 1 上的 IP
  2. 節點 1 檢測到 IP 失去並從 更改MASTERFAULT
  3. 節點 2 檢測到節點 1 上的狀態變化並從 更改BACKUPMASTER,在節點 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 選項。

引用自:https://serverfault.com/questions/953483