154
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

複数のWebサーバーを1つのドメインでアクセスさせたい場合 (Nginx でリバースプロキシ)

はじめに

アクセスするURLに応じて接続先のWebサーバを切り替えたい場合、
つまり http://hoge.com/XXXX/ というURLに対して
「XXXX」の値毎にアクセスするサーバを変更したい場合、
リバースプロキシを使うことで解決できる。

図にするとこのような感じ。各 Web app は全て別のサーバー上に存在する。
proxy.jpg

今回は Nginx を用いてリバースプロキシを構築する。

Nginx とは

Nginx 公式

・基本的な HTTP 機能(静的なWebサーバ)
・Webアプリケーションと連携することで動的なページもOK
・C10K問題への対応(Apacheで問題になった)
・ロードバランシングができる。
・リバースプロキシになる。

仮想環境の準備

作るもの

以下の合計3台の仮想環境を用意する。
Proxy サーバー (proxy_server): 1台
Web サーバー (web_server1, web_server2): 2台

VirtualBox + Vagrant を利用する。
OS は CentOS 6.5 を選択。

作成手順

VirtualBox と Vagrant をそれぞれインストールした後、
作業用ディレクトと Vagrantfile を作成する。

$ mkdir ~/vagrant/nginx_proxy_test
$ cd ~/vagrant/nginx_proxy_test
$ vagrant init

作成された Vagrantfile を下記のように編集。
3台分のサーバーをまとめて1つのファイルで管理する。
マシン名は proxy_server、web_server1、web_server2 とした。

Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # 全マシンで共通の設定
  config.vm.box = "centos6.5"
  config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box"
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end

  # Proxy サーバー用の設定
  config.vm.define :proxy_server do |proxy_server|
    proxy_server.vm.network "private_network", ip: "192.168.33.100"
  end

  # Web サーバー1の設定
  config.vm.define :web_server1 do |web_server1|
    web_server1.vm.network "private_network", ip: "192.168.33.101"
  end

  # Web サーバー2の設定
  config.vm.define :web_server2 do |web_server2|
    web_server2.vm.network "private_network", ip: "192.168.33.102"
  end
end

下記コマンドで全マシンをまとめて初期設定 & 起動できる。

$ vagrant up

各マシンにログインする際は下記のように指定する。

$ vagrant ssh proxy_server

シャットダウンする際は下記のようにすれば全マシンがまとめて終了する。

$ vagrant halt

Web sever の構築

作るもの

192.168.33.101 にアクセスした際、
下記の出力が以下のURLで見えるように設定する。

192.168.33.101/     ->  "Sample web app root 1"
192.168.33.101/app  ->  "Sample web app /app 1"

下記コマンドで web_server1 にログインして作業を行う。

$ vagrant ssh web_server1

Nginx のインストール

下記コマンドでインストール。

$ sudo yum install -y nginx
$ sudo service nginx start

サンプルコンテンツ作成とログ出力先の作成

Webコンテンツを置くドキュメントルートは、/var/www/ 以下とする。
サンプルhtmlは /var/www/sample_web_app 以下に置く。
またログは /var/log/nginx/sample_web_app 以下に出力する。

$ sudo mkdir /var/www
$ sudo mkdir /var/www/sample_web_app
$ sudo mkdir /var/www/sample_web_app/app
$ sudo mkdir /var/log/nginx/sample_web_app
sample_web_app/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
  <head>
    <title>Web server 1</title>
    </head>
  <body>
    <p>Sample web app root 1</p>
    </body>
</html>
sample_web_app/app/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
  <head>
    <title>Web server 1</title>
    </head>
  <body>
    <p>Sample web app /app 1</p>
    </body>
</html>

Nginx の設定

次に、nginxの設定ファイルを編集。
/etc/nginx/nginx.conf を下記のように記述する。

nginx.conf
user              nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

次に /etc/nginx/conf.d/ 以下の default.conf をリネームした後、
*.conf ファイルを作成する。

$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bk 
$ sudo emacs /etc/nginx/conf.d/192.168.33.101.conf
192.168.33.101.conf
server {
    listen 80 default_server;
    server_name 192.168.33.101;

    access_log  /var/log/nginx/sample_web_app/access.log main;
    error_log   /var/log/nginx/sample_web_app/error.log;

    client_max_body_size 10M;

    root    /var/www/sample_web_app;
    index   index.html index.htm;
}

