お金をかけずにサーバーの勉強をしよう

WEBサーバー冗長化(前編)

2022年11月26日

メニューへ戻る

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-web1192.168.1.127
nginx-web2192.168.1.128
FreeNAS192.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-web1へのアクセス結果

nginx-web2 のほう
nginx-web2へのアクセス結果

うん、同じ index.html を読んでいるっぽいですね。
(こんなアホなページをNGINXのデフォで提供するはずもなく…)


ちょっと長くなりますので、ロードバランスについては後編にて。

なお、上の構成図では、今回作ったのはこの範囲です。
今回作った範囲の図

とりあえず、これだけのことでも、例えば1台のサーバーが故障してしまっても、もう一台のサーバーでサービス提供ができるのですね。

サーバー環境を作る際には、このように冗長化ということを行って、1つの故障でサービスの停止を招いてしまわないように環境設計を行います。

ただ「冗長化と費用は比例する」または「冗長化をするとコストは上がる」という関係になっています。

ですので、システム構築プロジェクトの要件定義の際に

といったポイントを顧客と詰めて、冗長化の設計を行います。


さて「ここで作られた環境で冗長化できているんだからそれで良いじゃない?」と思う人がいるかも知れません。

そういう時には、実際に障害が起きた時の対応はどうなるか?を考えてみて下さい。

この環境で、仮に nginx-web1 サーバーがブッ壊れたとしましょう。
お客サンからはホームページが見えなくなってしまいました。

ここで「『nginx-web2 にアクセスして下さい!』って言うのか?」ですね。

社内システムならまだしも、インターネットに提供されている不特定多数にどうやって伝える?と考えると「それではちょっと…」ですよね。

「nginx-web2 を nginx-web1 に仕立てて、立ち上げ直す!」のも悪くないんですが、ちょっと時間がかかりそうです。

WEBサーバー冗長化(後編)」では、この辺の問題をクリアするために、ロードバランサ/リバースプロキシ を導入しようと思います。