2025-01-05 16:30:01
L7ロードバランサーにお近づきになるために docker コンテナで HAProxy を体験してみる
コンテナの構成
以下のコンテナ構成でホストPCからリクエストを行って体験します。
- HAProxy コンテナ1台
- Apache httpd コンテナ2台
- コンテナ名は httpd-1, httpd-2 です
- php-fpm コンテナ2台
- コンテナ名は phpfpm-1, phpfpm-2 です
設定ファイルは割愛しますが、httpd-1コンテナは phpfpm-1コンテナにリクエストを転送し、httpd-2コンテナは phpfpm-2コンテナにリクエストを転送します。
図解するよ以下のようになります。
HAProxy を動かすための Dockerfile を用意
パッケージインストールするところから始めたいのでここからスタートします。
FROM ubuntu:22.04
ENV TZ Asia/Tokyo
RUN apt update -y && apt upgrade -y
RUN apt install less -y
RUN apt install unzip -y
RUN apt install vim -y
RUN apt install inetutils-ping -y
RUN apt install -y language-pack-ja-base language-pack-ja locales
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
compose.yaml はこんな感じです
services:
ha_proxy:
build:
context: ./docker
dockerfile: ./dev-Dockerfile-HAProxy
ports:
- "80:80"
httpd-1:
container_name: httpd-1
build:
context: ./docker
dockerfile: ./dev-Dockerfile-httpd
depends_on:
- phpfpm-1
environment:
PHP_FPM_CONTAINER: "phpfpm-1"
httpd-2:
container_name: httpd-2
build:
context: ./docker
dockerfile: ./dev-Dockerfile-httpd
depends_on:
- phpfpm-2
environment:
PHP_FPM_CONTAINER: "phpfpm-2"
phpfpm-1:
container_name: phpfpm-1
build:
context: ./docker
dockerfile: ./dev-Dockerfile-phpfpm
phpfpm-2:
container_name: phpfpm-2
build:
context: ./docker
dockerfile: ./dev-Dockerfile-phpfpm
HAProxy コンテナに haproxy をインストールしました
HAProxy のバージョンは 2.4.24 でした。
root@952d31c187d4:/# which haproxy
/usr/sbin/haproxy
root@952d31c187d4:/# /usr/sbin/haproxy -h
HAProxy version 2.4.24-0ubuntu0.22.04.1 2023/10/31 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
HAProxy の設定
httpd-1, httpd-2 は Apache httpd が稼働するコンテナ2台のそれぞれのコンテナ名です。 Dockerではコンテナ名で相互に接続できるので名前で指定しています。
振り分けアルゴリズムはラウンドロビンにしました。後述しますが、リクエストごとに振り分け先を変更したかったのですが、そういう動作にはなりませんでした。
~^^^^ 上には初期設定がありますが省略 ^^^^~
frontend myfrontend
bind 0.0.0.0:80
default_backend myservers
backend myservers
balance roundrobin
server server1 httpd-1:80
server server2 httpd-2:80
ホストPCからリクエストしてみる
HAProxy コンテナは80番ポートでリクエストを受け付けています。また、Apache httpd コンテナは2台とも ServerName に www.nao000.internal
を設定しています。
ホストPCから http://www.nao000.internal/
という URL でアクセスできるようになります。
また、HAProxy コンテナによる振り分けが出来ているか判別できるように、画面には php-fpm コンテナ2台それぞれのホスト名を出力しています。
振り分けアルゴリズムをラウンドロビンにしてリクエストごとに php-fpm コンテナ2台に交互にアクセスする動作を確認したかったのですが、実際にはなりませんでした。
以下はブラウザからアクセスしたときの様子の gif です。F5で更新しています。
リクエストごとにコンテナが切り替わる動作にはなりませんでしたが、時々変わっているのが確認できました。
追記▶▶▶▶▶▶▶▶▶▶▶▶
2025-01-05 23:38
時々しか振り分け先サーバーが変わらないのは、リクエストヘッダーの Connection: KeepAlive が関係してそうです。
curl で試すと毎回変わっていました。
◀◀◀◀◀◀◀◀◀◀◀◀◀◀
追記▶▶▶▶▶▶▶▶▶▶▶▶
2025-01-06 21:50
curl で Connection: keep-alive をつけても毎回変わりました。謎です。
curl -H 'Connection: keep-alive' http://www.nao000.internal
実は HAProxy からのレスポンスはキャッシュされていて、同じTCPコネクションならキャッシュを返しているとかですかね。
curl の場合ってTCPコネクションを毎回破棄しているのですかね。
◀◀◀◀◀◀◀◀◀◀◀◀◀◀
なお、以下の index.php がレスポンスされています。
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
</head>
<body>
<p>hello from</p>
<p style="font-size: 24px;"><?php echo htmlspecialchars(gethostname()); ?></p>
</body>
</html>
おわり
ロードバランサーがより身近に感じれるようになりました。
今回は振り分け先サーバーの負荷状況は見ていませんが多分出来ますよね。それを行うには振り分け先サーバーにもエージェント的なツールをインストールする必要があるかなと思います。