WEBサーバーを冗長化して、NGINXのロードバランサー機能で振り分けます。
こんにちは。
数分でも止まっちゃ困るのよね、ってくらいの WEBサイトを運用する場合は、パブリッククラウドでもオンプレでも WEBサーバーを何台か作って冗長化というのをします。
ここでは NGINXのリバースプロキシ機能とロードバランサー機能の合わせ技で、クライアントからやってくるリクエストを 同じ内容を提供する 2台のWEBサーバーに振り分けます。
環境はこのように。
各サーバーの作成については、以下をご参照下さい。
「Ubuntu Linux Serverをインストール」
「Ubuntu Serverの初期設定」
「NGiNXでリバースプロキシ」
「FreeNASのNFSサーバー機能」
NFSサーバーは何で作っても同じですが、手頃な所に FreeNASがあったのでこれにしているだけです。
こちらでは Ubuntu Serverで NFSサーバーをつくっていますので、これでも良いです。
「Linux同士のファイル共有(NFS)」
では、NGINXが入ってる Ubuntuのサーバーを 3台作ります。
私は VMware Workstation Playerを使っていまして、今回のように似たような仮想OSをいくつも作る時は、既存の仮想OSのフォルダをまんまコピって作っています。
Ubuntu Server 22.04.1の場合は、インストールして初期設定(最新状態へのアップデートと日本環境への設定変更)した直後の状態をオリジナルとして保存してあって、それをコピっています。
コピーで作られた仮想OSはオリジナルと同じ IPとマシン名を持ってますので、それだけ変更してから最新状態へのアップデートを行い、以降の検証に使っています。
これだけで検証の時の面倒臭さが減りますね。
仮想環境ってのは良いものです。
そんなこんなで、まず WEBサーバーの nginx-web1 と nginx-web2 を作りました。
それから NFSサーバーの FreeNASも立ち上げました。
ネットワークは同じセグメントに属していて、IPアドレスはこうなっています。
nginx-web1 | 192.168.1.127 |
nginx-web2 | 192.168.1.128 |
FreeNAS | 192.168.1.109 |
nginx-web1 と nginx-web2 の /etc/hosts には関係するマシンのIPを記載して、マシン名解決できるようにしてあります。
以下 nginx-web1 と nginx-web2 で全く同じ事をしますが、例として nginx-web1 での作業を書きます。
NGINXと NFSClientをインストールします。
subro@nginx-web1:~$ sudo apt install -y nginx nfs-common
〜〜〜応用編なので途中経過は省略〜〜〜
FreeNASの NFSディスクをマウントします。
FreeNAS(マシン名も同じ)では、/mnt/NFStest/NFStestDataset で 10GBのディスクが共有されています。
マウントポイント(/data)を作っておきます。
subro@nginx-web1:~$ sudo mkdir /data
恒久的に NFSマウントするため、/etc/fstab に1行追加します。
subro@nginx-web1:~$ cat /etc/fstab # /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # ## / was on /dev/ubuntu-vg/ubuntu-lv during curtin installation /dev/disk/by-id/dm-uuid-LVM-dFP5vmw3Vnx7ikD7xru9uzz3LTTelW56DvanbW7sLxeumRQiDUiBBABOfNuV8OYF / ext4 defaults 0 1 # /boot was on /dev/sda2 during curtin installation /dev/disk/by-uuid/4c8ca588-f2f4-4ab6-aa28-4565acb6fff1 /boot ext4 defaults 0 1 /swap.img none swap sw 0 0 FreeNAS:/mnt/NFStest/NFStestDataset /data nfs defaults 0 0
/etc/fstab に書いた内容でマウントします。
subro@nginx-web1:~$ sudo mount -a subro@nginx-web1:/$ df Filesystem 1K-blocks Used Available Use% Mounted on tmpfs 810580 1512 809068 1% /run /dev/mapper/ubuntu--vg-ubuntu--lv 28719140 7877540 19357416 29% / tmpfs 4052896 0 4052896 0% /dev/shm tmpfs 5120 0 5120 0% /run/lock /dev/sda2 1992552 251952 1619360 14% /boot tmpfs 810576 4 810572 1% /run/user/1000 FreeNAS:/mnt/NFStest/NFStestDataset 7610880 128 7610752 1% /data
マウントできました。
ドキュメントルートになるディレクトリを /data の下に作っておきます。
(これは nginx-web1 だけでやります)
subro@nginx-web1:~$ sudo mkdir /data/www
そんでもってテスト用の HTMLをこのように用意しました。
(これも nginx-web1 だけでやります)
subro@nginx-web1:~$ cat /data/www/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>NGINXでロードバランスするテストっすわ</title>
</head>
<body>
<span style="font-size: 200%; color: red;">NGINXでロードバランスするテストっすわ!!</span>
</body>
</html>
NGINXの設定変更をして、ドキュメントルートを /data/www にします。
設定ファイルは /etc/nginx/sites-available/default です。
root /var/www/html; ↓ #root /var/www/html; root /data/www;
変更を反映するため、NGINXに設定ファイルを再読込みさせます。
subro@nginx-web1:~$ sudo systemctl reload nginx
セッティングはこれで完了です。
これで、nginx-web1 も nginx-web2 も NFSサーバーからマウントしている共通のディスク領域 /data/www を見ているはずです。
WEBブラウザでそれぞれのマシンにアクセスしてみます。
nginx-web1 のほう
nginx-web2 のほう
うん、同じ index.html を読んでいるっぽいですね。
(こんなアホなページをNGINXのデフォで提供するはずもなく…)
ちょっと長くなりますので、ロードバランスについては後編にて。
なお、上の構成図では、今回作ったのはこの範囲です。
とりあえず、これだけのことでも、例えば1台のサーバーが故障してしまっても、もう一台のサーバーでサービス提供ができるのですね。
サーバー環境を作る際には、このように冗長化ということを行って、1つの故障でサービスの停止を招いてしまわないように環境設計を行います。
ただ「冗長化と費用は比例する」または「冗長化をするとコストは上がる」という関係になっています。
ですので、システム構築プロジェクトの要件定義の際に
- どこまでの故障を想定するか
- どれくらいの期間のサービス停止を許容できるか
といったポイントを顧客と詰めて、冗長化の設計を行います。
さて「ここで作られた環境で冗長化できているんだからそれで良いじゃない?」と思う人がいるかも知れません。
そういう時には、実際に障害が起きた時の対応はどうなるか?を考えてみて下さい。
この環境で、仮に nginx-web1 サーバーがブッ壊れたとしましょう。
お客サンからはホームページが見えなくなってしまいました。
ここで「『nginx-web2 にアクセスして下さい!』って言うのか?」ですね。
社内システムならまだしも、インターネットに提供されている不特定多数にどうやって伝える?と考えると「それではちょっと…」ですよね。
「nginx-web2 を nginx-web1 に仕立てて、立ち上げ直す!」のも悪くないんですが、ちょっと時間がかかりそうです。
「WEBサーバー冗長化(後編)」では、この辺の問題をクリアするために、ロードバランサ/リバースプロキシ を導入しようと思います。