LoginSignup
42

More than 5 years have passed since last update.

NginxでリクエストをLXCコンテナに振り分ける

Last updated at Posted at 2015-04-28

やりたいこと

  • blog.abcang.netabcang.net宛のリクエストをwebコンテナに転送
  • blog.abcang.netabcang.netでそれぞれ別のページが表示される
  • app.abcang.net宛のリクエストをappコンテナに転送
  • 登録されていないサブドメインでのアクセスはabcang.netに転送
  • コンテナを増やすたびに設定ファイルを追加したくない

やったこと

以下のように設定ファイルを編集する。
各コンテナは普段通りの設定をすればいい。

/etc/nginx/conf.d/default.conf
map $http_host $cname {
    hostnames;
    abcang.net          web;
    blog.abcang.net     web;
    app.abcang.net      app;
    default             0;
}

server {
    listen       80 default_server;
    server_name  abcang.net;

    # 登録されていないホストはリダイレクト                            
    if ($cname = 0) {
        rewrite ^ http://abcang.net$request_uri? last;
    }

    # 内部DNSで名前解決して転送                                       
    location / {
        resolver dns.abcang.net valid=3600s;
        proxy_pass http://$cname;
        # 接続元情報を維持                                            
        proxy_set_header Host            $host;
        proxy_set_header X-Real-IP       $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_max_temp_file_size 0;

        # Websocket                                                   
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
    }
}

説明

ドメインからコンテナを指定

map $http_host $cname {
    hostnames;
    abcang.net          web;
    blog.abcang.net     web;
    app.abcang.net      app;
    default             0;
}

左にアクセス元のドメインを、右にコンテナの名前を書いていく。
新しくコンテナを追加した場合はこの部分を増やせば良い。
defaultは一致しなかったものがマッチして、0が設定されるようにしている。

登録されていないホストはリダイレクト

    # 登録されていないホストはリダイレクト                            
    if ($cname = 0) {
        rewrite ^ http://abcang.net$request_uri? last;
    }

先のmapでの設定で、登録されていない場合は$cname0になることがわかる。
それを検知したらrewriteでリダイレクトするようにしている。
lastをつけるとそこで処理を停止してくれるらしい。

各コンテナに転送

    # 内部DNSで名前解決して転送                                       
    location / {
        resolver dns.abcang.net valid=3600s;
        proxy_pass http://$cname;
        # 接続元情報を維持                                            
        proxy_set_header Host            $host;
        proxy_set_header X-Real-IP       $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_max_temp_file_size 0;

        # Websocket                                                   
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
    }

resolverの部分で内部DNS(LXCで使用されているもの)を指定する。
validをつけると再度DNSに問い合わせる時間を指定できるみたい。
proxy_passで転送先を指定しているが、ドメイン部分を変数にしておかないとnginx起動時以降名前解決してくれないらしい。
後は接続元の情報をヘッダに付けてあげたり、WebSocketも使えるようにしてあげたり。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42