ニフクラ ブログ

ニフクラ/FJ Cloud-Vやクラウドの技術について、エンジニアが語るブログです。

ニフクラのマルチIPアドレスサービスとkeepalivedでサーバーの冗長化をしてみた

こんにちは。富士通クラウドテクノロジーズの米澤です。

ニフクラではマルチIPアドレスというサービスを提供しています。 このサービスによって、複数のグローバルIPアドレスを、ニフクラ上のサーバーに自由に割り当てて使用することが可能になります。 具体的には、以下のような運用を想定しています。

  • 複数のサーバーで1つの仮想IPアドレスを共有し、サーバーの負荷分散や冗長化を行う
  • 1つのサーバーで複数の仮想IPアドレスを使う、マルチサイトの構築

今回は、サーバーの冗長化によく使われているミドルウェアkeepalivedによる冗長化構成を例に、マルチIPアドレスサービスをご紹介します。

本記事のゴール

  • ニフクラ上で「マルチIPアドレス」+「keepalived」を用いた冗長化構成を組むことができる
  • 仮想IPアドレスへのアクセスについて、サービスを提供するサーバーが停止したときに、もう一方のサーバーが代わりにパケット処理を行うことを確認する

前提条件

本ブログ記事は、以下の前提知識がある方を想定しています。

  • ニフクラの基本的なコントロールパネル(管理画面:以降コンパネ)の操作、サービスを利用する知識 (サーバー作成、ネットワーク構築など)
  • Linuxの基本的な操作、知識

ネットワーク構成

冗長化構成による挙動

まず、冗長化構成の簡単な説明のために、1つの仮想IPアドレスを2台のサーバーで共有すると仮定して、どのような挙動になるかをまとめてみました。

仮想IPアドレスを共有するサーバー間にはMasterBackupという状態が存在します。 基本的にはMaster状態のサーバーが仮想IPアドレスに送信されたパケットの処理を行います。 (一方でBackup状態のサーバーはMaster状態のサーバーが正常かどうかを監視しています。)

もしも何らかの原因でMaster状態のサーバーのサービスが停止した場合、Backup状態のサーバーがそれを検知して仮想IPアドレス宛ての通信の処理を行うよう自動的に切り替わります。

例として1つの仮想IPv4アドレスを2台のサーバーで共有し、これらの2台のサーバーを「ServerA」、「ServerB」と呼びます。 初期の状態(Master/Backup)は以下のように設定します。

サーバー名 デフォルトの状態
ServerA Master
ServerB Backup

ServerAが正常なときの挙動

f:id:byeron:20200715111424p:plain

ServerAのサービスが停止しているときの挙動

f:id:byeron:20200715111506p:plain

作成するサーバーの構成

改めて、以下の構成で実際に構築を行います(IPアドレス、MACアドレス、インターフェイス名は架空のものです)。

サーバー名 IPアドレス MACアドレス インターフェイス名
SVmultiIPA 192.0.2.1 00-00-5E-00-53-01 ens160
SVmultiIPB 192.0.2.2 00-00-5E-00-53-02 ens160
(Masterと同じ) 192.0.2.3(仮想) 00-00-5E-00-53-03(仮想) Masterと同じ
(ゲートウェイ) 192.0.2.10 省略 省略
(作業環境) 198.51.100.1 省略 省略

のちに設定しますが、初期でMaster状態となるサーバーはSVmultiIPAです。 f:id:byeron:20200715111542p:plain

また、ニフクラ上でサーバーを作成する際に自動的にグローバルのIPアドレスが割り振られます。一時的ではありますが、今回はそのIPアドレスに対してssh接続する必要があるため、以下の通りグローバルIPアドレスを示します。

  • SVmultiIPA: 203.0.113.1
  • SVmultiIPB: 203.0.113.2

※これらのIPアドレスはマルチIPアドレス割り当て後に使用できなくなります。

環境(ニフクラ上で作成)

  • サーバー(OS: CentOS 7.7)x 2

大まかな流れ

  1. ファイアウォールグループ作成
  2. SSHキー作成
  3. CentOS7.7のサーバー作成
  4. マルチIPアドレスグループ作成
  5. 作成されたサーバーに対するsshの接続確認
  6. ユーザー作成
  7. 各サーバーに対してマルチIPアドレスの割り当て
  8. ネットワーク設定の編集 + 反映
  9. keepalivedの設定を編集 + 反映

青色はニフクラコンパネからの操作、赤色はお客様の作業環境からの操作、緑色はニフクラのWebコンソールからの操作をそれぞれ示しています。

