Docker 네트워킹-nginx : [emerg] 호스트를 업스트림에서 찾을 수 없음
최근에 링크를 사용하여 대체하기 위해 Docker 1.9 및 Docker-Compose 1.5의 네트워킹 기능으로 마이그레이션하기 시작했습니다.
지금까지 링크로 nginx가 docker-compose를 통해 한 그룹의 다른 서버에있는 내 php5-fpm fastcgi 서버에 연결하는 데 문제가 없었습니다. 새로 docker-compose --x-networking up
php-fpm을 실행 하면 mongo 및 nginx 컨테이너가 부팅되지만 nginx는 즉시 종료됩니다.[emerg] 1#1: host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16
그러나 php와 mongo 컨테이너가 실행되는 동안 (nginx 종료) docker-compose 명령을 다시 실행하면 nginx가 시작되고 그때부터 제대로 작동합니다.
이것은 내 docker-compose.yml
파일입니다.
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
이것은 내 default.conf
nginx입니다.
server {
listen 80;
root /var/www/test;
error_log /dev/stdout debug;
access_log /dev/stdout;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
# Referencing the php service host (Docker)
fastcgi_pass waapi_php_1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# We must reference the document_root of the external server ourselves here.
fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
nginx가 단일 docker-compose 호출로만 작동하도록하려면 어떻게해야합니까?
dependent_on 기능 (아래에서 설명)이 도입 될 때까지 "volumes_from"을 해결 방법으로 사용할 수 있습니다. 다음과 같이 docker-compose 파일을 변경하기 만하면됩니다.
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
volumes_from:
- php
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
위의 접근 방식에서 한 가지 큰주의 사항은 PHP 볼륨이 nginx에 노출되어 바람직하지 않다는 것입니다. 그러나 현재 이것은 사용할 수있는 하나의 도커 특정 해결 방법입니다.
Depend_on 기능 이것은 아마도 미래의 대답이 될 것입니다. 기능이 아직 Docker에서 구현되지 않았기 때문에 (1.9 기준)
Docker가 도입 한 새로운 네트워킹 기능에 "depends_on"을 도입하라는 제안이 있습니다. 그러나 동일한 @ https://github.com/docker/compose/issues/374 에 대한 오랜 논쟁이 있습니다. 따라서 일단 구현되면 기능 의존 _ 온을 사용하여 컨테이너 시작을 주문할 수 있지만 순간, 다음 중 하나에 의지해야합니다.
- PHP 서버가 올라갈 때까지 nginx를 재 시도하십시오-나는 이것을 선호합니다
- 위에서 설명한대로 volums_from 해결 방법을 사용하십시오. 불필요한 컨테이너로의 볼륨 누출 때문에 이것을 사용하지 않을 것입니다.
이것은 depends_on
지금 구현되었으므로 (2016) 언급 된 지시문 으로 해결할 수 있습니다 .
version: '2'
services:
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
depends_on:
- mongo
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
성공적으로 테스트 :
$ docker-compose version
docker-compose version 1.8.0, build f3628c7
자세한 내용은 설명서를 참조하십시오 .
이 주제에 관한 매우 흥미로운 기사도 있습니다. Compose에서 시작 순서 제어
nginx의 max_fails 및 fail_timeout 지시문을 설정하여 nginx가 업스트림 서버를 사용할 수없는 상태에서 실패하기 전에 컨테이너에 대한 연결 요청 x 회를 재 시도해야 함을 나타낼 수 있습니다.
인프라 및 전체 설정이 진행되는 속도에 따라이 두 수치를 조정할 수 있습니다. 아래 URL의 상태 확인 섹션에 대한 자세한 내용을 읽을 수 있습니다. http://nginx.org/en/docs/http/load_balancing.html
다음은 http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server 에서 발췌 한 것입니다. max_fails=number
fail_timeout 매개 변수로 설정된 기간 동안 서버를 사용할 수없는 것으로 간주하기 위해 fail_timeout 매개 변수로 설정된 기간 동안 발생해야하는 서버와의 통신 실패 횟수를 설정합니다. 기본적으로 실패한 시도 횟수는 1로 설정됩니다. 0 값은 시도 계산을 비활성화합니다. 실패한 시도로 간주되는 것은 proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream 및 memcached_next_upstream 지시문에 의해 정의됩니다.
fail_timeout=time
서버를 사용할 수없는 것으로 간주하기 위해 서버와의 통신 시도에 실패한 지정된 횟수의 시간을 설정합니다. 서버를 사용할 수없는 것으로 간주되는 기간입니다. 기본적으로 매개 변수는 10 초로 설정됩니다.
정확하게 수정 된 nginx 구성 파일은 다음과 같아야합니다 (이 스크립트는 모든 컨테이너가 적어도 25 초 이상 작동한다고 가정합니다. 그렇지 않은 경우 아래 업스트림 섹션에서 fail_timeout 또는 max_fails를 변경하십시오) : 참고 : 그렇지 않았습니다. 스크립트를 직접 테스트하여 사용해 볼 수 있습니다!
upstream phpupstream {
waapi_php_1:9000 fail_timeout=5s max_fails=5;
}
server {
listen 80;
root /var/www/test;
error_log /dev/stdout debug;
access_log /dev/stdout;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
# Referencing the php service host (Docker)
fastcgi_pass phpupstream;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# We must reference the document_root of the external server ourselves here.
fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
또한 docker ( https://github.com/docker/compose/blob/master/docs/networking.md ) 의 다음 참고 에 따라 다른 컨테이너의 상태를 확인하기위한 재시도 논리가 그렇지 않은 것이 분명합니다. 도커의 책임이며 컨테이너가 스스로 상태를 확인해야합니다.
컨테이너 업데이트
서비스에 대한 구성을 변경하고이를 업데이트하기 위해 docker-compose를 실행하면 이전 컨테이너가 제거되고 새 컨테이너가 다른 IP 주소이지만 동일한 이름으로 네트워크에 연결됩니다. 실행중인 컨테이너는 해당 이름을 찾아 새 주소에 연결할 수 있지만 이전 주소는 작동을 멈 춥니 다.
이전 컨테이너에 대한 연결이 열려있는 컨테이너가 있으면 닫힙니다. 이 조건을 감지하고 이름을 다시 찾은 다음 다시 연결하는 것은 컨테이너의 책임입니다.
Nginx가 Docker resolver (127.0.0.11)를 고려하지 않는다고 생각하므로 다음을 추가해보십시오.
resolver 127.0.0.11
nginx 구성 파일에 있습니까?
당신이 너무 길을 잃었다면 마지막 코멘트를 읽으십시오. 나는 다른 해결책에 도달했습니다.
주된 문제는 서비스 이름을 지정하는 방식입니다.
이 경우에서 docker-compose.yml
php 용 서비스가 "api"또는 이와 유사한 이름 인 경우 파일 nginx.conf
에서로 시작하는 줄이 fastcgi_pass
php 서비스와 동일한 이름을 갖는지 확인해야합니다. 즉fastcgi_pass api:9000;
두 개의 네트워크가 정의 되었기 때문에 동일한 문제가 발생했습니다 docker-compose.yml
. 하나는 백엔드이고 하나는 프런트 엔드입니다.
동일한 기본 네트워크에서 컨테이너를 실행하도록 변경했을 때 모든 것이 제대로 작동하기 시작했습니다.
같은 문제가 있었고 그것을 해결했습니다. docker-compose.yml nginx 섹션에 다음 줄을 추가하십시오.
links:
- php:waapi_php_1
nginx config fastcgi_pass 섹션의 호스트는 docker-compose.yml nginx 구성 내부에 연결되어야합니다.
링크를 사용하면 컨테이너 시작 순서가 적용됩니다. 링크가 없으면 컨테이너는 임의의 순서로 (또는 실제로 한 번에 모두) 시작할 수 있습니다.
waapi_php_1
컨테이너가 시작 속도가 느리면 이전 설정이 동일한 문제를 일으킬 수 있다고 생각합니다 .
나는 그것을 작동시키기 위해 PHP 컨테이너가 시작되고 준비 될 때까지 폴링하고 기다리는 nginx 진입 점 스크립트를 만들 수 있다고 생각합니다.
nginx가 업스트림에 대한 연결을 자동으로 재 시도 할 수있는 방법이 있는지 확실하지 않지만, 그렇다면 더 나은 옵션이 될 것입니다.
백엔드가 가동 될 때 nginx 구성을 동적으로 업데이트하려면 docker-gen과 같은 것을 사용해야합니다.
보다:
Nginx + (프리미엄 버전)에도 resolve 매개 변수가 포함되어 있다고 생각합니다 ( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream )
컨테이너 연결 문제를 방지하는 최선의 선택은 Docker 네트워킹 기능 일 것입니다.
그러나이 작업을 수행하기 위해 docker 는 할당 된 이름에서 각 컨테이너에 대한 각 컨테이너 의 / etc / hosts 에 항목을 만듭니다 .
docker-compose --x-networking -up은 [docker_compose_folder]-[service]-[incremental_number]와 같습니다.
이러한 이름의 예기치 않은 변경에 의존하지 않으려면 매개 변수를 사용해야합니다.
container_name
다음과 같이 docker-compose.yml에서 :
php:
container_name: waapi_php_1
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
이 서비스에 대한 구성 파일에 지정된 이름과 동일한 지 확인하십시오. 이 작업을 수행하는 더 좋은 방법이 있다고 확신하지만 시작하기에 좋은 방법입니다.
내 해결 방법 (많은 시행 착오 후) :
이 문제를 해결 하려면 업스트림 컨테이너 의 전체 속성을 실행 하고 가져 와서 찾은 '업스트림'Docker 컨테이너 의 전체 이름 을 가져와야했습니다 .
docker network inspect my-special-docker-network
name
"Containers": { "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": { "Name": "my_upstream_container_name_1_2478f2b3aca0",
그런 다음 속성 블록의 NGINX
my-network.local.conf
파일에서 다음을 사용 했습니다. (컨테이너 이름에 GUID 추가에 유의하십시오) :location
proxy_pass
location / { proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
이전에 작동했지만 지금은 깨졌습니다.
location / {
proxy_pass http://my_upstream_container_name_1:3000
가장 가능성이 높은 원인은 여기에 나열된 컨테이너의 기본 이름 지정 체계에서 Docker Compose의 최근 변경 사항 입니다.
이것은 최신 버전의 Docker nginx
이미지 를 사용하여 나와 내 팀에서 발생하는 것 같습니다 .
- 나는 docker / compose GitHub 에서 문제를 열었습니다.
(new to nginx) In my case it was wrong folder name
For config
upstream serv {
server ex2_app_1:3000;
}
make sure the app folder is in ex2 folder:
ex2/app/...
Two things worth to mention:
- Using same network bridge
- Using
links
to add hosts resol
My example:
version: '3'
services:
mysql:
image: mysql:5.7
restart: always
container_name: mysql
volumes:
- ./mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: tima@123
network_mode: bridge
ghost:
image: ghost:2
restart: always
container_name: ghost
depends_on:
- mysql
links:
- mysql
environment:
database__client: mysql
database__connection__host: mysql
database__connection__user: root
database__connection__password: xxxxxxxxx
database__connection__database: ghost
url: https://www.itsfun.tk
volumes:
- ./ghost-data:/var/lib/ghost/content
network_mode: bridge
nginx:
image: nginx
restart: always
container_name: nginx
depends_on:
- ghost
links:
- ghost
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/letsencrypt:/etc/letsencrypt
network_mode: bridge
If you don't specify a special network bridge, all of them will use the same default one.
Add the links section to your nginx container configuration.
You have to make visible the php
container to the nginx
container.
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
links:
- php:waapi_php_1
This is how I get it over, the best way I can think of.
ADD root /
RUN cp /etc/hosts /etc/hosts.tmp && \
echo -e "\
127.0.0.1 code_gogs_1 \n\
127.0.0.1 pm_zentao_1 \n\
127.0.0.1 ci_drone_1 \n\
" >> /etc/hosts && \
nginx -t && \
# mv: can't rename '/etc/hosts.tmp': Resource busy
# mv /etc/hosts.tmp /etc/hosts
cat /etc/hosts.tmp > /etc/hosts && \
rm /etc/hosts.tmp
'developer tip' 카테고리의 다른 글
IIS 7에서 "통과 인증"이란 무엇입니까? (0) | 2020.10.22 |
---|---|
Docker 내에서 루트가 아닌 사용자로 앱 실행 (0) | 2020.10.22 |
주어진 Lat Lng 위치에서 특정 거리 내에있는 모든 Latitude Longitude 위치를 찾는 알고리즘 (0) | 2020.10.22 |
TypeScript를 축소 된 코드로 컴파일 할 수 있습니까? (0) | 2020.10.22 |
shared_ptr 전달 (0) | 2020.10.22 |