도커 컨테이너 내부로 포워딩하기

도커로 테스트 환경을 구축 후 웹 호출 테스트 진행을 해야했다.
host OS로 브라우저에서 호출했을때, 도커 컨테이너에서 응답하게 하기 위해
iptables 의 nat설정에 대해 작성하였다.

1.준비과정

먼저 도커 컨테이너에 구축된 웹서버를 구동한다.

[root@552677a7c57e ~]# systemctl start httpd
[root@552677a7c57e ~]# curl  127.0.0.1
docker test
[root@552677a7c57e ~]#

컨테이너 내부에서 curl호출시 정상 호출된다.

2.IPTABLES 룰 확인

기본적으로 도커를 설치 후 구동하면 iptables 에 forward,nat룰이 생성된다.(기본옵션일 경우)

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
Chain OUTPUT (policy ACCEPT 4 packets, 544 bytes)
 pkts bytes target     prot opt in     out     source               destination         
Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0    
Chain PREROUTING (policy ACCEPT 3 packets, 124 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    3   124 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0 

도커 컨테이너 생성시 proxy설정(예를들어 " -p 192.168.0.100:80:80" 와 같은 옵션을 지정하지 않았다면,)이 되어있지 않다면, 내부로 연결이 되지 않는다.
이럴 경우, 옵션을 주고 재생성하면 되지만, iptables 포워딩으로도 할 수가 있다.

3. 적용 테스트

우선 현재 host os엔 80포트로 구동되어 사용중인 웹서버가 존재하나, iptables로 80포트 인입되는 패킷은 내부 컨테이너로 포워딩 처리할 예정이다,
그러므로, 포워딩 적용이 되면 처음 host의 아파치가 아닌 , 컨테이너의 아파치로 연결될 것이다.

host로 브라우저 접근시, host에서 구동중인 웹서버로 연결이 된다.

우선 컨테이너의 IP를 확인해야 한다.

docker inspect 552677a7c57e | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
위 명령어로 확인이 가능하다 

이제 내부 IP를 알았으니, nat,forward 룰을 넣어야 한다.

#nat rule
iptables -t nat -A PREROUTING -p tcp -d 192.168.0.100(host os IP) --dport 80 -j DNAT --to-destination 172.17.0.2:80 
#forward rule / 내부 컨테이너로 포워딩 되는 부분에 대해서 ACCEPT처리를 해줘야 한다.
iptables -A FORWARD -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j ACCEPT   

이제 브라우저에서 접속하여 어디로 연결되는지 확인한다.

iptables 포워딩 설정으로 host os가 아닌 내부 컨테이너로 연결되며,적용테스트에서 초기 확인되었던 host의 아파치가 아닌, 내부 컨테이너의 페이지로 연결되는게 확인된다.