ファイアウォールグループ作成

冗長化構成をとるサーバーに適用するファイアウォールをあらかじめ作成します。 ファイアウォールの設定はこちら(ファイアウォールグループの新規作成)に沿って行います。

今回は「FWmultiIP」という名前を付けたファイアウォールグループを作成し、以下のIn/Outルールを適用します。 このファイアウォールは手元の作業環境からの通信を行うために設定します。

f:id:byeron:20200618114513p:plain

Inルール

  • ssh(作業環境からssh接続するため)
  • ICMP(のちの検証でping疎通を確認するため)
  • (お客様のサービスに応じたポート)

接続元種別」については作業環境からの接続を許可する必要があり、ここではどちらもANYとしました。 また、ニフクラの仕様上、同一のファイアウォールグループに所属するサーバー間ではすべての通信を許可するのでVRRPを許可するルール等は必要ありません。 加えて今回はpingコマンドによる疎通を確認するためにICMPを許可していますが、実際はお客様のサービスに必要なポートをInルールとして適用してください。

f:id:byeron:20200618095605p:plain

Outルール

  • 設定なし

実際はお客様のサービスに応じてOutルールを設定していただく必要がありますが、 今回の環境では、作業環境からの通信に対する応答以外でファイアウォールグループ内から作業環境に向けて通信はないため、特にOutルールの設定は行っておりません。

f:id:byeron:20200618095750p:plain

ファイアウォール作成については以上です。 実際の運用においては安全のため適切にファイアウォールを設定してください。

SSHキー作成

作成したサーバーにssh接続するためのSSHキーをあらかじめ作成します。 今回は「SSHmultiIP1」と「SSHmultiIP2」という名前を付けた2組のSSHキーをこちら(SSHキー)の手順に沿って作成します。

サーバー作成

ニフクラのコンパネからCentOS.7.7のサーバーを作成します。 サーバー作成はこちら(サーバーの作成)に沿って行います。

今回は「SVmultiIPA」と「SVmultiIPB」という名前を付けた2台のサーバーを作成します。「SVmultiIPA」の作成を例に手順を説明します。

  1. OSイメージは「CentOS7.7」を選択f:id:byeron:20200618113930p:plain
  2. サーバーを作成するゾーンを選択後、サーバータイプとして「e-mini」を選択f:id:byeron:20200618114010p:plain
  3. 「サーバー名」は「SVmultiIPA」を設定
  4. 「料金プラン」は「従量」
  5. 「SSHキー」はプルダウンメニューから「SSHmulti1」を選択
  6. 「ファイアウォール」はプルダウンメニューから「FWmultiIP」を選択
  7. 「ネットワーク」はグローバル、共通プライベートともに「自動割り当て」を選択

以上の手順で下図のサーバー設定となっていることを確認したら、サーバーを作成します。 f:id:byeron:20200618120720p:plain

サーバー作成については以上です。

マルチIPアドレスグループ作成

ニフクラのコンパネからマルチIPアドレスグループを作成します。 マルチIPアドレスグループはこちら(マルチIPアドレスグループ作成)に沿って作成します。

今回は「GmultiIP」という名前を付けたマルチIPアドレスグループを作成します。マルチIPアドレスは、仮想IPv4アドレス1つ+2台のサーバに1つずつ割り当てるための実IPv4アドレス2つの計3つ用意します。

  1. 「マルチIPアドレスグループ名」は「GmultiIP」を設定
  2. 「ゾーン」は任意のゾーンを選択
  3. 「確保するIPアドレス数」は3を選択(仮想IPv4アドレスx1 + 実IPv4アドレスx2)

以上の手順で下図のマルチIPアドレスグループとなっていることを確認したら、マルチIPアドレスグループを作成します。 f:id:byeron:20200618131736p:plain

ニフクラのコンパネ上で以下の表示となれば、マルチIPアドレスグループが作成されています。 f:id:byeron:20200709114910p:plain

マルチIPアドレスグループ作成については以上です。

作成したサーバーに対するsshの接続確認

ここからは手元にssh接続できる端末をご用意ください

この項目は「SVmultiIPA」と「SVmultiIPB」のそれぞれに対して行います。 ここでは「SVmultiIPA」を例に説明します。 まずはコンパネから、サーバーに割り当てられたグローバルIPアドレスを確認します

f:id:byeron:20200709114958p:plain

グローバルIPアドレスが確認できたら、お手元の作業環境で「SVmultiIPA」にssh接続します(今回はSVmultiIPA_ip203.0.113.1)。

