1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

3.4.2 キープアライブを用いたLVSのHA構成

Posted at

(2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報はIBM Cloud アップデート情報柔らか層本をご参照ください。)

概要
キープアライブ(Keepalived)をつかってLVSの高可用性(High Availability)構成をご紹介します。 LVSはウェブサーバー、KVS(Key-Value Store)、メモリキャッシュの負荷分散と高可用性のために、たいへん良く利用されています。 特にLVSは、データベースのアクセス負荷を軽減してレスポンスを改善するためにAPサーバーとDBサーバーの間で多く利用されています。 さらに、今回はMySQLのリード・レプリカを構成例を通してご紹介していきます。

LVSの高可用性構成
LVS (Linux Virtual Server)は、安価に構築できるのに高性能なロードバランサーとして、たいへん重宝されています。 このLVSをアクティブ・スタンバイ方式の高可用性の構成するために、キープアライブが利用されます。 SoftLayerでは、APサーバーとDBサーバー間など、プライベート・ネットワークの通信に対して、ローカル・ロードバランサーや高可用性の提供がありません。 しかし、LVSを利用することで、この課題を解決することができます。 LVSの概要説明は3.4 アクティブ・スタンバイのサーバーを構成するには?、シングル構成の設定方法は3.3 ロードバランサーを利用するには?をご参照お願いします。

次の図のLVSの左側のクライアントは、VIP(仮想IPアドレス)に向かってアクセスします。 そして、右側のサーバー群へ分散してアクセスします。 障害や保守のために、アクティブのLVSが停止した場合、スタンバイのLVSヘVIPが移動することで、クライアントは継続してVIPにアクセスして処理を継続することができます。 一方、LVSの右側にはMySQL, KVS, memcachedを配置して、応答を返せないサーバーへのアクセスを止めるために利用します。 次の図の中では、MySQLサーバーのリードレプリカに対する負荷分散の例です。

ウェブのよるカタログ販売の場合、そのほとんどが、カタログを閲覧しながら欲しい商品を探し求めるユーザーのアクセスとなり、商品データベースへの接続の殆どが、読取りアクセスとなります。 ここで快適な応答速度で表示ができなければ、ユーザーは去って行ってしまいます。 このため、MySQLの負荷分散は重要なテーマです。 KVSを使ってSQL文をキーとして結果をバリューに保管することで、MySQLの負荷を下げ、検索速度を劇的に改善する手法もありますが、ここでは、MySQLの読取り専用レプリカを複数準備してLVSで負荷分散する方法を例に挙げます。 この方法では、アプリケーションで、KVSをアクセスするためのコードを書かなくても良いため、実装が簡単になるメリットがあります。

VIPは、仮想サーバーや物理サーバーの起動時に付与されるIPアドレス以外のものを利用する必要があります。 クラウドの環境では、同じサブネットの空いているIPアドレスを適当にVIPとして使うと、IPアドレスは、クラウドの管理システムが割当を行なうため、新しく起動するサーバーのIPアドレスと同じになるといった障害になる恐れがあります。 そこで、SoftLayerでは、ポータブルIPという機能を活用します。 この機能の利用方法は、4.2 サーバーが変わっても同じIPアドレスを利用するには?をご参照お願いします。

構成に必要な材料の注文
具体的な構成では、次の図のようにLVSを一つのVLAN内だけで利用します。 LVSのVIPは、プライベート・アドレスを設定して、同じプライベートVLAN内のサーバーへ負荷分散することを実装していきます。

