3 Keepalivedを使用したロード・バランシングの設定

この章では、Keepalivedを使用してロード・バランシングNATモードを構成する方法を説明するタスクと例を記載しています。この章には、KeepalivedとHAProxyを組み合せて高可用性ロード・バランシングを実行する方法を示す構成シナリオも含まれています。

Keepalivedのインストールと構成

Keepalivedを使用してロード・バランシングを設定する前に、その機能をインストールして構成する必要があります。

  1. 各サーバーにkeepalivedパッケージをインストールします。

    sudo dnf install keepalived
  2. /etc/keepalived/keepalived.confを編集して、各サーバーでKeepalivedを構成します。Keepalived構成ディレクティブを参照してください。

  3. /etc/sysctl.confでIP転送を有効にします。

    net.ipv4.ip_forward = 1
  4. IP転送が適用されていることを確認します。

    sudo sysctl -p
    net.ipv4.ip_forward = 1
  5. 次の例のように、各ネットワーク・インタフェースでKeepalivedが制御するマルチキャストIPアドレス224.0.0.18およびVRRPプロトコル(112)を使用してVRRP通信を受け入れるファイアウォール・ルールを追加します。

    sudo firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
      --in-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
    sudo firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
      --out-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
    sudo firewall-cmd --reload
  6. 各サーバーでkeepalivedサービスを有効にし、起動します。

    sudo systemctl enable --now keepalived

    Keepalived構成を変更した場合は、keepalivedサービスを再ロードします。

    sudo systemctl reload keepalived

Keepalived構成ディレクティブ

/etc/keepalived/keepalived.conf構成ファイルは、次の各セクションに分かれています。

global_defs

通知メッセージを送信するための電子メール・アドレス、SMTPサーバーのIPアドレス、SMTP接続のタイムアウト値(秒)、ホスト・マシンを識別する文字列、VRRP IPv4およびIPv6マルチキャスト・アドレス、SNMPトラップを有効にするかどうかなどの、グローバルな設定を定義します。

static_ipaddress
static_routes

VRRPが変更できない静的IPアドレスおよび静的ルートを定義します。これらのセクションは、サーバーでアドレスおよびルートがすでに定義されており、これらのサーバーにすでにネットワーク接続があれば必要ありません。

vrrp_sync_group

一緒にフェイルオーバーするVRRPインスタンスのVRRP同期グループを定義します。

vrrp_instance

状態遷移中に他のグループ・メンバーに従うVRRP同期グループの内部または外部のネットワーク・インタフェースのメンバーに対して移動可能な仮想IPアドレスを定義します。各VRRPインスタンスには、プライマリ・サーバーとバックアップ・サーバー上のどのインタフェースに指定の仮想IPアドレスを割り当てることができるかを識別する、一意のvirtual_router_id値が必要です。また、BACKUPMASTERおよびFAULTへの状態遷移時に実行されるスクリプトと、状態遷移に対してSMTPアラートをトリガーするかどうかを指定することもできます。

vrrp_script

Keepalivedが一定の間隔で実行できる追跡スクリプトを定義して、vrrp_instanceまたはvrrp_sync_groupセクションから監視アクションを実行します。

virtual_server_group

実サーバーを複数の仮想サーバー・グループのメンバーに構成できるように、仮想サーバー・グループを定義します。

virtual_server

複数の実サーバーで構成される、ロード・バランシングのための仮想サーバーを定義します。

Keepalivedによるロード・バランシングの設定の詳細は、Keepalivedを使用したロード・バランシングの設定を参照してください

NATモードでのロード・バランシングの設定

次の例に、NATモードでKeepalivedを使用して、2つのサーバーに基本的なフェイルオーバーおよびロード・バランシング構成を実装する方法を示します。1つのサーバーがプライマリとして、もう1つのサーバーがバックアップとして機能し、プライマリ・サーバーの優先度がバックアップ・サーバーよりも高くなります。どちらのサーバーもVRRPを使用して現在のルーティング状態を監視します。VRRPの詳細は、VRRPでのKeepalivedの使用を参照してください。

各サーバーには2つのネットワーク・インタフェースがあり、1つのインタフェースは外部ネットワーク(192.168.1.0/24)に接続されています。もう一方のインタフェースは、2つのWebサーバーにアクセスできる内部ネットワーク(10.0.0.0/24)に接続されています。