$ chmod 0600 ${your_ssh_private_key}
$ ssh -p 22 -i ${your_ssh_private_key} root@${SVmultiIPA_ip}

ここで、${variable}は変数を示します。お客様の環境に合わせて適宜書き換えてください。

接続が確認出来たら、まずはリポジトリの更新を行います

$ yum update

ユーザー作成(Webコンソールからのアクセスに必要となります)

次に、Webコンソールからサーバーへアクセスするためにsudo権限を持つ任意のユーザー(user_name)を作成します。

#user_nameを持つユーザーを追加
$ useradd -m -s /bin/bash ${user_name}

#sudo権限を付与するため、ユーザーをwheelグループに追加
$ gpasswd -a ${user_name} wheel

#ログインするためのパスワードを設定
$ passwd ${user_name}

パスワードが正しく設定されていることを確認できればokです。 「ssh接続の確認」と「ユーザー作成」の操作を「SVmultiIPB」に対しても行います。

各サーバーに対してマルチIPアドレスの割り当て

(ここで再びコンパネからの操作となります)

コンパネのマルチIPアドレスから「GmultiIP」を選択し、マルチIPアドレスを割り当てるサーバーを選択します。(左のチェックボックスで適用するサーバーを選択し、一台ずつマルチIPアドレスを割り当ててください) f:id:byeron:20200709115037p:plain

マルチIPアドレスの設定が反映され次第、コンパネの「サーバー」の表示を確認します。 現時点でステータスは「異常あり」となっていますが問題ありません。 ここで各サーバーの詳細表示から「ネットワーク」を確認し、「マルチIPアドレス」と対応するMACアドレスをメモしておきます。 f:id:byeron:20200709115109p:plain

この時点で作業環境からのssh接続は一時的に不可能となるため、ニフクラのWebコンソール上からの作業が必要となります。(サーバーのステータスが「正常」に戻ればマルチIPアドレスから割り当てた実IPアドレスに対するssh接続が可能となります。)

ネットワーク設定の編集 + 反映

(ここからはWebコンソールからの操作となります。接続方法はこちら

この項目は「SVmultiIPA」と「SVmultiIPB」のそれぞれに対して行います。 ここでは「SVmultiIPA」を例に説明します。

まず、先ほど作成したユーザー(user_name)とパスワードでコンソールにログインします。 コンソールにログイン後、マルチIPアドレスを割り当てられたインターフェース名をip aコマンドで確認します。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00-00-5E-00-53-01 brd ff:ff:ff:ff:ff:ff
    inet 203.0.113.1/24 brd 192.0.2.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe89:89f7/64 scope link 
       valid_lft forever preferred_lft forever

インターフェース名(今回はens160)に対応したネットワーク設定(/etc/sysconfig/network-scripts/ifcfg-ens160)を編集します。

#任意のテキストエディタでネットワーク設定ファイルを編集
$ vi /etc/sysconfig/network-scripts/ifcfg-ens160

/etc/sysconfig/network-scripts/ifcfg-ens160を書き換えます。 コンパネの「マルチIPアドレス」の情報を参考に編集します。 f:id:byeron:20200709115146p:plain 手作業でのIPアドレスの書き換えは打ち間違えが起きる可能性があるので慎重にお願いします。

DEVICE=ens160 # 対応するインターフェース名を記述
BOOTPROTO=none
ONBOOT=yes
PEERDNS=no
DNS1=127.0.0.1
IPADDR1=192.0.2.1 # ニフクラコンパネ上の「マルチIPアドレスグループ」で割り当てられたマルチIPアドレスの一つを記述
NETMASK1=255.255.255.0
GATEWAY1=192.0.2.10 # ニフクラコンパネ上で「マルチIPアドレスグループ」-> 「デフォルトゲートウェイ」のIPアドレスを記述

次に編集内容を反映します。以下のコマンドを実行後にnetworkがActiveであることを確認してください。

$ systemctl restart network
$ systemctl status network

ネットワーク設定の操作を「SVmultiIPB」に対しても行います。

keepalivedの設定を編集 + 反映

(ここからは、先ほど設定したSVmultiIPAとSVmultiIPBのIPアドレス(192.0.2.1、192.0.2.2)を使って作業端末からssh接続を行い作業します。)

keepalivedの設定項目は「SVmultiIPA」と「SVmultiIPB」で作業が異なるため、気を付けて作業を進めましょう。

(「SVmultiIPA」・「SVmultiIPB」共通作業) keepalivedをインストールし、任意のテキストエディタでkeepalivedの設定(/etc/keepalived/keepalived.conf)を編集する。

$ yum install keepalived
# バックアップ作成
$ cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org
$ vi /etc/keepalived/keepalived.conf

(「SVmultiIPA」での作業) keepalived.confに対して以下の内容を記述します。追記ではなく何も書かれていないファイルにこの内容を記述します

! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict # Master時に仮想IPアドレス宛の通信を受け取るためにコメントアウト
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160 # マルチIPアドレスに対応するインターフェース名
    virtual_router_id 51 # 冗長化させたいルーター間で同じルーターidとなるよう適切に値を変更してください
    priority 200  # デフォルトの100より高く設定(1-254まで割り当て可能)
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111 # 冗長化させたいルーター間で同じauth_passとなるよう適切に値を変更してください
    }
    virtual_ipaddress {
        192.0.2.3 # ニフクラコンパネ上で割り当てられた仮想IPアドレスを設定
    }
}