上記の構成を作るために、次の3点をカスタマーポータル ( https://control.softlayer.com/ )から注文します。

  1. 仮想サーバー CentOS 6.x - Minimal Install (64 bit) x 2 LVSのアクティブとスタンバイ
  2. 仮想サーバー CentOS 6.x - LAMP Install (64 bit) x 4 MySQLマスタ・サーバー x1, MySQLリード・レプリカ x2, アプリケーション・サーバー x1
  3. ポータブルIPアドレス(8 Portable Private IP Addresses)× 1 VIP用

LVS用として「仮想サーバー CentOS 6.x - Minimal Install (64 bit)」を注文します。 最初のサーバーの設定後に取得したイメージ・テンプレートから複製サーバーを起動して、アクティブ・スタンバイの設定を追加していきます。 MySQLのマスター、リード・レプリカ、ウェブサーバー用に「仮想サーバー CentOS 6.x - LAMP Install (64 bit)」を注文します。 「LAMP Install」は、Apache HTTP server、MySQL、PHPが最初から稼働できる状態でサーバーが起動してきます。 一方「Minimal Install」は、Linuxディストリビューションの最小限の導入になっています。

VIPのためのプライベートのポータブルIPアドレスは、無料ですので少し多めに、8個を確保しておきます。 この8個の内、3つはゲートウェイ、ネットワークアドレス、ブロードキャストアドレスとして、予約されていますので、5個を使うことができます。 ただし、プライベートの場合、SoftLayerのHSRPの予約アドレスが含まれることがあり、3個しか使えないことがあります。

これらの注文の方法は、仮想サーバーは1.2 仮想サーバーを起動するには?、ポータブルIPアドレスは4.2 サーバーが変わっても同じIPアドレスを利用するには?を参照してください。 そして、2台目のサーバーを作るには、「3.2.サーバーを複製するには?」の方法を利用していきます。 ここでは、判り易くするために、最初にまとめて注文するようにしていますが、仮想サーバーの費用を節約するには、必要な都度、注文する方法もあります。

LVSサーバーの追加ソフトウェアのインストール
仮想サーバーが起動したら、sshでログインして、KVSを設定を進めていきます。 仮想サーバーにログインする方法は、1.4 サーバーへログインするには?を参照してください。

仮想サーバーの起動直後は、OSの導入イメージ作成時点のソフトウェア更新レベルのため、現在までのアップデートを適用します。 これは以降の作業にとって重要なので必ず実施します。

# yum update

LVSのソフトウェアの導入を以下のコマンドで実行します。

# yum install ipvsadm keepalived

導入したサービスが、自動起動するように設定します。

# chkconfig ipvsadm on
# chkconfig keepalived on

複数のethインタフェース間でパケットの転送を許可するため /etc/sysctl.conf に、net.ipv4.ip_forward = 1 を設定します。

# vi /etc/sysctl.conf
# cat /etc/sysctl.conf
...省略
# Controls IP packet forwarding                        
net.ipv4.ip_forward = 1           <--  1 へ変更する

編集した設定をカーネルに反映させるため、以下のコマンドを実行します。

# sysctl -p

LVSのアクティブ側設定
アクティブ・スタンバイの構成のため、キープアライブの /etc/keepalived/keepalived.conf を編集します。 変更箇所は「<--」で注釈しています。

[root@lvs1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

vrrp_instance vip_1 {
    state MASTER     <--  アクティブは「MASTER」、スタンバイは「BACKUP」と設定
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.66.136.58/32 dev eth0     <-- VIP と ネットワークインターフェース
    }
}

virtual_server 10.66.136.58 3306 {
    delay_loop 6
    lb_algo wlc     <-- 負荷分散アルゴリズムは、コネクション数と重み付けによる負荷分散
    lb_kind DR      <-- 転送方式は、ダイレクト・ルーティング
    nat_mask 255.255.255.0
    persistence_timeout 50
    protocol TCP

    real_server 10.67.24.196 3306 {  <-- MySQL リードレプリカ #1
        weight 1
        TCP_CHECK {
          connect_ip 10.67.24.196
          connect_port 3306
        }
    }

    real_server 10.67.24.198 3306 {  <-- MySQL リードレプリカ #2
        weight 1
        TCP_CHECK {
          connect_ip 10.67.24.198
          connect_port 3306
        }
    }
}

これで、LVSのアクティブ側のキープアライブの設定が完了しました。 サービスを起動しておきます。

# service ipvsadm start
# service keepalived start

ここでスタンバイ側の設定は完了していませんが、以下のように、VIPが有効になっていることがわかります。

# ip addr show dev eth0
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 06:ac:64:68:be:bf brd ff:ff:ff:ff:ff:ff
    inet 10.67.24.200/26 brd 10.67.24.255 scope global eth0     <-- 仮想サーバーのI/Fアドレス
    inet 10.66.136.58/32 scope global eth0                      <-- VIP
    inet6 fe80::4ac:64ff:fe68:bebf/64 scope link
       valid_lft forever preferred_lft forever

さらに、次のコマンドで、キープアライブの設定ファイルの内容が、IPVS(IP Virtual Server: ロードバランサ機能を持つLVSの構成要素)に反映されていることが確認できます。

[root@lvs1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.66.136.58:3306 wlc persistent 50
  -> 10.67.24.196:3306            Route   1      0          0        
  -> 10.67.24.198:3306            Route   1      0          0      

LVS用の仮想サーバーの複製
ここまで作成してきた仮想サーバーをマスターのイメージにして、スタンバイになるサーバーを作成します。 この作成方法は、3.2 サーバーのクローンを作成するには?を参照してください。 イメージから新たなサーバーを起動する場合、元の仮想サーバーと同じVLANに作成する必要があります。 この理由は、VIPを利用するポータブルIPはVLANに割当られるためです。 新たに起動される仮想サーバーのIPアドレスは、異なるアドレスが付与され、ホスト名は起動時に指定したものが付与されます。

複製されたサーバーのIPアドレスのサブネットは、元になったサーバーと異なるサブネットに割り当てられる可能性がありますが、VLANが同じであれば、ポータブルIPを利用することに問題はありません。

LVSのスタンバイ側設定
イメージ・テンプレートから起動した仮想サーバーの /etc/keepalived/keepalived.conf の次の部分を「BACKUP」に値を変更します。

# vi /etc/keepalived/keepalived.conf

...省略
vrrp_instance vip_1 {
    state MASTER     <--  スタンバイは「BACKUP」と設定
    interface eth0
...省略

これで、LVSのスタンバイの設定が完了しましたので、サービスを起動します。

# service ipvsadm start
# service keepalived start

これで、LVSのアクティブ・スタンバイの設定が完了しました。 次に、LVSが負荷分散するMySQLのリードレプリカの設定に移っていきます。 ここで、次に説明する設定を行なわないで、VIPをアクセスして振り分けの確認をしてはいけません。 少しだけ我慢をお願いします。

MySQLのリードレプリカの設定 (LVSのリアルサーバー設定)
LVSがリクエストを振分け先は、同じプライベートIP側のMySQLリードレプリカのサーバーに転送するために、少し特別な設定が必要になります。 LVSのVIPに届いたパケットをダイレクトに転送するため、転送先のサーバーがパケットを自分のパケットとして受け取るように、ifcfg-lo:0ファイルを作成して、VIPアドレスを設定します。

[root@db2 ~]# cat /etc/sysconfig/network-scripts/ifcfg-lo:1
DEVICE=lo:1
IPADDR=10.66.136.58        <-- VIPのアドレス
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback

次の設定は、大変重要な設定で省略するとLVSが期待通りに動作しません。 イーサーネットでは、ARPによって、IPパケットの次の転送先を記憶する機能があります。 もし間違った値を周辺のルーターが記憶していまうと、キャッシュがリフレッシュされるまで、正しく通信できない状態になります。 次の設定は、この問題を回避するために、LVSの振り分け先のサーバーでARPを無視、また、通知しないというものです。 もしこの設定をしないで動かしてしまうと、LVSから来たパケットを処理する過程で、SoftLayer側のルーターへ、MySQLレプリカのサーバーである自己のMACアドレスが、VIPの代表アドレスとしてARPで通知します。 そうすると、それ以降は、VIPの転送先は、LVSではなくMySQLサーバー側に固定され、LVSをバイパスされ負荷分散が働かなくなります。

/etc/sysctl.confのファイルに次の4行を追加します。

net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

カーネルへ設定を反映させるためsysctlコマンドを実行します。

# sysctl -p

ループバック・インターフェースを有効にします。

# ifup lo:1

MySQLのマスターサーバーの設定
リードレプリカへ更新ログを提供するためのMySQLサーバーを設定した後、リードレプリカのMySQLサーバーを設定します。

# cat /etc/my.cnf
[mysqld]
server-id=100      <-- 複数のMySQLサーバーを連携させるため、識別子を設定  
log-bin=log-bin    <-- バイナリ形式のログを出力するように設定
character-set-server = utf8
collation-server = utf8_general_ci
...省略

設定を保存してMySQLサービスを開始します。 また、サーバーが再起動しても自動起動するように設定しておきます。

# service mysqld start
# chkconfig mysqld on

次のコマンドで、MySQLサーバーにログインして、レプリカサーバーの登録、レプリカへのデータ転送を進めていきます。

# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 38
Server version: 5.1.73-log Source distribution

リード・レプリカのユーザー、IPアドレス、パスワードを登録します。 負荷分散するリード・レプリカのサーバー数分だけ登録します。

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@10.67.24.196 IDENTIFIED BY 'Passw0rd';
Query OK, 0 rows affected (0.00 sec)

データを転送する前に、バッファを書き出してロックします。

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)

ログファイルの名前とポジションは、レプリカ側で開始前に設定する必要があるので、メモしておきます。

mysql> SHOW MASTER STATUS;
+----------------+----------+--------------+------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| log-bin.000003 |      257 |              |                  |
+----------------+----------+--------------+------------------+
1 row in set (0.00 sec)

MySQLのデータ領域を丸ごとレプリカ側へ転送します。 そして、他のすべてのレプリカ・サーバーへもコピーを実行します。

# cd /var/lib/mysql
# scp -r * 10.67.24.196:/var/lib/mysql

次のコマンドで、ロックを解除して、マスター側の設定は完了です。

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

MySQLのリードレプリカの設定
設定ファイルの変更します。 レプリカでは、バイナリーログの出力設定は不要です。

# cat /etc/my.cnf
[mysqld]
server-id=101      <-- 他のサーバーと異なる一意の識別子を設定  
character-set-server = utf8
collation-server = utf8_general_ci
...省略

コピーしたファイルは、オーナーを変更して、MySQLサーバーを起動します。 次回から自動起動にします。

# chown -R mysql:mysql /var/lib/mysql/
# service mysqld start
Starting mysqld:                                           [  OK  ]
# chkconfig mysqld on

マスター側で、コピー前にロックしていたので、解除します。

mysql> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

マスター側で取得したファイル名とポジションを設定します。

mysql > CHANGE MASTER TO MASTER_HOST='10.67.24.201',MASTER_USER='repl',MASTER_PASSWORD='Passw0rd',
MASTER_LOG_FILE='log-bin.000003',MASTER_LOG_POS=257;

次のコマンドで、レプリカを開始します。

mysql> START SLAVE;

マスターとリードレプリカの連携状態を確認します。 ここで問題が発見された場合、最初から手順を見直します。

mysql> show slave status G

...省略
             Slave_IO_Running: Yes  <-- YESであれば成功
            Slave_SQL_Running: Yes   <-- 同上
...省略
                Last_IO_Errno: 0
                Last_IO_Error:        <-- 上記がNOになる原因のメッセージが表示される
               Last_SQL_Errno: 0
               Last_SQL_Error:        <-- 同上
1 row in set (0.00 sec)

おめでどうございます! これでマスターとレプリケーションの設定が完了です。

動作確認
アプリケーションサーバーからVIPをアクセスして、MySQLのリードレプリカをアクセスして、動作確認を行います。
最初にマスターのMySQLで、テーブルを作ってデータを登録しておきます。 ここで登録したデータがリード・レプリカのMySQLサーバーから読み取ることで、レプリカ設定を確認します。

mysql> use test;
Database changed
mysql> create table person (id int, name varchar(20));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into person (id,name) values (1, 'takara');
Query OK, 1 row affected (0.00 sec)

mysql> insert into person (id,name) values (2, 'suzuki');
Query OK, 1 row affected (0.00 sec)

マスター側とレプリカ側で、それぞれ SELECT を実行して、同じ結果が得られることを確認します。

# mysql
...省略
mysql> select id,name from person;
+------+--------+
| id   | name   |
+------+--------+
|    1 | takara |
|    2 | suzuki |
+------+--------+
2 rows in set (0.00 sec)

次に、アプリケーション・サーバーから、VIPを指定して mysql コマンドを実行して、接続を確認します。 その前に、外部のサーバーからアクセスできるようにするための、設定を行ないます。 次のコマンドは、アプリケーション・サーバーのIPアドレスから、root ユーザーが指定のパスワードで、アクセスを許可するものです。 VIPを介してアクセスするアプリケーション・サーバーについて、アクセスできるように設定しておく必要あります。

mysql> grant all on *.* to 'root'@'10.67.24.194' IDENTIFIED BY 'Passw0rd';

この設定により、アプリケーション・サーバーから mysql コマンドを実行できるようになったので、確認します。

[root@web1 html]#  mysql -u root -h 10.66.136.58  test -p
Enter password:
...省略
mysql> 

LVSのアクティブ側のサーバーにログインして、次のコマンドを実行することで、VIPから転送されている状況を確認することができます。

[root@lvs1 ~]# ipvsadm -Lnc
IPVS connection entries
pro expire state       source             virtual            destination
TCP 00:12  NONE        10.67.24.194:0     10.66.136.58:3306  10.67.24.198:3306
TCP 14:22  ESTABLISHED 10.67.24.194:45782 10.66.136.58:3306  10.67.24.198:3306

それでは、PHPのアプリケーションからの動作確認です。 次のテスト用コードを /var/httpd/html において、ブラウザからアクセスします。

# cat index.php



接続に成功しました。

');

$db_selected = mysql_select_db('test', $link);
if (!$db_selected){
  die('データベース選択失敗です。'.mysql_error());
}

print('

testデータベースを選択しました。
');

mysql_set_charset('utf8');

$result = mysql_query('SELECT id,name FROM person ORDER BY id');
if (!$result) {
  die('クエリーが失敗しました。'.mysql_error());
}

while ($row = mysql_fetch_assoc($result)) {
  print('id='.$row['id']);
  print(',name='.$row['name']);
  print('
');
}

$close_flag = mysql_close($link);

if ($close_flag){
  print('

切断に成功しました。
');
}
?>

次のブラウザ画面のように表示されたら成功です。 マスターMySQLでデータを適当に追加して、レプリカ側へ反映されていることが確認できます。

これで、HA構成の動作確認として、MySQLサーバーのリード・レプリカの一つを停止、また、LVSのプライマリを停止させても、ブラウザからのアクセスが継続できることが確認できます。 いろいろ試してみて構成の理解を深めて頂けると幸いです。

まとめ
本章では、プライベート・ネットワークに負荷分散サーバーとして LVS をHA構成で立ち上げ、ウェブ・アプリケーションサーバーが、VIPを経由して、MySQLのリード・レプリカサーバーへアクセスする方法を見てきました。 この方法は、KVSにも適用でき、たいへん応用価値の高い構成です。 設定の手間はかかりますが、システム内部の連携に関して、最小の仮想サーバーでも構成できるためコストパフォーマンスが良く、高可用性の構成が可能であることを、ご理解頂けたのはないかと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?