下記コマンドで nginx をリスタート。

$ sudo service nginx restart

アクセスした結果見えるもの

http://192.168.33.101/ にアクセスした際、
Sample web app root 1
http://192.168.33.101/app にアクセスした際、
Sample web app /app 1
がそれぞれ出力されていればOK。

同様の手順で web_server2 も構築する
(hoge 1 -> hoge 2, 192.168.33.101 -> 192.168.33.102 と置き換えて読めばOK)。

最終的に下記のようになるはず。

192.168.33.101/        ->  "Sample web app root 1"
              /app     ->  "Sample web app /app 1"
192.168.33.102/        ->  "Sample web app root 2"
              /app     ->  "Sample web app /app 2"

Proxy sever の構築

作るもの

次は 192.168.33.100 にアクセスした際、
Web server1 or Web server2 に転送し
下記のコンテンツが以下のURLで見えるように設定する。

192.168.33.100/          ->  "Sample proxy root"
192.168.33.100/web1      ->  "Sample web app root 1"
192.168.33.100/web1/app  ->  "Sample web app /app 1"
192.168.33.100/web2      ->  "Sample web app root 2"
192.168.33.100/web2/app  ->  "Sample web app /app 2"

以下の作業は下記コマンドで proxy_server にログインして行う。

$ vagrant ssh proxy_server

Nginx のインストール

下記コマンドでインストール。

$ sudo yum install -y nginx
$ sudo service nginx start

サンプルコンテンツ作成とログ出力先の作成

Webコンテンツを置くドキュメントルートは、/var/www/ 以下とする。
サンプルhtmlは /var/www/sample_proxy 以下に置く。
またログは /var/log/nginx/sample_proxy 以下に出力する。

$ sudo mkdir /var/www
$ sudo mkdir /var/www/sample_proxy
$ sudo mkdir /var/log/nginx/sample_proxy
sample_proxy/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
  <head>
    <title>Proxy server</title>
    </head>
  <body>
    <p>Sample proxy root</p>
    </body>
</html>

Nginx の設定

次に、nginxの設定ファイルを編集。
/etc/nginx/nginx.conf を下記のように記述する。

nginx.conf
user              nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

次に /etc/nginx/conf.d/ 以下の default.conf をリネームした後、
*.conf ファイルを作成する。

$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bk 
$ sudo emacs /etc/nginx/conf.d/192.168.33.101.conf
192.168.33.101.conf
server {
    listen 80 default_server;
    server_name 192.168.33.100;

    access_log  /var/log/nginx/sample_proxy/access.log main;
    error_log   /var/log/nginx/sample_proxy/error.log;

    client_max_body_size 10M;

    root       /var/www/sample_proxy;
    index      index.html index.htm;

    location / {
    }

    location /web1 {
        proxy_pass http://192.168.33.101/
    }

    location /web1/app {
        proxy_pass http://192.168.33.101/app
    }

    location /web2 {
        proxy_pass http://192.168.33.102/
    }

    location /web2/app {
        proxy_pass http://192.168.33.102/app
    }
}

下記コマンドで nginx をリスタート。

$ sudo service nginx restart

http://192.168.33.100/
http://192.168.33.100/web1
http://192.168.33.100/web1/app
http://192.168.33.100/web2
http://192.168.33.100/web2/app

クライアントマシンから上記URLへアクセスした結果が
下記の通りになっているのを確認できればOK。

192.168.33.100/          ->  "Sample proxy root"
192.168.33.100/web1      ->  "Sample web app root 1"
192.168.33.100/web1/app  ->  "Sample web app /app 1"
192.168.33.100/web2      ->  "Sample web app root 2"
192.168.33.100/web2/app  ->  "Sample web app /app 2"

おわりに

無事、アクセスするURLに応じて接続先のWebサーバを切り替えられた。
Nginx のお勉強ちゃんとしたほうが良さそうだったので資料を漁った。
下記の資料がよくまとまっていたので学習が捗った。

・Nginx の紹介
http://www.slideshare.net/ttkzw/nginx-intro

・Nginx 入門
http://www.slideshare.net/ttkzw/nginx-primer

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
154
Help us understand the problem. What are the problem?