「SVmultiIPA」のpriorityを「SVmultiIPB」よりも高い値(今回は200)に設定することで、デフォルトでMasterとして選択されます。

(「SVmultiIPB」での作業) keepalived.confに対して以下の内容を記述します。

! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   #vrrp_strict # Master時に仮想IPアドレス宛の通信を受け取るためにコメントアウト
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens160 # マルチIPアドレスに対応するインターフェース名
    virtual_router_id 51 # 冗長化させたいルーター間で同じルーターidとなるよう適切に値を変更してください
    priority 100 # デフォルトのまま変更しない(1-254まで割り当て可能)
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111 # 冗長化させたいルーター間で同じauth_passとなるよう適切に値を変更してください
    }
    virtual_ipaddress {
        192.0.2.3 # ニフクラコンパネ上で割り当てられた仮想IPアドレスを設定
    }
}

(「SVmultiIPA」・「SVmultiIPB」共通作業) 次に編集内容を反映します。以下のコマンドを実行後にkeepalivedがActiveであることを確認してください。

$ systemctl restart keepalived
$ systemctl status keepalived

以上でkeepalivedの設定は終了です。ニフクラコンパネ上の「サーバー」のステータスが正常になれば、冗長化設定が反映されています。

検証

次に、今回構築した冗長化構成について以下の3点について検証します。

  1. 作業環境から仮想IPアドレスに対してpingコマンドを受けての応答がある
  2. 作業環境から実行されたpingに対して、「Master」状態のサーバーがパケットを受け取っている
  3. 「Master」状態のサーバーから死活確認のためのVRRPパケットが送信されない場合、「Backup」状態のサーバーが「Master」状態に切り替わりパケットの処理を行う

作業環境から仮想IPアドレスにpingコマンドを受けての応答がある

まず、1「作業環境から仮想IPアドレスにpingコマンドを受けての応答がある」について検証します。

今回はお客様の作業環境を疑似的に再現するために、ニフクラ上で別のサーバーを立ち上げてpingによる疎通確認を行います。 作業環境のファイアウォールにICMPをフィルタするIn/Outルールがないことを確認し、 以下のコマンドで仮想IPアドレス(VIP192.0.2.3)に対してpingコマンドを実行します。

$ ping ${VIP}

pingの応答が確認できればokです。

作業環境から実行されたpingに対して、「Master」状態のサーバーがパケットを受け取っている

次に作業環境から仮想IPアドレスに向けて送られたpingコマンドによるパケットを仮想IPアドレスを持つサーバー側から確認します。

作業環境からは先ほどと同じようにpingコマンドによるパケットを仮想IPアドレス宛てに送りながら、別の窓でMaster状態のサーバー(SVmultiIPA)にssh接続します。 このとき、サーバーの実IPアドレス(今回はSVmultiIPA_ip192.0.2.1)を使ってssh接続をすることを忘れないようにしましょう。

$ ssh -p 22 -i ${your_ssh_private_key} root@${SVmultiIPA_ip}

