> to English Pages
https://kyowg.blogspot.com/2017/11/load-balancer-with-lvs-keepalived-dsr.html
1. 要約
この記事では、LVS (keepalived + IPVS) & firewalld による DSR 方式ロードバランサーの設計と構築例を投稿します。
2. はじめに
高トラフィックなプロジェクトでは、そのシステムパフォーマンス会議などにおいて、ロードバランサーが議題に上がる事もあると思います。
そして、ソフトウェアロードバランサーのパフォーマンスについて、ネガティブな意見が出る事もあるかもしれません。
そのような場合、BIG-IP のような物理ロードバランサーの名前が上がる事もあるでしょう。
しかし、LVS (keepalivee + IPVS) & firewalld を利用した DSR 方式のソフトウェアロードバランサーが、2 〜 4vCPU、4 〜 16RAM スペックで、日に 100 万アクセスある某プロジェクトにおいて、SLA 100%、負荷率 10% で稼働しているという事実を知ったらいかがでしょうか?
この事実は、この設計技術が、ロードバランサー製品のないホスティングサービスや、オンプレミス、あるいはクラウドにおけるローコスト設計において、有効なロードバランサーソリューションの一つである事を実証してるといってもいいでしょう。
このようなハイパフォーマンスな成果は、特に DSR という通信方式によってもたらされている側面が強いでしょう。
DSR 方式とは、Direct Server Return の略語で、“ノードからクライアントへのレスポンスを、ロードバランサーを経由させずにダイレクト返却にする”という通信方式の事をさし、この仕組みによってロードバランサーの劇的な負荷軽減を実現させています。
また、この方法のメリットは、コスト削減や高パフォーマンスだけでなく、ハードウェアロードバランサーにまつわる様々な課題(故障、劣化、サポート契約や体制、機種依存など)の影響を受けないところにもあります。
では、以降で LVS (keepalived + IPVS) & firewalld による DSR 方式ロードバランサーの設計と構築の一例を投稿してみます。
また、この記事では、DSR V.S. Not DSR などのベンチマークテストについては実施しません。
3. DSR 方式ロードバランサー環境
- RHEL 7 系
- Keepalived 1.2.13
- ipvsadm 1.27
- firewalld 0.3.9
4. DSR 方式ロードバランサー設計
5. Web サーバー側 DSR 用設定
5-1. firewalld 設定
@ Web サーバー 1
$ sudo systemctl start firewalld
$ sudo systemctl enable firewalld
$ sudo systemctl status firewalld
$ sudo firewall-cmd --set-default-zone=internal
$ sudo firewall-cmd --add-port=22/tcp --zone=internal
$ sudo firewall-cmd --add-port=22/tcp --zone=internal --permanent
$ sudo firewall-cmd --add-port=80/tcp --zone=internal
$ sudo firewall-cmd --add-port=80/tcp --zone=internal --permanent
物理 IP アドレス用
$ sudo firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.3 -j REDIRECT
$ sudo firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.3 -j REDIRECT
仮想 IP アドレス用
$ sudo firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.5 -j REDIRECT
$ sudo firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.5 -j REDIRECT
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all-zone
$ sudo firewall-cmd --direct --get-rule ipv4 nat PREROUTING
@ Web サーバー 2
$ sudo systemctl start firewalld
$ sudo systemctl enable firewalld
$ sudo systemctl status firewalld
$ sudo firewall-cmd --set-default-zone=internal
$ sudo firewall-cmd --add-port=22/tcp --zone=internal
$ sudo firewall-cmd --add-port=22/tcp --zone=internal --permanent
$ sudo firewall-cmd --add-port=80/tcp --zone=internal
$ sudo firewall-cmd --add-port=80/tcp --zone=internal --permanent
物理 IP アドレス用
$ sudo firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.4 -j REDIRECT
$ sudo firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.4 -j REDIRECT
仮想 IP アドレス用
$ sudo firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.5 -j REDIRECT
$ sudo firewall-cmd --permanent --direct --add-rule ipv4 nat PREROUTING 0 -d 10.0.0.5 -j REDIRECT
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all-zone
$ sudo firewall-cmd --direct --get-rule ipv4 nat PREROUTING
6. LVS (keepalived + IPVS) ロードバランサー構築
6-1. Web サーバー疎通確認
@ ロードバランサー 1, 2
$ sudo telnet 10.0.0.3 80
$ sudo telnet 10.0.0.4 80
6-2. Linux カーネル設定
@ Web サーバー 1, 2
$ sudo vim /etc/sysctl.conf
# Enable Packet Transfer between Interfaces
net.ipv4.ip_forward = 1
# Do not discard packets from networks that do not belong to the interface.
net.ipv4.conf.all.rp_filter = 0
$ sudo sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
6-3. keepalived 設定
@ ロードバランサー 1, 2
$ sudo yum -y install keepalived
$ sudo yum -y install ipvsadm
$ sudo cp -a /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org
@ ロードバランサー 1
$ sudo vim /etc/keepalived/keepalived.conf
; Common Configuration Block
global_defs {
notification_email {
alert@example.com
}
notification_email_from lb1@example.com
smtp_server mail.example.com
smtp_connect_timeout 30
router_id lb1.example.com
}
; Master Configureation Block
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 1
priority 101
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass foo
}
virtual_ipaddress {
10.0.0.5/24 dev eth0
}
}
; Virtual Server Configureation Block
virtusl_server 10.0.0.5 80 {
delay_loop 6
lvs_sched rr
lvs_method DR
persistence_timeout 50
protocol TCP
sorry_server 10.0.0.254 80
real_server 10.0.0.3 80 {
weight 1
inhibit_on_failure
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 10.0.0.4 80 {
weight 1
inhibit_on_failure
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
$ sudo systemctl start keepalived
$ sudo systemctl enable keepalived
$ sudo systemctl status keepalived
VIP を取得していることを確認
$ sudo ip addr
ロードバランサー 2
$ sudo vim /etc/keepalived/keepalived.conf
; Common Configuration Block
global_defs {
notification_email {
admin@example.com
}
notification_email_from lb2@example.com
smtp_server mail.example.com
smtp_connect_timeout 30
router_id lb2.example.com
}
; Backup Configureation Block
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 1
priority 100
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass foo
}
virtual_ipaddress {
10.0.0.5/24 dev eth0
}
}
; Virtual Server Configureation Block
virtusl_server 10.0.0.5 80 {
delay_loop 6
lvs_sched rr
lvs_method DR
persistence_timeout 50
protocol TCP
sorry_server 10.0.0.254 80
real_server 10.0.0.3 80 {
weight 1
inhibit_on_failure
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 10.0.0.4 80 {
weight 1
inhibit_on_failure
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
$ sudo systemctl start keepalived
$ sudo systemctl enable keepalived
$ sudo systemctl status keepalived
VIP を取得してない事を確認
$ sudo ip addr
6-4. IPVS (IP Virtual Server) 設定
@ ロードバランサー 1, 2
$ sudo yum -y install ipvsadm
$ sudo touch /etc/sysconfig/ipvsadm
$ sudo systemctl start ipvsadm
$ sudo systemctl enable ipvsadm
$ sudo systemctl status ipvsadm
$ sudo ipvsadm -Ln
7. テスト
7-1. 疎通テスト
ブラウザまたは、違うホストから VIP 宛てへ http アクセス
7-2. フェイルオーバーテスト
@ ロードバランサー 1
$ systemctl stop keepalived
$ ip addr
$ ipvsadm -Ln
@ ロードバランサー 2
$ ip addr
$ ipvsadm -Ln
7-1 疎通テストと同様
8. まとめ
この記事では、LVS (keepalived + IPVS) & firewalld による DSR 方式ロードバランサーの設計と構築の一例を投稿してみました。
こうすることで、ソフトウェアロードバランサーの弱点である高負荷に対するパフォーマンスの低下を DSR ソリューションによって改善する事ができるようになります。
また、この方法のメリットは、コスト削減や高パフォーマンスだけでなく、ハードウェアロードバランサーにまつわる様々な課題(故障、劣化、サポート契約や体制、機種依存など)の影響を受けないところにもあります。