LoginSignup
5
2

More than 5 years have passed since last update.

LVS & firewalld による DSR 方式ロードバランサー

Last updated at Posted at 2018-12-04

> 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 方式ロードバランサー設計

dsr.png

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

/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

/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

/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 ソリューションによって改善する事ができるようになります。
また、この方法のメリットは、コスト削減や高パフォーマンスだけでなく、ハードウェアロードバランサーにまつわる様々な課題(故障、劣化、サポート契約や体制、機種依存など)の影響を受けないところにもあります。

5
2
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
5
2