次の図は、Keepalivedプライマリ・サーバーのネットワーク・アドレス192.168.1.10192.168.1.1 (仮想)、10.0.0.10および10.0.0.100 (仮想)を示しています。

Keepalivedバックアップ・サーバーのネットワーク・アドレスは192.168.1.11および10.0.0.11です。

IPアドレスの場合、websrv1には10.0.0.71websrv2には10.0.0.72があります。

図3-1 NATモードでのロード・バランシングのためのKeepalived構成


この図は、Keepalivedプライマリ・サーバーのネットワーク・アドレスが192.168.1.10、192.168.1.1 (仮想)、10.0.0.10および10.0.0.100 (仮想)であることを示しています。Keepalivedバックアップ・サーバーのネットワーク・アドレスは192.168.1.11および10.0.0.11です。IPアドレスの場合、websrv1には10.0.0.71、websrv2には10.0.0.72があります。

次に、プライマリ・サーバーの/etc/keepalived/keepalived.confファイルの構成の例を示します。

global_defs {
   notification_email {
     root@example.com
   }
   notification_email_from srv1@example.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_sync_group VRRP1 {
#   Group the external and internal VRRP instances so they fail over together
    group {
        external
        internal
        }
}

vrrp_instance external {
    state MASTER
    interface enp0s8
    virtual_router_id 91
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the external network interface
    virtual_ipaddress {
        192.168.1.1/24
    }
}

vrrp_instance internal {
    state MASTER
    interface enp0s9
    virtual_router_id 92
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the internal network interface
    virtual_ipaddress {
        10.0.0.100/24
    }
}

# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
    delay_loop 10
    protocol TCP
#   Use round-robin scheduling in this example
    lb_algo rr
#   Use NAT to hide the back-end servers
    lb_kind NAT
#   Persistence of client sessions times out after 2 hours
    persistence_timeout 7200
    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
       weight 1
       TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

前述の構成には、フェイルオーバー時にネットワーク・インタフェースがまとめて割り当てられるように、vrrp_sync_groupセクション、およびKeepalivedでロード・バランシングに使用される実際のバックエンド・サーバーを定義するvirtual_serverセクションが含まれています。lb_kindの値はNATを使用するように設定されます。これは、Keepalivedサーバーがバックエンド・サーバーのかわりにクライアントとの間のインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックの両方を処理します。

バックアップ・サーバーの構成は、notification_email_fromstatepriorityおよびinterface, (システム・ハードウェア構成が異なる場合)の値を除けば同じです。

global_defs {
   notification_email {
     root@example.com
   }
   notification_email_from srv2@example.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_sync_group VRRP1 {
#   Group the external and internal VRRP instances so they fail over together
    group {
        external
        internal
        }
}

vrrp_instance external {
    state BACKUP
    interface enp0s8
    virtual_router_id 91
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the external network interface
    virtual_ipaddress {
        192.168.1.1/24
    }
}

vrrp_instance internal {
    state BACKUP
    interface enp0s9
    virtual_router_id 92
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the internal network interface
    virtual_ipaddress {
        10.0.0.100/24
    }
}

# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
    delay_loop 10
    protocol TCP
#   Use round-robin scheduling in this example
    lb_algo rr
#   Use NAT to hide the back-end servers
    lb_kind NAT
#   Persistence of client sessions times out after 2 hours
    persistence_timeout 7200
 
    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

次の構成変更が必要になります。

詳細は、Keepalivedのインストールと構成を参照してください。

Keepalived NATモード・ロード・バランシングのためのファイアウォール・ルールの構成

内部ネットワーク上のサーバーでロード・バランシングにNATモードを使用するようにKeepalivedを構成した場合、Keepalivedサーバーはすべてのインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックを処理し、送信パケット内のバックエンド・サーバーのソースIPアドレスを外部ネットワーク・インタフェースの仮想IPアドレスでリライトすることにより既存のバックエンド・サーバーを非表示にします。

次の例は、どのようにインタフェースenp0s9internalゾーンに移動し、インタフェースenp0s8publicゾーンに残すかを示しています。

ロード・バランシングにNATモードを使用するようにKeepalivedサーバーを構成するには:

  1. システム上でアクティブなファイアウォール・ゾーンの状態を確認します。

    sudo firewall-cmd --get-active-zones
    public
      interfaces: enp0s8 enp0s9
  2. ファイアウォールを構成して、外部ネットワーク側のインタフェースが、内部ネットワーク側のインタフェースとは異なるゾーンにあるようにします。

    sudo firewall-cmd --zone=public --remove-interface=enp0s9
    sudo firewall-cmd --zone=internal --add-interface=enp0s9
    sudo firewall-cmd --permanent --zone=public --remove-interface=enp0s9
    sudo firewall-cmd --permanent --zone=internal --add-interface=enp0s9

    変更が適用されたことを確認します。

    sudo firewall-cmd --get-active-zones
    internal
      interfaces: enp0s9
    public
      interfaces: enp0s8
  3. 外部ネットワーク・インタフェースでNATモード(マスカレード)を構成します。たとえば:

    sudo firewall-cmd --zone=public --add-masquerade
    sudo firewall-cmd --permanent --zone=public --add-masquerade

    オプションで、各NATモードを問い合せて、両方が正しく設定されていることを確認できます。publicゾーンの問合せはyesレスポンスを返し、internalゾーンの問合せはnoレスポンスを返します。

    sudo firewall-cmd --zone=public --query-masquerade
    sudo firewall-cmd --zone=internal --query-masquerade
  4. ファイアウォールに対してまだ有効にしていない場合、外部ネットワーク・インタフェースと内部ネットワーク・インタフェースの間の転送ルールを構成します。次に例を示します。

    sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -i enp0s8 -o enp0s9 -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -i enp0s9 -o enp0s8 -j ACCEPT
    sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -j REJECT --reject-with icmp-host-prohibited
    sudo firewall-cmd --reload
  5. Keepalivedにより処理するサービスまたはポートへのアクセスを有効にします。

Keepalived NATモード・ロード・バランシングのためのバックエンド・サーバー・ルーティングの構成

Keepalivedロード・バランサで使用する各バックエンド実サーバーで、ルーティング表に、ロード・バランサの内部ネットワーク・インタフェースの仮想IPアドレスのデフォルト・ルートが含まれていることを確認してください。

たとえば、仮想IPアドレスが10.0.0.100である場合、ipコマンドを使用してルーティング表を調べます。

sudo ip route show
10.0.0.0/24 dev enp0s8  proto kernel  scope link  src 10.0.0.71

ipコマンドを使用してデフォルト・ルートを追加し、変更を確認することもできます。

sudo ip route add default via 10.0.0.100 dev enp0s8
sudo ip route show
default via 10.0.0.100 dev enp0s8 
10.0.0.0/24 dev enp0s8  proto kernel  scope link  src 10.0.0.71 

enp0s8のデフォルト・ルートをシステムの再起動後も維持するには、ファイル/etc/sysconfig/network-scripts/route-enp0s8ファイルを作成します。

sudo echo "default via 10.0.0.100 dev enp0s8" |sudo tee /etc/sysconfig/network-scripts/route-enp0s8

HAProxyでのKeepalivedを使用したロード・バランシングの拡張

Keepalivedを使用して、バックアップ・ルーターにフェイルオーバー・サービスを提供できますが、同時にロード・バランシングにHAProxyを使用し、分散サーバー間で高可用性を実現することもできます。このアプローチの利点は、パケットおよびアプリケーション・レイヤーが分離されていることです。つまり、ロード・バランシング・サーバーでKeepalivedによって実行されるヘルス・チェックは、HAproxyが管理するインバウンドHTTPまたはTCPトラフィックの影響を受けません。また、VRRPを使用して実行されるフェイルオーバー・ルーティングも、タイムアウトへのクライアントのレスポンスを待たずに自動的にアクティブ化できます。VRRPの有用性の詳細は、「VRRPでのKeepalivedの使用」を参照してください。

この方法の使用が現実的であるのは、パブリック対応のHAProxyロード・バランサがオフラインになった場合、Keepalivedによってこのイベントが自動的に検出され、別のHAProxyサーバーに動的に切り替えられるという点です。Keepalivedプライマリ・ルーターがオフラインになると、設定したVRRP設定により、トラフィックは自動的にKeepalivedバックアップルータで処理されます。

設定におけるHAProxyの役割は、インバウンド・ロード・バランシングおよびセッション永続性をバックエンド・サーバーに提供することです。Keepalivedは、HAProxyのステータスの監視と代替ルーティング・メカニズムの提供のみを実行します。両方のツールを組み合せて使用すると、可用性が高く、自己回復性を備えたロード・バランシング・ソリューションが得られます。

次の例の手順は、NATモードでのロード・バランシングの設定の手順と同様です。ただし、ここでは、HAProxyがKeepalivedプライマリ・サーバーとKeepalivedバックアップ・サーバーの両方にインストールされています。

外部仮想IPアドレスは、192.168.1.0/24外部ネットワーク上の192.168.1.1です。このIPアドレスは、NATを介して、IPアドレスが192.168.1.10のKeepalivedプライマリ・サーバーと外部IPアドレスが192.168.1.11のKeepalivedバックアップ・サーバーの間に動的に割り当てられます。

内部ネットワークは、10.0.0.0/24サブネットでホストされます。IPアドレスの場合、websvr1には10.0.0.71websvr2には10.0.0.72があります。

図3-2 高可用性ロード・バランシングのためのKeepalivedおよびHAProxy構成


この図は、HAProxyを実行しているKeepalivedプライマリ・サーバーのネットワーク・アドレスが192.168.1.10、10.0.0.10および10.0.0.100 (仮想)であることを示しています。また、HAProxyを実行しているKeepalivedバックアップ・サーバーのネットワーク・アドレスは192.168.1.11および10.0.0.11であり、現在のプライマリ・ルーターが使用できなくなった場合は新しいプライマリ・ルーターになります。IPアドレスの場合、websvr1には10.0.0.71、websvr2には10.0.0.72があります。

次の例に、プライマリ・サーバーの/etc/keepalived/keepalived.confファイルの構成を示します

global_defs {
 
  notification_email {
    root@example.com
  }
 
  notification_email_from srv1@example.com
  smtp_server localhost
  smtp_connect_timeout 30
}
 
vrrp_sync_group vg1 {
  group {
    external
    internal
  }
}
 
vrrp_script chk_haproxy {
  script "killall -0 haproxy" # check the haproxy process
  interval 2 # every 2 seconds
  weight 2 # add 2 points if OK
}
 
vrrp_instance external {
  state MASTER
  interface enp0s8
  virtual_router_id 91
  priority 200
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 1215
  }
  virtual_ipaddress {
    192.168.1.1/24
  }
  track_script {
    chk_haproxy
  }
}
 
vrrp_instance internal {
  state MASTER
  interface enp0s9
  virtual_router_id 92
  priority 200
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 1215
  }
  virtual_ipaddress {
    10.0.0.100/24
  }
}    
      

