web-dev-qa-db-ja.com

keepalivedが仮想IPの損失を検出しない

Keepalivedを使用して、2つのVM間でフローティングIPを切り替えています。

/etc/keepalived/keepalived.conf on VM 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 on VM 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
    }
}

これは基本的には正常に機能しますが、1つの例外があります。systemdが更新されるたびに(Ubuntu 18.04を実行しています)、ネットワークコンポーネントがリロードされ、システムで構成されていないため、フローティングIPがドロップされます。キープアライブされた両方のインスタンスは引き続き相互に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の1つで稼働していることをどのように確認できますか?

さらなるテスト:

Check_scriptで特定のホスト上でアクティブかどうかを確認する代わりに、フローティングIPにpingを実行しようとしました。

vrrp_script chk_proxyip {
    script "/bin/ping -c 1 -w 1 1.2.3.4"
    interval 2
}

このスクリプトをノード2で構成すると、次のようになります。

  1. テストのためにノード1のIPを削除しました
  2. ノード2がIP損失を検出し、BACKUPからFAULTに変更されました
  3. ノード1は状態の変更を無視し、MASTERのままでした

その結果、IPはダウンしたままでした。

ノード1でスクリプトを構成すると、次のようになります。

  1. ノード1のIPを削除しました
  2. ノード1がIP損失を検出し、MASTERからFAULTに変更されました
  3. ノード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を再起動する必要がありました。

8

私たちはこの問題を経験し、ubuntu 18.04のsystemd-networkdの問題であると判断し、現在ネットプランを使用しています。 keepalivedの新しいバージョンでは、フェイルオーバーの原因となるフローティングIPの削除を検出できるため、これを修正する必要があります。 https://github.com/acassen/keepalived/issues/836 を参照してください。

Keepalivedの新しいバージョンは18.04では利用できません。バックポートしようとするのではなく、ubuntu 16.04に留まり、keepalivedを使用するサーバーがubuntu 20.04になるまで待つことにしました。

7
mp3foley

この問題は、2018-05-26のkeepalived 2.0.0で修正されています。 keepalivedの変更ログ を参照してください

  • VIP/eVIPが削除された場合、VIP/eVIPの削除を監視し、バックアップに移行します。Voice/ eVIPがno-trackオプションで構成されている場合、それが解除されます。
5
teissler

一般的なアプローチは問題ないと思いますが、テスト条件を再考する必要があります。懸念している状態は、systemdがインフラストラクチャをインフラストラクチャで再起動しているかどうか(つまり、VIPが起動しているかどうか)の間接的な結果)であるため、これを確認する必要があります。ために。

これをタイプするときに簡単にテストできるシステムがないので、YMMVですが、これをカバーするにはsystemctl is-active network.serviceで十分です。 「アクティブ」以外の状態についてsystemctl show network.service | grep 'ActiveState'の状態を確認すると失敗します。

余談ですが、どちらかのノードを両方とも「マスター」としてではなく、「バックアップ」状態で構成する必要がありますか?

0
clockworknet

回避策として、プライマリノードの追加IPとしてフローティングIPを構成しました(優先順位が高い)

/ etc/netplan/01-netcfg.yaml

network:
  version: 2
  renderer: networkd
  ethernets:
    ens160:
      addresses: [ 1.2.3.5/24, 1.2.3.4/24 ]
      gateway4: 1.2.3.254
      nameservers:
          search: [ example.com ]
          addresses:
              - "1.2.3.40"

このように、起動時またはsystemdの再構成時に、フローティングIPはプライマリノードにあります。失敗した場合は、keepalivedを介してセカンダリノードに引き継がれます。プライマリノードが戻ると、IPはセカンダリノードのkeepalivedによって解放されます。

これは実際には解決策ではありませんが、現在のところ、これ以上の解決策はありません。


更新

この回避策はうまくいったが、いくつかの副作用があった。再起動後、フローティングIPアドレスがインターフェイスに2回存在しました。

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:50:56:a3:d7:d1 brd ff:ff:ff:ff:ff:ff
    inet 1.2.3.5/24 brd 1.2.3.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet 1.2.3.4/32 scope global ens160
       valid_lft forever preferred_lft forever
    inet 1.2.3.4/24 brd 1.2.3.255 scope global secondary ens160
       valid_lft forever preferred_lft forever

これは何にも影響を与えていないようでしたが、うまくいきましたが、それは私を悩ませました。最終的に私は mp3foleyによる答え をもたらし、Ubuntu 16.04でVMを再インストールしました。

0

私はあなたがフローティングIPでpingチェックを行うことができると思います、そしてそれが失敗したらすべてのノードでkeepalivedサービスを再起動してください

Youre ip wil com back

これを毎分または5分ごとに実行されるcronjobに入れます

0
Mark