「SVmultiIPA」側では作業環境から送られてきたpingコマンドによるパケットを受け取っているかどうかをtcpdumpで確認します。 「SVmultiIPA」のグローバルIPと紐づいているインターフェース名や作業環境のIPアドレスはあらかじめip aで確認してください。 (今回はNW_interfaceens160Workspace_ip198.51.100.1

$ tcpdump -i ${NW_interface} icmp and host ${Workspace_ip}

「SVmultiIPA」で以下のようなパケットが取得できれば成功です。Master状態のサーバーが作業環境から送られてきたpingコマンドによるパケット(ICMP)を受け取っています。

10:07:47.292359 IP 198.51.100.1 > localhost.localdomain: ICMP echo request, id 20010, seq 1, length 64
10:07:47.292385 IP localhost.localdomain > 198.51.100.1: ICMP echo reply, id 20010, seq 1, length 64
10:07:48.293580 IP 198.51.100.1 > localhost.localdomain: ICMP echo request, id 20010, seq 2, length 64
10:07:48.293603 IP localhost.localdomain > 198.51.100.1: ICMP echo reply, id 20010, seq 2, length 64
10:07:49.295011 IP 198.51.100.1 > localhost.localdomain: ICMP echo request, id 20010, seq 3, length 64
10:07:49.295028 IP localhost.localdomain > 198.51.100.1: ICMP echo reply, id 20010, seq 3, length 64
10:07:50.296125 IP 198.51.100.1 > localhost.localdomain: ICMP echo request, id 20010, seq 4, length 64
10:07:50.296146 IP localhost.localdomain > 198.51.100.1: ICMP echo reply, id 20010, seq 4, length 64

また、このときにBackup状態の「SVmultiIPB」でtcpdumpによるパケットキャプチャを行うと、「SVmultiIPB」側では作業環境からpingコマンドによるパケットを受け取っていないことが同時にわかります。

VRRPパケットによる「Master」状態のサーバーの死活確認ができない場合、「Backup」状態のサーバーが「Master」状態に切り替わりパケットの処理を行う

「SVmultiIPA」と「SVmultiIPB」に対して2窓で同時にssh接続し、手元の作業環境からは仮想IPアドレス宛てにpingコマンドを実行し続けます。 先ほどの検証で、仮想IPアドレス宛てのパケットはMaster状態のサーバーにすべて振り分けられることが分かっています。 ここで意図的にMaster状態のサーバーを停止させて、作業環境のpingコマンドによるパケットはどうなるか確認しましょう。

「SVmultiIPB」に対してtcpdumpを使って作業環境からのパケットをキャプチャします。現時点では仮想IPアドレス宛てのpingコマンドによるパケットを「SVmultiIPB」側では受け取っていません。

$ tcpdump -i ${NW_interface} icmp and host ${Workspace_ip}

ここで、「SVmultiIPA」のkeepalivedを停止します。

$ systemctl stop keepalived

数秒後に「SVmultiIPB」側が仮想IPアドレス宛てのpingコマンドによるパケットを受け取っていることが分かります。 これは「SVmultiIPB」が「SVmultiIPA」の停止を検知し、Backup状態からMaster状態に移行したためです。

注意してほしい点は以下の過程でパケットを落とす可能性があります。

  1. Master状態のサーバーの停止
  2. Backup状態のサーバーがそれを検知(今回は検知までに最大5秒かかる)
  3. Backup状態のサーバーがMaster状態に移行
  4. 新しくMaster状態に移行したサーバーが仮想IPアドレス宛のパケットを受け取る

これはサーバーの状態を監視する間隔を決定するパラメーター(advert_int)がkeepalived.confに設定されており、今回は5秒に設定されているためです。

検証結果

検証により本記事のゴールである以下の2点について達成することができました。

  • ニフクラ上で「マルチIPアドレス」+「keepalived」を用いた冗長化構成を組むことができる
  • 仮想IPアドレスへのアクセスについて、どちらかのサーバーのサービスが停止したときにもう一方のサーバーが代わりにパケットを受け取ることができることを確認する

まとめ

本記事ではニフクラのマルチIPアドレスサービスの紹介を行い、検証例としてkeepalivedを用いた冗長化構成を実際に構築しました。 また、仮想IPアドレス宛に通信をすることで各々のサーバーがどのように振舞うかを検証しました。 その結果、「Master」サーバーのサービスが停止した場合、仮想IPアドレス宛ての通信が「Backup」サーバーに振り分けられることが分かりました。

あくまでも今回紹介したのはニフクラのマルチIPサービスを用いたネットワーク構築の一例ですが、 この記事がお客様の導入の手掛かりになることを願っています。

注意事項

  • 本記事については検証結果の1つとなります。実際に導入を検討される場合は、事前にサーバーの切り替わりによる通信断の影響などの要件を鑑みて実装するかどうかを判断してください。
  • 本記事ではOS上の操作についても記載していますが、ニフクラではOS以上はお客様の責任範囲となりますのでご留意ください。
  • 本記事で記載した各サービス/ニフクラの機能等は、2020年7月時点の情報です。利用時には各サービス/ニフクラの機能の最新情報をご確認いただいた上でご利用ください。