前の例では、バックアップKeepalivedサーバーの構成は同じですが、state値はBACKUPに設定する必要があります。このシナリオでは、Keepalivedはトラフィックのルーティングにのみ使用され、ロード・バランシングを実行しないため、virtual_serverを設定する必要はありません。

Keepalivedの構成および適切なファイアウォール・ルールの設定の詳細は、Keepalivedを使用したロード・バランシングの設定を参照してください。

HAProxy設定は、/etc/haproxy/haproxy.cfgファイルに構成されます。Keepalivedは自動的に構成間で動的にルーティングされるため、どちらのHAProxyインストールでも設定は同じです。

global
  daemon
  log 127.0.0.1 local0 debug
  maxconn 4000
  nbproc 1
 
defaults
  mode          http
  retries       3
  timeout connect 5s
  timeout client 25s
  timeout server 25s
  timeout queue 10s

listen http-incoming
  mode http
  bind internal-server-ip:80
  option http-server-close
  option forwardfor
  default_backend app

backend app
  balance roundrobin
  option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost
  option httpclose
  option forwardfor
  server websrv1 192.168.1.71:80 weight 1 maxconn 512 check
  server websrv2 192.168.1.72:80 weight 1 maxconn 512 check

前述の例では、option http-server-closeおよびoption httpcloseオプションを使用してアイドル接続を停止します。この構成では、ラウンド・ロビン・ロード・バランシング戦略を示します。オプションを指定しない場合、HAProxyはデフォルトでoption http-keep-aliveオプションを使用し、関連付けられているリクエストおよびレスポンス・ジャーニーがすべて処理されるまで新しい接続を開いたままにします。

HAProxyの構成および適切なファイアウォール・ルールの設定の詳細は、HAProxyを使用したロード・バランシングの設定を参照してください。