도커 컨테이너에서 호스트 개인 인터페이스 (ip)에 액세스하는 데 문제가 있습니다. 나는 그것이 Iptables 규칙 (또는 라우팅)과 관련이 있다고 확신합니다. 에 --net=host
플래그를 추가하면 docker run
모든 것이 예상대로 작동합니다. 마찬가지로 INPUT 정책이 자유주의를 따르도록 지정 -P INPUT ACCEPT
하면 예상대로 작동합니다. 그러나 이것은 바람직하지 않고 안전하지 않은 옵션입니다.
내 서비스 (DNS)에만 국한되지 않기 때문에 문제에서 제외했습니다. 도커와 함께 검색하면 다른 (인기있는) 문제 영역에서 결과가 나오기 때문에 검색 결과에 노이즈가 추가됩니다.
또한 Docker 컨테이너의 링크는 실행 가능한 옵션이 아닙니다. 왜냐하면 특정 컨테이너는 --net = host 옵션으로 실행해야 연결이 불가능하고 가능한 한 일관된 상황을 만들고 싶습니다.
다음 Iptables 규칙이 있습니다. CoreOS, Digital Ocean 및 Docker의 조합으로 가정합니다.
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
내 (관련) 호스트 인터페이스 :
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 10.129.112.210/16 brd 10.129.255.255 scope global eth1
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
그리고 도커 컨테이너를 실행합니다.
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
이 시점에서 10.129.112.210:53에 바인딩 된 로컬 서비스를 사용할 수 있기를 원합니다. 따라서 다음과 같은 답변이 제공됩니다.
$ ping google.com
^C
$ ping user.skydns.local
^C
호스트에서 동일한 명령을 실행할 때 :
$ ping photo.skydns.localPING photo.skydns.local (10.129.112.206) 56(84) bytes of data.
64 bytes from 10.129.112.206: icmp_seq=1 ttl=64 time=0.790 ms
^C
내 resolv.conf
$ cat /etc/resolv.conf
nameserver 10.129.112.210
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
여기서 중요한 점은 호스트에서 사용 가능한 로컬 DNS 서비스 (다른 도커 인스턴스를 통해)를 사용하여 퍼블릭 호스트가 아니라 내부 호스트에 액세스하는 것입니다.
더 자세히 설명하기 위해 (아스키 아트 디자인 기술이 내 iptables fu를 능가 하므로이 시점에서 충분히 말해야합니다) :
______________________________________________
| __________________________ Host |
| | Docker DNS container | |
| ``````````````````````|``` |
| | |
| ,----------,---( private n. interface ) |
| | | |
| | | ( public n. interface )---
| | | |
| | | ( loopbck n. interface ) |
| | | |
| | | |
| | __|_______________________ |
| | | Docker service container | |
| | `````````````````````````` |
| | |
| | |
| [ Local host service using DNS. ] |
| |
|______________________________________________|
private (host) network interface: eth1 (10.129.0.0/16)
Docker network interface: docker0 (172.17.0.0/16)
나는 다른 예제 Iptables 구성을 검색하고 읽고 적용했지만, 진행중인 상황을 이해하고 원하는 결과를 얻기 위해 더 "고급"Iptables 규칙을 너무 적게 알고 있습니다.
출력 iptables -t nat -nL
:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
출력 cat /proc/sys/net/ipv4/ip_forward
:
1
$ cat /proc/sys/net/ipv4/ip_forward -> 1
그리고 -A INPUT -i eth1 -j ACCEPT
온 모든 연결을 받아 개인 인터페이스를. 어떤 규칙이 누락 되었습니까?
-A INPUT -i docker0 -j ACCEPT
iptables -t nat -nL
? 소스 컨테이너에서 핑을 수행하고 tcpdump를 사용하여 호스트의 패킷을 캡처하는 등 패킷 분석을 수행 했습니까?