過去にAWSの環境でELBを使って、後方のPrivateSubnetに配置したEC2(WebServer)へロードバランスする環境を作ってみましたが、比較的クラウドサーバーの場合簡単に作れてしまうため、オンプレの場合どう作っているのかな?というのが気になり、仮想LinuxのUbuntu20.04でNginxを使用してロードバランスする構成を構築してみました。
AWSのELBを使ったロードバランスに関する記事は以下でもポイントについて解説しています。
参考 プライベートサブネットにEC2を配置するとyumが通らない件ITサービス指向エンジニアブログTable of Contents
前提
IPアドレスやホスト名、VirtualBoxのネットワーク設定はすでに出来ている前提でお話します。
Ubuntu20.04構成図
OS | 役割 | メモリ | ネットワーク |
---|---|---|---|
Windows10 Pro | client | 16GB | |
Ubuntu20.04 | LoadBalancer | 1GB | ホストオンリーアダプタ NAT |
Ubuntu20.04 | WebServer01 | 1GB | ホストオンリーアダプタ NAT |
Ubuntu20.04 | WebServer02 | 1GB | ホストオンリーアダプタ NAT |
LB.kyrieee.jpへアクセスすると、ラウンドロビンで後方のweb01.kyrieee.jp, web02.kyrieee.jpにアクセスします。
環境情報
仮想化ソフトウェア |
---|
Virtualbox 6.1.36 |
ホスト名 | ドメイン名 | IPアドレス | ゲートウェイアドレス |
---|---|---|---|
web01 | kyrieee.jp | 192.168.255.4/24 | 192.168.255.1 |
web02 | kyrieee.jp | 192.168.255.5/24 | 192.168.255.1 |
LB | kyrieee.jp | 192.168.255.5/24 | 192.168.255.1 |
Nginxインストール
各Uubntuに対して以下を実施し、nginxをインストールを行います。
sudo apt install -y nginx
インストールを実施後、インストールが問題なくされているか確認の為、バージョン確認し以下のように表示されれば問題なくインストールされています。
nginx -v
nginx version: nginx/1.18.0 (Ubuntu)
Nginx起動
nginxを起動
sudo systemctl start nginx
自動起動設定
sudo systemctl enable nginx
ステータス確認
sudo systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset:>
Active: active (running) since Sat 2022-09-17 16:29:48 JST; 35min ago
Docs: man:nginx(8)
Process: 612 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_proces>
Process: 642 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (co>
Main PID: 647 (nginx)
Tasks: 2 (limit: 1078)
Memory: 2.8M
CGroup: /system.slice/nginx.service
├─647 nginx: master process /usr/sbin/nginx -g daemon on; master_p>
└─651 nginx: worker process
active (running)と表示されていれば、nginxは起動状態になっています。
Nginx設定
clientからリクエストがきたらweb01とweb02へリクエストを振り分けるため、nginxの設定ファイルを作成し、設定ファイルの内容を変更します。
Nginx設定ファイルの作成
viでnginx.confファイルを作成し、内容を記載します。
sudo vi /etc/nginx/conf.d/nginx.conf
upstream backend { #proxy_passに記載されたURIとupstream後に記載された値がマッチ
#特に指定が無い場合はラウンドロビンで以下のホストへトラフィックを分散する
server web01.kyrieee.jp:80; #web01のwebserverへトラフィックを流す
server web02.kyrieee.jp:80; #web02のwebserverへトラフィックを流す
}
server {
listen 80; #listenするポート番号
server_name LB.kyrieee.jp; #ロードバランサーのhost名を指定
location / { #locationディレクティブの書き方には様々あるため別途説明
proxy_pass http://backend; #転送先のURIを指定します。プロトコルスキームとしてhttp/httpsを指定する
proxy_http_version 1.1;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
詳細は設定ファイル内のコメントに記載してみました。
nginx.confファイルを保存後は
sudo nginx -t
で、構文に誤りが無いかを確認します。
sudoを付けなかったりやrootユーザーではないユーザーでnginx -tとだけ叩くと以下のメッセージが表示され、
管理者権限で実行しろ、と怒られます。
nginx: could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2022/09/18 07:03:52 [warn] 13963#13963: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2022/09/18 07:03:52 [emerg] 13963#13963: open() "/run/nginx.pid" failed (13: Permission denied)
nginx: configuration file /etc/nginx/nginx.conf test failed
sudoでコマンドを実行し、構文に誤りが無い場合は以下のように表示されます。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
構文に誤りがある場合は以下のようなメッセージが表示されます。
1行目の”htttp”の記載は許可してないよ、といったメッセージなので、httpディレクティブ自体を削除します。
nginx: [emerg] "http" directive is not allowed here in /etc/nginx/conf.d/nginx.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
構文エラーが出ないことが確認できれば、nginxを再起動します。
sudo systemctl restart nginx
名前解決
WindowsからUbuntuへホスト名アクセスする際に名前解決ができないため、WindowsのhostsファイルにIPアドレスとホスト名を追加します。
以下にあるhostsファイルを管理者権限で編集します。
デフォルトの状態だと、書き込み権限がないため随時書き込み権限を付与して編集してください。
C:\Windows\System32\drivers\etc\hosts
以下の内容を記述して保存します。
これでWindows->Ubuntuへの名前解決ができ、Windowsホストからブラウザでアクセスしたときに名前解決できるかと思います。
# Ubuntu20.04
192.168.255.3 LB.kyrieee.jp
192.168.255.4 web01.kyrieee.jp
192.168.255.5 web02.kyrieee.jp
アクセス確認
ゲストOSでWebブラウザを立ち上げ、ロードバランサーからWebServerへトラフィックが流れることを確認するため、各Ubuntuサーバーでアクセスログをtail -f で確認します。
事前にロードバランサからweb01とweb02へ振り分けられたかを明確にするために、index.htmlを編集します。
cd /var/www/html
sudo vi index.html
web01のindex.htmlは
webserver01
web02のindex.htmlは
webserver02
上記とし、ブラウザにロードバランサへアクセスしたら、上記のどちらかがラウンドロビンで交互に表示されるはずです。
3台のUbuntuを起動した状態です。
左がロードバランサ
右二つ(上下に表示されているターミナル画面)がWebServerでtail -fをしている状態です。
この状態でホストOSからロードバランサのドメインにアクセスしてみます。
まず、ブラウザにアクセスしてみます。
webserver01が表示されました。
画面をリロードすると、webserver02が表示されました。
各サーバーのaccess.logもみてみます。
ロードバランサのアクセスログ
192.168.255.1 - - [19/Sep/2022:08:12:48 +0900] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
web01のアクセスログ
S192.168.255.3 - - [19/Sep/2022:08:12:47 +0900] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
web02のアクセスログ
SS192.168.255.3 - - [19/Sep/2022:08:12:20 +0900] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"
問題なく分散されていることが確認できました。
仮想Ubuntuを構築し、nginxの設定ファイルをいじる際に、サイトで検索していてもなかなかどの情報が正しいのか?の見分けがつかなない、本当にこれで正しいのかな?といった不安もあったため、僕は以下の本を一冊買ってまずは基本の部分を学びました。
nginxの設定ファイルの書き方で困っている人は参考になるかと思いますので、一度ご覧になってみるかと良いかと思います。
nginx実践入門 (WEB+DB PRESS plus)
Amazon.co.jp: nginx実践入門 (WEB+DB PRESS plus) : 久保 達彦, 道井 俊介: 本