@ T0xicCodeの答えは正しいですが、実際に機能するソリューションを実装するのに実際には約20時間かかったので、詳細を拡張しようと思いました。
Nginxを独自のコンテナーで実行し、それをリバースプロキシとして使用して、同じサーバーインスタンスで複数のアプリケーションの負荷を分散する場合、実行する必要のある手順は次のとおりです。
コンテナをリンクする
docker run
コンテナを作成する場合、通常はシェルスクリプトをに入力することで、実行中のUser Data
他のコンテナへのリンクを宣言できます。つまり、コンテナを順番に起動する必要があり、前者のコンテナにリンクできるのは後者のコンテナのみです。そのようです:
#!/bin/bash
sudo docker run -p 3000:3000 --name API mydockerhub/api
sudo docker run -p 3001:3001 --link API:API --name App mydockerhub/app
sudo docker run -p 80:80 -p 443:443 --link API:API --link App:App --name Nginx mydockerhub/nginx
したがって、この例では、API
コンテナは、他のものにリンクされていないが、
App
コンテナはにリンクされているAPI
とNginx
の両方にリンクされているAPI
とApp
。
この結果、およびコンテナ内に存在するenv
変数と/etc/hosts
ファイルが変更されます。結果は次のようになります。
API
App
/ etc / hosts
コンテナcat /etc/hosts
内で実行Nginx
すると、次のようになります。
172.17.0.5 0fd9a40ab5ec
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 App
172.17.0.2 API
ENV変数
コンテナenv
内で実行Nginx
すると、次のようになります。
API_PORT=tcp://172.17.0.2:3000
API_PORT_3000_TCP_PROTO=tcp
API_PORT_3000_TCP_PORT=3000
API_PORT_3000_TCP_ADDR=172.17.0.2
APP_PORT=tcp://172.17.0.3:3001
APP_PORT_3001_TCP_PROTO=tcp
APP_PORT_3001_TCP_PORT=3001
APP_PORT_3001_TCP_ADDR=172.17.0.3
実際の変数の多くを切り捨てましたが、上記はトラフィックをコンテナにプロキシするために必要な重要な値です。
実行中のコンテナー内で上記のコマンドを実行するためのシェルを取得するには、以下を使用します。
sudo docker exec -i -t Nginx bash
リンクされたコンテナのローカルIPアドレスを含む/etc/hosts
ファイルエントリとenv
変数の両方があることがわかります。私の知る限り、リンクオプションが宣言された状態でコンテナを実行すると、これがすべて発生します。ただし、この情報を使用nginx
してNginx
コンテナー内で構成できるようになりました。
Nginxの構成
ここで少し注意が必要ですが、いくつかのオプションがあります。作成した/etc/hosts
ファイルのエントリを指すようにサイトを構成するdocker
か、ENV
varsを利用して、フォルダ内にある可能性のある他のconfファイルで文字列置換(私が使用sed
)を実行してIPを挿入することができます値。nginx.conf
/etc/nginx/sites-enabled
オプションA:ENV変数を使用してNginxを構成する
これは、/etc/hosts
ファイルオプションを機能させることができなかったために
使用したオプションです。私はすぐにオプションBを試し、発見があればこの投稿を更新します。
このオプションと/etc/hosts
ファイルオプションの使用の主な違いはDockerfile
、CMD
引数としてシェルスクリプトを使用するように作成する方法です。これにより、文字列の置換が処理され、IP値がENV
confファイルにコピーされます。
これが私が最終的に得た構成ファイルのセットです:
Dockerfile
FROM ubuntu:14.04
MAINTAINER Your Name <you@myapp.com>
RUN apt-get update && apt-get install -y nano htop git nginx
ADD nginx.conf /etc/nginx/nginx.conf
ADD api.myapp.conf /etc/nginx/sites-enabled/api.myapp.conf
ADD app.myapp.conf /etc/nginx/sites-enabled/app.myapp.conf
ADD Nginx-Startup.sh /etc/nginx/Nginx-Startup.sh
EXPOSE 80 443
CMD ["/bin/bash","/etc/nginx/Nginx-Startup.sh"]
nginx.conf
daemon off;
user www-data;
pid /var/run/nginx.pid;
worker_processes 1;
events {
worker_connections 1024;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 33;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip Settings
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 3;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/xml text/css application/x-javascript application/json;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# Virtual Host Configs
include /etc/nginx/sites-enabled/*;
# Error Page Config
#error_page 403 404 500 502 /srv/Splash;
}
注:起動直後にコンテナが終了しないようdaemon off;
に、nginx.conf
ファイルに含めることが重要です。
api.myapp.conf
upstream api_upstream{
server APP_IP:3000;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.myapp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
Nginx-Startup.sh
#!/bin/bash
sed -i 's/APP_IP/'"$API_PORT_3000_TCP_ADDR"'/g' /etc/nginx/sites-enabled/api.myapp.com
sed -i 's/APP_IP/'"$APP_PORT_3001_TCP_ADDR"'/g' /etc/nginx/sites-enabled/app.myapp.com
service nginx start
私は内容のほとんどについてのあなたの宿題やってあなたにそれを任せるnginx.conf
とをapi.myapp.conf
。
魔法が起こるにNginx-Startup.sh
我々が使用する場所sed
の上に文字列置換を行うためにAPP_IP
、我々はに書いたことをプレースホルダupstream
当社のブロックapi.myapp.conf
およびapp.myapp.conf
ファイル。
このask.ubuntu.comの質問は、それを非常にうまく説明してい
ます。コマンドを使用してファイル内のテキストを検索して置換します。
GOTCHA
OSXではsed
、オプションの処理方法が異なります-i
。具体的にはフラグです。Ubuntuでは、-i
フラグは「インプレース」の置換を処理します。ファイルを開き、テキストを変更してから、同じファイルを「保存」します。OSXでは、-i
フラグには、結果のファイルに付けるファイル拡張子が必要です。拡張子のないファイルで作業している場合は、-i
フラグの値として ''を入力する必要があります。
GOTCHAsed
置換する文字列を見つけるために使用する
正規表現内でENV変数を使用するには、変数を二重引用符で囲む必要があります。したがって、見た目は不安定ですが、正しい構文は上記のとおりです。
そのため、dockerはコンテナーを起動し、Nginx-Startup.sh
スクリプトの実行をトリガーしました。スクリプトは、コマンドで指定した対応する変数にsed
値APP_IP
を変更するために使用ENV
されていましたsed
。これで、コンテナの起動時にdockerが設定/etc/nginx/sites-enabled
したENV
変数のIPアドレスを持つconfファイルがディレクトリ内にあります。api.myapp.conf
ファイル内で、upstream
ブロックが次のように変更されていることがわかります。
upstream api_upstream{
server 172.0.0.2:3000;
}
表示されるIPアドレスは異なる場合がありますが、通常はであることに気付きました172.0.0.x
。
これで、すべてが適切にルーティングされるはずです。
GOTCHA
最初のインスタンス起動を実行すると、コンテナを再起動/再実行することはできません。Dockerは、起動時に各コンテナーに新しいIPを提供し、以前に使用したものを再利用していないようです。したがってapi.myapp.com
、最初は172.0.0.2を取得しますが、次回は172.0.0.4を取得します。ただしNginx
、最初のIPはすでにconfファイルまたはファイルに設定され/etc/hosts
ているため、の新しいIPを判別することはできませんapi.myapp.com
。これに対する解決策は、使用する可能性が高くCoreOS
、そのetcd
サービスは、私の限られた理解ではENV
、同じCoreOS
クラスターに登録されているすべてのマシンで共有されているように機能します。これは私がセットアップで遊ぶつもりの次のおもちゃです。
オプションB:/etc/hosts
ファイルエントリを使用する
これは、これを行うためのより速く、より簡単な方法であるはずですが、私はそれを機能させることができませんでした。表向きはあなただけの入力の値/etc/hosts
あなたへの参入api.myapp.conf
やapp.myapp.conf
ファイルが、私は仕事に、この方法を得ることができませんでした。
更新:このメソッドを機能させる方法
については、@ WesTodの回答を参照してください。
これが私が行った試みですapi.myapp.conf
:
upstream api_upstream{
server API:3000;
}
私の/etc/hosts
ファイルに次のようなエントリがあることを考えると172.0.0.2 API
、値を取得するだけだと思いましたが、そうではないようです。
またElastic Load Balancer
、すべてのAZからの調達に関して、いくつかの付随的な問題があったため、このルートを試したときに問題が発生した可能性があります。代わりに、Linuxで文字列の置換を処理する方法を学ぶ必要があったので、それは楽しかったです。しばらくしてから試してみて、どうなるか見ていきます。