CentOS Stream 9でのNginxリバースプロキシ:ロードバランシングからSSL Let’s Encryptまで

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

マイクロサービスシステムが「肥大化」し始めたら

CentOS 7からCentOS Stream 9へのインフラ移行中、OSのインストール自体は難しくないものの、トラフィック管理こそが難題であると痛感しました。Node.js、Python、Goなどの多数のサービスを3000、8000、5000といった個別のポートで稼働させている場合、クライアントに直接ポートを公開するのはセキュリティ上、重大なミスです。

そこで、Nginxが信頼できるゲートキーパーとして機能します。実稼働環境で1分間に約50,000リクエストを処理するシステムを6ヶ月運用した経験から、CentOS Stream 9上のNginxは非常に安定していると言えます。バックエンドを隠蔽するだけでなく、負荷分散(ロードバランシング)や暗号化(SSL)を担うことで、後方のサーバーがビジネスロジックの処理に専念できるようになります。

なぜApacheではなくNginxを選ぶのか?

馴染みのあるApacheを好む方も多いでしょう。しかし、極めて低いメモリ消費量で数千の同時接続(コンカレンシー)を処理することを優先するなら、やはりNginxが「王者」です。CentOS Stream 9において、Nginxはdnfやsystemdと非常にスムーズに連携します。特にSELinuxとの組み合わせは、プロダクション環境において極めて強固なセキュリティレイヤーを形成します。

動作図はシンプルです:ユーザー → インターネット → Nginx (Port 80/443) → バックエンドサービス. Nginxが中央に立ち、全データフローの調整役を務めます。

ステップ1:インストールと環境準備

まず、セキュリティライブラリを最新の状態に保つためにシステムを更新します。

sudo dnf update -y
sudo dnf install nginx -y

システム起動時にNginxが自動開始されるように設定します:

sudo systemctl enable --now nginx
sudo systemctl status nginx

ファイアウォールを開放するのを忘れないでください。CentOS Stream 9では、これが最も忘れがちなステップであり、サービスが動いていてもウェブサイトにアクセスできない原因になります。

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

ステップ2:実践的なリバースプロキシ設定

元のnginx.confを直接編集するのではなく、/etc/nginx/conf.d/内に個別のファイルを作成するのが私の推奨です。これにより、設定が重なる心配をせずに、数十のドメインを効率的に管理できます。

例えば、ポート3000で動作するNode.jsアプリにトラフィックを誘導する場合、/etc/nginx/conf.d/app.confを作成します:

server {
    listen 80;
    server_name app.itfromzero.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

ヒント: proxy_set_headerの各行は非常に重要です。これらがないと、バックエンドはすべてのリクエストが内部IP(127.0.0.1)から来ていると誤解し、ユーザー識別やレート制限(rate limiting)のロジックに支障をきたします。

ステップ3:大規模システム向けの負荷分散の最適化

ユーザー数が急増すると、単一のバックエンドでは過負荷に陥りやすくなります。ここでupstream技術が真価を発揮します。Nginxは、指定したサーバーリストにリクエストを自動的に分散します。

upstream backend_servers {
    least_conn; # 接続数が最も少ないサーバーを優先
    server 192.168.1.10:3000 weight=3;
    server 192.168.1.11:3000;
    server 192.168.1.12:3000 backup;
}

server {
    listen 80;
    server_name app.itfromzero.com;

    location / {
        proxy_pass http://backend_servers;
    }
}

実際には、デフォルトのラウンドロビンよりもleast_connを優先しています。リクエストごとに処理の重さが異なる場合、よりインテリジェントに処理してくれるからです。また、weightパラメータを使うことで、CPUやRAMのスペックが高いサーバーの能力を最大限に引き出すことができます。

ステップ4:30秒で完了するSSL Let’s Encryptの導入

今やHTTPSなしでのウェブサイト運用はほぼ不可能です。NginxにSSL復号化(SSLターミネーション)を担当させることで、バックエンドはデータ暗号化の負担から解放され、CPUリソースを20〜30%節約できます。

Certbotを使用するのが、証明書発行を自動化する最短の方法です:

sudo dnf install epel-release -y
sudo dnf install certbot python3-certbot-nginx -y
sudo certbot --nginx -d app.itfromzero.com

CertbotはNginxの設定を自動的に修正し、自動更新メカニズムをセットアップします。証明書の有効期限をもう気にする必要はありません。

SELinuxによる「502 Bad Gateway」エラーの解決

これはCentOS初心者が最もイライラする部分です。Nginxの設定が正しく、ファイアウォールが開いており、バックエンドも動いているのに、502エラーが発生します。Nginxのログには「Permission denied」と出力されているはずです。

主な原因はSELinuxです。デフォルトでは、Nginxが外部ネットワークに接続することをブロックしています。これを根本的に解決するには、以下のコマンドを実行します:

sudo setsebool -P httpd_can_network_connect 1

Flag -Pは、サーバー再起動後もこの設定を維持するためのものです。システムの重要な防御層を弱めてしまうため、決してSELinuxを無効化(setenforce 0)しないでください。

結論

upstreamの活用とSELinuxの扱いさえマスターすれば、CentOS Stream 9上のNginxは非常に強力な武器になります。プロキシ層を切り離すことで、インフラはより柔軟になります。アプリケーションのコードを書き換えることなく、古いサーバーのメンテナンスや新しいバックエンドの追加が容易になります。最後に一点:設定ミスによるシステム停止を防ぐため、再起動前には必ずnginx -tを実行しましょう。

Share: