HAProxyとKeepalivedを使ってオンプレ環境で冗長構成を実現

検証環境

  • ホストOS: CentOS7.5
  • 仮想環境: Vagrant (VirtualBox)
    • ゲストOS: CentOS7.5
    • haproxy1, haproxy2, app1, app2, postgres
  • HAProxy: 1.5.18
  • Keepalived: v1.3.5
  • PostgreSQL: 9.2.23

要件

第一の要件を可用性、次に運用容易性に設定して、自前のサーバでアプリケーション基盤を実現する方法を考えてみた。

構成イメージ図

前段のロードバランサー(HAProxy)はKeepalivedで冗長化し、LBの可用性を確保。

LBのバックにはアプリケーション本体を2台にデプロイするようにして、片方が落ちてもサービス継続できるようにした。(今時で言うとKubernetesやDocker Swarmなんだけど、運用容易性の観点から単純にアプリのプロセス立ち上げるだけで良いようにした)

その後段にはデータベースを配置。ここの可用性については今回の記事では省略。いつかpgpool的なのを使った場合の記事書きたい。

構成イメージ図

ネットワーク図

構成イメージでは階層構造になっているが、実際には全サーバ同一サブネット(192.168.33.0/24)に繋いで検証した。(すべて同じprivate networkに接続)
性能を求めているわけではないので、今回はこれで手打ち。

ネットワーク図

サーバ設定

データベース(PostgreSQL)

PostgreSQLをインストール

yum -y install postgresql-server
postgresql-setup initdb

/var/lib/pgsql/data/postgresql.confを編集

listen_addresses = '*'
timezone = 'Asia/Tokyo'
log_timezone = 'Asia/Tokyo'

/var/lib/pgsql/data/pg_hba.confを編集

host    all             all             192.168.33.0/24            md5

サービス起動

systemctl start postgresql
systemctl enable postgresql

データベースを作成

# su - postgres
-bash-4.2$ psql -c "CREATE ROLE django WITH LOGIN PASSWORD 'django';"
CREATE ROLE
-bash-4.2$ psql -c "CREATE DATABASE django OWNER django ENCODING 'utf8';"
CREATE DATABASE

アプリケーションサーバ

今回はDjangoで作ったシンプルWebアプリケーションを使う。
まずはDockerとdocker-composeをインストール

yum -y install git docker
systemctl start docker
systemctl enable docker
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

アプリケーション本体をGitHubから持ってきてデプロイ

git clone https://github.com/tetsis/nginx-gunicorn-django-postgres.git
cd nginx-gunicorn-django-postgres/
docker-compose -f docker-compose-without-postgres.yml up -d
docker exec nginx-gunicorn-django-postgres_django_1 ./init.sh

上記の手順をアプリケーションサーバ2台(app1, app2)両方で実施する

ロードバランサー

HAProxyとKeepalivedをインストール
psmiscはプロセスチェックコマンドkillallのために必要

yum -y install haproxy keepalived psmisc

/etc/haproxy/haproxy.cfgを編集

# デフォルトのfrontend句を以下のように変更
frontend  main *:80
    default_backend             app

# デフォルトのbackend句を以下のように変更
backend app
    balance     roundrobin
    server  app1 192.168.33.103:80 check
    server  app2 192.168.33.104:80 check

/etc/keepalived/keepalived.confを以下のように修正

! Configuration File for keepalived

global_defs {
    router_id LVS_DEVEL
}

vrrp_script chk_haproxy {
    script "/usr/bin/killall -0 haproxy" # check the haproxy process
    interval 2 # every 2 seconds
    weight 2 # add 2 points if OK
}

vrrp_instance VI_1 {
    interface eth1 # interface to monitor
    state MASTER # MASTER on haproxy1, BACKUP on haproxy2
    virtual_router_id 51
    priority 101 # 101 on haproxy1, 100 on haproxy2
    virtual_ipaddress {
        192.168.33.100 # virtual ip address
    }
    track_script {
        chk_haproxy
    }
}

サービス起動

systemctl start haproxy
systemctl enable haproxy
systemctl start keepalived
systemctl enable keepalived

上記の手順をロードバランサーサーバ2台(haproxy1, haproxy2)両方で実施する
※ keepalived.confについては、stateとpriorityはhaproxy1とhaproxy2で設定値が異なる