UbuntuでProxyサーバロードバランス(1)

PROXYサーバをLinuxのLVS(ipvsadm)を使って冗長構成にする事を考えました。
LVSは既に使っている(RedHat Enterprise LinuxでWebサーバロードバランス)のですが、ここではWebサーバのバランシングではなく、Proxyサーバのバランシングを行います。
また、前回の検証時はRedHat Enterprise Linux ES3を使って検証を行っていましたが、今回はUbuntu Server 12.04LTSを使います。ipvsadmがディストリビューションに含まれているため、それにあわせてファイルの配置が変更になります。検証機も実機ではなくESXi上に立てることにします。
今回も目的はProxyサーバの耐障害性の向上で、負荷分散を目的とはしていませんが、構築の順序としては負荷分散機能(ipvsadm)→耐障害機能(keepalived)となります。


LB.jpg

※Proxyサーバの仮想IPアドレスは192.168.100.10にする

論理的にはロードバランサーがクライアントからの要求をすべて受けて、2台のProxyサーバに振り分ける構成になるため、図のようにロードバランサーの配下にProxyサーバ2台がぶら下がる構成になります。
物理的には同一セグメントでフラットに接続されている構成になります。
ロードバランサーの構成をNATにしてしまうと、ProxyサーバのアクセスログにクライアントのIPアドレスではなく、ロードバランサーのIPアドレスが記録されてしまう弊害がおきるため、構成はDSRにします。この構成の大きなメリットが2つあり、1つ目がソースIPアドレス(クライアントのIPアドレス)がそのままサーバに伝わることと、戻りパケットの処理にロードバランサーが介在しないことで、ロードバランサー自身の負荷が少なくなる事です。 デメリットはリアルサーバ側に若干細工が必要になることですが、今回はPROXYサーバも自前のため、デメリットになりません。

Proxyサーバの待ち受けポートは8080を使用しています。


ロードバランサーの設定(ipvsadm)

ipvsadmパッケージのインストール
$ sudo apt-get install ipvsadm

仮想アドレスを設定
$ sudo ifconfig eth0:1 192.168.100.10

IPフォワードを有効に設定
$ sudo sysctl -w net.ipv4.ip_forward=1

カーネルにip_vsモジュールが読み込まれていることを確認(念のため)
$ sudo sudo modprobe -l ip_vs* kernel/net/netfilter/ipvs/ip_vs.ko kernel/net/netfilter/ipvs/ip_vs_rr.ko kernel/net/netfilter/ipvs/ip_vs_wrr.ko kernel/net/netfilter/ipvs/ip_vs_lc.ko kernel/net/netfilter/ipvs/ip_vs_wlc.ko kernel/net/netfilter/ipvs/ip_vs_lblc.ko kernel/net/netfilter/ipvs/ip_vs_lblcr.ko kernel/net/netfilter/ipvs/ip_vs_dh.ko kernel/net/netfilter/ipvs/ip_vs_sh.ko kernel/net/netfilter/ipvs/ip_vs_sed.ko kernel/net/netfilter/ipvs/ip_vs_nq.ko kernel/net/netfilter/ipvs/ip_vs_ftp.ko kernel/net/netfilter/ipvs/ip_vs_pe_sip.ko

IPVSADMのテーブルを空にする
$ sudo ipvsadm -C

IPVSADMに仮想IPアドレスを登録
※ロードバランス方式を最小コネクション数(lc)に設定しています。端末固定(Persistent)は不要なので行っていません。
$ sudo ipvsadm -A -t 192.168.100.10:8080 -s lc

IPVSADMに実サーバのIPアドレスを登録
※NAT時は-mになるが、DSR時は-gになる。また重み(Weight)は両サーバ共に1(-w 1)に設定している
$ sudo ipvsadm -a -t 192.168.100.10:8080 -r 192.168.100.11 -g -w 1 $ sudo ipvsadm -a -t 192.168.100.10:8080 -r 192.168.100.12 -g -w 1

IPVSADMの設定を確認
$ sudo ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.100.10:8080 lc -> 192.168.100.11:8080 Route 1 0 0 -> 192.168.100.12:8080 Route 1 0 0

仮想インターフェースのIPアドレスを恒久的な設定にする
※ eth0:1の設定を追記する
$ sudo vi /etc/network/interfaces
auto eth0:1
iface eth0:1 inet static
address 192.168.100.10
netmask 255.255.255.0

IPフォワードの設定を恒久的な設定にする
※ 28行目のip_forwardがコメントアウトされているので、行頭の#を削除する
$ sudo vi /etc/sysctl.conf
net.ipv4.ip_forward=1

IPVSADMの設定を保存する
※ /etc/ipvsadm.rulesに保存されます
$ sudo service ipvsadm save

IPVSADMのインストール時に、自動起動に設定されるため、sysv-rc-confでの設定は不要です。



PROXYサーバの設定(2台共)
※PROXYサーバ(Squid)の設定は終わっていることを前提としています。

DSR方式のLB配下になるため、Squidは実IPアドレスへアクセスされる可能性と、仮想IPアドレスへアクセスされる可能性がある事を前提に構成します。(無難に設定するなら、squid.confのhttp_portはポート番号のみ記述し、IPアドレスは記述しない)

ループバックインターフェースの作成
$ sudo ifconfig lo:1 192.168.10.100 netmask 255.255.255.255 broadcast 192.168.10.100

ARP応答の抑止
$ sudo sysctl -w net.ipv4.conf.all.arp_ignore=1 $ sudo sysctl -w net.ipv4.conf.all.arp_announce=2 $ sudo sysctl -w net.ipv4.conf.default.arp_ignore=1 $ sudo sysctl -w net.ipv4.conf.default.arp_announce=2 $ sudo sysctl -w net.ipv4.conf.eth0.arp_ignore=1 $ sudo sysctl -w net.ipv4.conf.eth0.arp_announce=2

ループバックインターフェースの設定を恒久的な設定にする
※ /etc/network/interfacesに追記します
$ sudo vi /etc/network/interfaces auto lo:1 iface lo:1 inet static address 192.168.100.10 netmask 255.255.255.255 network 192.168.100.10 broadcast 192.168.100.10

ARP応答の抑止を恒久的な設定にする
※ /etc/sysctl.d/60-ipv4-config.confを新規に作成して、そこに記述します
$ sudo vi /etc/sysctl.d/60-ipv4-config.conf net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.default.arp_ignore = 1 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2
動作確認
ここまでの設定を行う事で、仮想IPアドレスにアクセスするとロードバランサーが各Proxyサーバに振り分ける動作をします。
ipvsadmの動作状況をロードバランサーのコンソールで確認しながら仮想IPアドレスにアクセスしてみます。

$ watch -n1 sudo ipvsadm -Ln
Every 1.0s: sudo ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.100.10:8080 lc
-> 192.168.100.11:8080 Route 1 0 0
-> 192.168.100.12:8080 Route 1 0 0
アクセスしながら、ActiveConnの数値が上がることと、各Proxyに負荷が分散されている様子を確認します。