브리지된 네트워크에 컨테이너가 있습니다. 문제 없이 호스트에 도달하고 호스트의 모든 포트에 연결됩니다(다른 컨테이너에서 게시한 포트 제외).
사용자 영역 프록시를 비활성화했기 때문에 docker가 iptable 규칙을 설정하는 방법과 관련이 있을 수 있다고 생각했습니다.
컨테이너가 다른 컨테이너(다른 브리지 네트워크에서 실행)가 게시한 포트에 도달하도록 허용하는 쉬운 방법이 있습니까?
두 컨테이너를 동일한 네트워크에 두지 않거나 호스트 네트워크로 전환하고 싶습니다.
답변1
문제를 재현할 수 없습니다.
두 개의 Docker 브리지 네트워크를 정의했습니다.
eecf335e7600 net1 bridge local
5c7ca74637b0 net2 bridge local
c1
네트워크에서 컨테이너를 시작하고 net1
컨테이너 포트를 8080
호스트 포트에 게시합니다 8081
.
$ docker run -d --rm --net net1 -p 8081:8080 --name c1 \
--add-host host.docker.local:host-gateway alpinelinux/darkhttpd
c2
네트워크에서 컨테이너를 시작하고 net2
컨테이너 포트를 8080
호스트 포트에 게시합니다 8082
.
$ docker run -d --rm --net net2 -p 8082:8080 --name c2 \
--add-host host.docker.local:host-gateway alpinelinux/darkhttpd
이제 컨테이너 내부에서 c1
호스트 포트에 액세스하여 컨테이너의 웹 서비스에 액세스할 수 있습니다.c2
8082
$ docker exec c1 wget -O- http://host.docker.local:8082
Connecting to host.docker.local:8082 (172.17.0.1:8082)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
...
컨테이너에서 c2
호스트 포트에 액세스하여 컨테이너의 웹 서비스에 액세스할 수 있습니다.c1
8081
$ docker exec c2 wget -O- http://host.docker.local:8081
Connecting to host.docker.local:8081 (172.17.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
...
모든 것이 광고된 대로 작동하는 것 같았습니다. 동일한 단계를 반복해도 결과가 달라지는 경우 가장 먼저 확인해야 할 것은 호스트에 트래픽을 방해할 수 있는 방화벽 규칙이 있는지 확인하는 것입니다.
고쳐 쓰다
--add-host
예상대로 해당 옵션을 사용하는 대신 호스트 주소만 선택해도 동작은 동일합니다. 예를 들어 다음과 같은 경우가 있습니다.
$ ip -o addr |grep -o '.*inet [^ ]*'
1: lo inet 127.0.0.1/8
2: eth0 inet 192.168.123.106/24
4: docker_gwbridge inet 172.23.0.1/16
8: br-70f125dc5b7d inet 192.168.208.1/20
15: br-a87cc1462629 inet 172.29.0.1/16
18: docker0 inet 172.17.0.1/16
35: br-eecf335e7600 inet 172.18.0.1/16
36: br-5c7ca74637b0 inet 172.19.0.1/16
그러면 이것들은 모두 작동합니다:
$ docker exec c2 wget -O- 192.168.123.106:8081 | head -3
Connecting to 192.168.123.106:8081 (192.168.123.106:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
$ docker exec c2 wget -O- 172.29.0.1:8081 | head -3
Connecting to 172.29.0.1:8081 (172.29.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
$ docker exec c2 wget -O- 172.18.0.1:8081 | head -3
Connecting to 172.18.0.1:8081 (172.18.0.1:8081)
writing to stdout
- 100% |********************************| 191 0:00:00 ETA
written to stdout
<html>
<head>
<title>/</title>
등.
비활성화하기 전에 이 문제가 있었던 것이 확실하기 때문에 질문에서 언급하지 않았습니다.
이는 기본 설정에 비해 꽤 큰 구성 변경 사항입니다. :)
사용자 레이어 프록시를 비활성화하면 모든 것이 작동하지 않습니다.
이 기사관심이 있을 수 있는 항목:
이전 섹션에서는 Docker가 iptables NAT 규칙을 사용하여 게시된 포트를 컨테이너 서비스에 매핑할 수 없는 두 가지 시나리오를 식별했습니다.
- 다른 Docker 네트워크에 연결된 컨테이너가 서비스에 액세스하려고 할 때(Docker가 Docker 네트워크 간의 직접 통신을 차단하고 있는 경우)
- 로컬 프로세스가 루프백 인터페이스를 통해 서비스에 액세스하려고 시도하는 경우.
두 경우 모두 Docker는 사용자 수준(Linux 프로세스) TCP 또는 UDP 프록시를 사용합니다. 게시된 포트로 컨테이너를 시작한 후 netstat 명령을 사용하여 프록시를 쉽게 식별할 수 있습니다(표준 Flask 애플리케이션을 다시 사용하겠습니다).