Edited at

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

More than 3 years have passed since last update.


やりたいこと



  • 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も使えるようにしてあげたり。


参考