@ 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.
그 결과 및 컨테이너 내에있는 envvars 및 /etc/hosts파일 이 변경됩니다 . 결과는 다음과 같습니다.
APIApp
/ 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변수를 활용 하고 IP를 삽입 하기 위해 폴더에 있을 수있는 다른 conf 파일 에서 문자열 대체 (I used sed)를 실행할 nginx.conf수 있습니다. /etc/nginx/sites-enabled가치.
옵션 A : ENV 변수를 사용하여 Nginx 구성
이것은 /etc/hosts파일 옵션을 작동 시킬 수 없기 때문에 내가 사용했던
옵션입니다. 곧 옵션 B를 시도하고이 게시물을 발견 한 내용으로 업데이트 할 것입니다.
이 옵션과 /etc/hosts파일 옵션 사용의 주요 차이점은 Dockerfile쉘 스크립트를 CMD인수 로 사용하도록 작성하는 방법 이며, 차례로 문자열 대체를 처리 ENV하여 conf 파일로 IP 값을 복사합니다 .
내가 만든 구성 파일 세트는 다음과 같습니다.
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_IPupstreamapi.myapp.confapp.myapp.conf
이 ask.ubuntu.com 질문은 매우 잘 설명합니다.
명령을 사용하여 파일 내에서 텍스트 찾기 및 바꾸기
GOTCHA
OSX에서 sed옵션, 특히 -i플래그를 다르게 처리합니다 . 우분투에서는 -i플래그가 'in place'교체를 처리합니다. 파일을 열고 텍스트를 변경 한 다음 동일한 파일을 '저장'합니다. OSX에서 -i플래그 에는 결과 파일에 적용 할 파일 확장자 가 필요 합니다. 확장자가없는 파일로 작업하는 경우 -i플래그 값으로 ''를 입력해야합니다 .
GOTCHAsed 교체하려는 문자열을 찾는 데 사용
하는 정규식 내에서 ENV 변수를 사용하려면 var를 큰 따옴표로 묶어야합니다. 따라서 엉뚱 해 보이지만 올바른 구문은 위와 같습니다.
따라서 docker는 컨테이너를 시작하고 Nginx-Startup.sh스크립트를 실행 하여 명령 에서 제공 한 해당 변수로 sed값 APP_IP을 변경하는 데 사용 되었습니다 . 이제 컨테이너를 시작할 때 docker가 설정 한 변수 의 IP 주소가 있는 conf 파일이 디렉터리 내에 있습니다. 파일 내 에서 블록이 다음과 같이 변경된 것을 볼 수 있습니다 .ENVsed/etc/nginx/sites-enabledENVapi.myapp.confupstream
upstream api_upstream{
server 172.0.0.2:3000;
}
표시되는 IP 주소는 다를 수 있지만 일반적으로 172.0.0.x.
이제 모든 것이 적절하게 라우팅되어야합니다.
GOTCHA
초기 인스턴스 시작을 실행 한 후에는 컨테이너를 다시 시작 / 다시 실행할 수 없습니다. Docker는 시작시 각 컨테이너에 새 IP를 제공하며 이전에 사용 된 IP를 재사용하지 않는 것 같습니다. 따라서 api.myapp.com처음에는 172.0.0.2를 얻고 다음에는 172.0.0.4를 얻습니다. 그러나 Nginx이미 첫 번째 IP를 conf 파일이나 해당 /etc/hosts파일에 설정 했으므로 .NET의 새 IP를 확인할 수 없습니다 api.myapp.com. 이에 대한 해결책 은 내 제한된 이해 로 동일한 클러스터에 등록 된 모든 시스템에 대해 공유 된 것처럼 작동 CoreOS하는 etcd서비스 와 사용 가능성이 높습니다 . 이것은 제가 설정과 함께 놀게 될 다음 장난감입니다.ENVCoreOS
옵션 B : /etc/hosts파일 항목 사용
이 작업을 수행하는 더 빠르고 쉬운 방법 이어야 하지만 작동하지 못했습니다. 표면적으로는 /etc/hosts항목 의 값을 api.myapp.conf및 app.myapp.conf파일에 입력했지만이 방법을 사용할 수 없습니다.
업데이트 : 이 방법을 작동시키는 방법에 대한 지침
은 @Wes Tod의 답변 을 참조하십시오 .
내가 시도한 것은 다음과 같습니다 api.myapp.conf.
upstream api_upstream{
server API:3000;
}
내 /etc/hosts파일에 다음과 같은 항목이 있다는 것을 고려할 때 : 172.0.0.2 API값을 끌어 올 것이라고 생각했지만 그렇지 않은 것 같습니다.
또한 Elastic Load Balancer모든 AZ에서 소싱 하는 데 몇 가지 보조 문제가 있었기 때문에이 경로를 시도 할 때 문제가되었을 수 있습니다. 대신 Linux에서 문자열 교체를 처리하는 방법을 배워야했기 때문에 재미있었습니다. 잠시 후에 시도해보고 어떻게 진행되는지 볼 것입니다.