keepalived でロードバランサー冗長化を手元で試した記録

  • このエントリーをはてなブックマークに追加

概要

keepalivedでVRRPを使ったロードバランサーの冗長化がいまいちイメージしにくかったので、Vagrantを用いて仮想的にmaster/slave構成のLBサーバを構築して試した記録。

ルーティングテーブルの範囲外のIPアドレスをVIPとして設定していて、うまくいかずに嵌ったという話です。

サーバの準備

master, slave の2台のサーバを立てる

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-6.7"
  config.ssh.forward_agent = true
  
  config.vm.define 'master' do |master|
    master.vm.hostname = 'master.mizukmb.test'
    master.vm.network :private_network, ip: '192.168.33.10'
  end
  config.vm.define 'slave' do |slave|
    slave.vm.hostname = 'slave.mizukmb.test'
    slave.vm.network :private_network, ip: '192.168.33.11'
  end
end

Vagrantfile があるディレクトリ上で以下のコマンドを実行する

$ vagrant up # master, slaveの両方のサーバが立ち上がる
$ vagrant status # サーバが立ち上がったか確認
Current machine states:

master                    running (virtualbox)
slave                     running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

環境構築

master/slave 両方のサーバにkeepalivedをインストールする(下の例はmasterの場合)

$ vagrant ssh master
[vagrant@master ~]$ sudo yum -y install keepalived
$ vagrant ssh slave
[vagrant@slave ~]$ sudo yum -y install keepalived

keepalivedの設定

keepalivedは以下の2つの機能を提供している。

  1. LVS (Linux Virtual Server) 機能を使ったロードバランサー
  2. VRRP (Virtual Router Redundancy Protocol) 機能を使ったサーバのクラスタ化(冗長性の確保)

今回検証したのは2の方。

keepalived.conf

keepalivedの設定は /etc/keepalived/keepalived.conf に書く。

インストール時に適当な設定が書かれているファイルが置いてあるが今回は使用しないので mvrm でどけておく

[vagrant@master ~]$ sudo mv /etc/keepalived/keepalived.conf /tmp
! Configuration File for keepalived

global_defs {
   notification_email {
   }
}

vrrp_instance VI_1 {
  state MASTER
  interface eth1
  garp_master_delay 5
  virtual_router_id 11
  priority 101
  nopreempt
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass himitsu
  }
  virtual_ipaddress {
    192.168.31.10 dev eth1
  }
}
! Configuration File for keepalived

global_defs {
   notification_email {
   }
}

vrrp_instance VI_1 {
  state BACKUP
  interface eth1
  garp_master_delay 5
  virtual_router_id 11
  priority 100
  nopreempt
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass himitsu
  }
  virtual_ipaddress {
    192.168.31.10 dev eth1
  }
}

statepriority 以外は同じ設定。

vrrp_instancevirtual_router_id を合わせているのでクラスタ化はうまくいってるはずです。

keepalivedを起動する

master/slave両方とも起動する。起動したときの理想としては masterがVIP 192.168.31.100 を持ち、slaveは持っていない という状態。

下記コマンドで起動します。master/slave両方で実行してください。

[vagrant@master ~]$ sudo /etc/init.d/keepalived start
keepalived を起動中:                                       [  OK  ]

ちゃんとVIPが振られているか確認するために ip コマンドを用います。 ifconfig コマンドでは確認できないことに注意してください。

[vagrant@master ~]$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:25:ec:7d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe25:ec7d/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:15:21:78 brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1
    inet 192.168.31.10/24 scope global eth1
    inet6 fe80::a00:27ff:fe15:2178/64 scope link
       valid_lft forever preferred_lft forever

うまくいってそう、と思ってslave側も確認したら…

[vagrant@slave ~]$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:25:ec:7d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe25:ec7d/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:3d:8b:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.11/24 brd 192.168.33.255 scope global eth1
    inet 192.168.31.10/24 scope global eth1
    inet6 fe80::a00:27ff:fe3d:8bbe/64 scope link
       valid_lft forever preferred_lft forever

slave側にもVIPが設定されてる…(eth1 の inet 192.168.31.10/24 scope global eth1 という記述がそのIPアドレスを受け付けているという意味です)

masterからslaveにpingが打てているので、同じネットワーク上にはあるんだけどなあ…

ルーティングテーブルにない範囲のIPアドレスをVIPとして指定していたのが原因だった

route コマンドでルーティングテーブルを調べる

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.2.0        *               255.255.255.0   U     0      0        0 eth0
192.168.33.0    *               255.255.255.0   U     0      0        0 eth1
link-local      *               255.255.0.0     U     1002   0        0 eth0
link-local      *               255.255.0.0     U     1003   0        0 eth1
default         10.0.2.2        0.0.0.0         UG    0      0        0 eth0

私がVIPに設定していたアドレスは 192.168.31.10 だけど、192.168.31.xxx/24 はルーティングテーブルには設定されておらず範囲外だった!!

というわけで virtual_ipaddress のVIPを 192.168.33.100 に変更して再起動

  virtual_ipaddress {
-    192.168.31.10 dev eth1
+    192.168.33.100 dev eth1
  }

動かしてみる…

keeplived.png

うまくいった!!

keepalived.gif

slaveからmasterへの昇格も問題なく動いてます!

見えにくいと思いますが、master (画面左) のkeepalivedをstopするとslave (画面右) のeth1に VIP (192.168.33.100) が移っていることに注目してください。 これは、masterのkeepalivedがstopしたことにより、slaveからmasterへと昇格したことを意味しています。その後、masterのkeepalivedを起動することでpriorityの高いサーバにVIPが戻っていくことが確認できるかと思います。

外部からは(画面右下のping)masterからslaveへとVIPが移ったことは関係なくアクセスできています。(ほぼ)ダウンタイムなしでslaveへと切り替わるので安心ですね。

まとめ

keepalivedのVRRP機能を使ったロードバランサー冗長化を手元で試してみました。 virtual_ipaddress に設定するVIPはルーティングテーブルの範囲外のIPアドレスを指定すると嵌るという話でした。

参考サイト

keepalived講習会|feedforceEngineers’blog

DSAS開発者の部屋:こんなに簡単! Linuxでロードバランサ (3)

keepalivedでVIPを設定してVRRPを試してみる - bose999の試験管の中の話