HAProxyをソースからビルドしてporgでパッケージ管理を行う

大栗です。

動的名前解決ができるHAProxyを使いたくなったのですが、Amazon Linux 2017.03でもHAProxyが1.5.2であるためソースからビルドする必要があります。ソースからビルドすると管理が行いにくくなるので、ソースインストールを管理できるporgを使って管理してみます。基本的には標準リポジトリでインストールできるものを使いたいのですがリポジトリのバージョンが上がっていないので仕方がありません。。。

2017年10月5日:手動で作成したファイルの追加方法がわかったので追記しています。

porgとは?

以前はpacoという名前のプロジェクトでしたが、現在はporgとして開発が進められています。 ソースからビルドしたソフトウェアを管理できるツールです。

試してみる

以下の環境で試してみます。

  • OS: Amazon Linux 2017.03
  • インストール対象: HAProxy 1.6.12

インストール対象のHAProxyは1.6系の最新である1.6.12を使用します。HAProxyを普通にビルドする方法はこちらを参照して下さい。

[小ネタ] Amazon Linux に最新バージョンの HAProxy をインストールする

porgのインストール

porgをビルドするためにgccgcc-c++をインストールします。

$ sudo yum install -y gcc gcc-c++

porgをダウンロードして展開します。

$ wget https://downloads.sourceforge.net/project/porg/porg-0.10.tar.gz
$ tar xf porg-0.10.tar.gz
$ cd porg-0.10

progをインストールします。そのままmakeするとGropというGUIツールも入るのですが、不要であるため--disable-gropオプションを付けます。

$ ./configure --disable-grop
$ make
$ sudo make install

porg自身をporgの管理下に置きます。

$ sudo /usr/local/bin/porg -lp porg-0.10 make install

porgがporgに登録されていることを確認します。

$ porg -a
porg-0.10

HAProxyのインストール

HAProxyをダウンロードして展開します。ここでは1.6系の最新である1.6.12を使います。

$ cd ~
$ wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.12.tar.gz
$ tar xf haproxy-1.6.12.tar.gz
$ cd haproxy-1.6.12
$ make TARGET=generic
$ sudo /usr/local/bin/porg -lp haproxy-1.6.12 "make install"

porgの管理下にあることを確認します。

$ porg -a
haproxy-1.6.12
porg-0.10
$ porg -f haproxy-1.6.12
haproxy-1.6.12:
/home/ec2-user/haproxy-1.6.12/.build_opts
/usr/local/doc/haproxy/architecture.txt
/usr/local/doc/haproxy/close-options.txt
/usr/local/doc/haproxy/configuration.txt
/usr/local/doc/haproxy/cookie-options.txt
/usr/local/doc/haproxy/intro.txt
/usr/local/doc/haproxy/linux-syn-cookies.txt
/usr/local/doc/haproxy/lua.txt
/usr/local/doc/haproxy/management.txt
/usr/local/doc/haproxy/network-namespaces.txt
/usr/local/doc/haproxy/proxy-protocol.txt
/usr/local/sbin/haproxy
/usr/local/share/man/man1/haproxy.1

HAProxyを動かす

HAProxyの設定を行います。(追加したファイルをporgの管理下に置くための手順に変更しています。)

$ sudo mkdir /var/lib/haproxy
$ sudo mkdir /usr/share/haproxy
$ sudo /usr/local/bin/porg -+lp haproxy-1.6.12 "install -o root -g root -m 0644 -D examples/option-http_proxy.cfg /etc/haproxy/haproxy.cfg"
$ sudo /usr/local/bin/porg -+lp haproxy-1.6.12 "install -o root -g root -m 0755 /usr/local/sbin/haproxy /usr/sbin/haproxy"
$ sudo /usr/local/bin/porg -+lp haproxy-1.6.12 "install -o root -g root -m 0755 examples/haproxy.init /etc/init.d/haproxy"
$ sudo /usr/local/bin/porg -+lp haproxy-1.6.12 "cp examples/errorfiles/* /usr/share/haproxy/"

以下は旧手順になります。

$ sudo mkdir /var/lib/haproxy
$ sudo mkdir /etc/haproxy
$ sudo mkdir /usr/share/haproxy
$ sudo cp /usr/local/sbin/haproxy /usr/sbin/
$ sudo cp examples/haproxy.init /etc/init.d/haproxy
$ sudo cp examples/errorfiles/* /usr/share/haproxy
$ sudo chmod +x /etc/init.d/haproxy

HAProxyを実行するユーザを作成します。まずはデフォルトの定義を確認します。

$ cat /usr/share/doc/setup-2.8.14/uidgid | grep haproxy
haproxy	188	188	/var/lib/haproxy		/sbin/nologin	haproxy

haproxyユーザを作成します。

$ sudo groupadd -g 188 haproxy
$ sudo useradd -u 188 -g haproxy -d /var/lib/haproxy -s /sbin/nologin haproxy

サービスの登録をします。

$ sudo chkconfig --add haproxy
$ sudo chkconfig haproxy on

設定ファイルを作成します。サンプルとして5000番ポートをローカルの80番ポートに繋げる設定をしました。

$ sudo vim /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend  main
    bind 127.0.0.1:5000
    default_backend             back

backend back
    balance     roundrobin
    server      static 127.0.0.1:80 check

テスト用にapacheもインストールします。

$ sudo yum install -y httpd

普通にhttpでアクセスすると以下のようになります。

$ curl http://127.0.0.1/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>Test Page for the Apache HTTP Server on Amazon Linux AMI</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<style type="text/css">
・
・
・
略

今度はHAProxyで設定した5000番ポートでアクセスします。先ほどと同じレスポンスが返ってきます。

$ curl http://127.0.0.1:5000/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>Test Page for the Apache HTTP Server on Amazon Linux AMI</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<style type="text/css">
・
・
・
略

HAProxyを削除する

最後にHAProxyを削除します。

まずは、サービスを停止します。

$ sudo service haproxy stop
Shutting down haproxy:                                     [  OK  ]
$ sudo service httpd stop
Stopping httpd:                                            [  OK  ]

-rオプションにパッケージ名を指定して削除します。

$ sudo /usr/local/bin/porg -b -r haproxy-1.6.12
$ porg -a
porg-0.10

HAProxyのファイルが消えています。

$ sudo ls -al /usr/local/doc/haproxy
ls: cannot access /usr/local/doc/haproxy: No such file or directory

ただし手動で作成したファイルはporgの管理外なので別途削除します。手動で作成したファイルも一緒にporgで管理する方法を知っている方がいたら教えてください。。。以下のオプションで追加できるようでした。

$porg -lp+ haproxy-1.6.12 "COMMAND"
$ sudo chkconfig --del haproxy
$ sudo userdel haproxy
$ sudo rm -f /usr/sbin/haproxy   # 新手順では不要です
$ sudo rm -f /etc/init.d/haproxy # 新手順では不要です
$ sudo rm -rf /usr/share/haproxy # 新手順では不要です

さいごに

私は基本的にはディストリビューションのリポジトリにあるパッケージを使用すべきだと考えていますが、バージョンが古いなどといった問題などでパッケージをソースからビルドする必要に迫られる場合があります。しかしインストールしたパッケージに脆弱性が発見されて入れ替えを行う必要が出てくる事があります。パッケージ管理をしていないと入れ替えを行えなくなるため、ソースからビルドする場合は何らかのパッケージ管理ツールを使用しましょう。