도커에서 컨테이너는 서로 격리된 환경에서 동작하므로, 기본적으로 컨테이너끼리는 서로 통신할 수 없다. 하지만 여러 컨테이너를 하나의 도커 네트워크에 연결시키면 서로 통신이 가능해진다. 도커 네트워크에 대해 알아보자.
도커 네트워크 조회
먼저 docker network ls 명령어를 통해 현재 생성된 네트워크를 조회해보자.
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
5ff1ee73cdfc   bridge    bridge    local
4bb888e5a996   host      host      local
a0a0b6f89227   none      null      local
이 bridge, host, none은 Docker를 실행하면 자동으로 생성되는 네트워크다. 컨테이너를 생성하면 기본적으로 이 브릿지 네트워크를 사용하게 된다. 이 브릿지 네트워크를 docker0 브릿지라고 하는데, docker0 브릿지는 172.17.0.0/16 CIDR를 갖기 때문에 여기에 컨테이너를 생성하면 172.17.0.1, 172.17.0.2처럼 차례로 IP를 할당받게 된다.
네트워크 종류
도커 네트워크엔 기본적으로 bridge, host, none, container, overlay 네트워크가 있다.
- bridge: 호스트 내의 같은 브릿지에 있는 컨테이너끼리 통신을 가능하게 해준다.
- host: 호스트의 네트워크 환경을 그대로 사용한다. 따라서 포트포워딩 작업이 필요가 없다.
- none: 컨테이너를 완전히 고립시킨다. 어떤 컨테이너와도 통신할 수 없다.
- container: 다른 컨테이너의 네트워크 환경을 공유한다.
- overlay: 분산된 네트워크(도커 호스트가 여러개)인 환경에서 도커를 사용해야 할 때 사용한다.
컨테이너간 통신
이제 docker-compose와 브릿지를 이용해 두 컨테이너를 생성하고, 컨테이너끼리 ping 통신을 날려보도록 하자. 아래 코드를 docker-compose up 명령어를 통해 실행시키자
version: '3'
services:
  service1:
    image: busybox:latest
    tty: true #바로 종료되는걸 막기 위함
    networks:
      - my_network
  service2:
    image: busybox:latest
    tty: true 
    networks:
      - my_network
networks:
  my_network:
    driver: bridge
실행이 끝났다면, docker ps 명령어를 통해 컨테이너ID를 가져오자.
macintosh@Macintoshui-MacBookPro ~ % docker ps
CONTAINER ID   IMAGE            COMMAND   CREATED         STATUS         PORTS     NAMES
865eaac3a6cf   busybox:latest   "sh"      2 minutes ago   Up 2 minutes             service2-1
7aba153cd49d   busybox:latest   "sh"      2 minutes ago   Up 2 minutes             service1-1
이제 docker exec <컨테이너ID> ifconfig을 통해 IP를 가져와보자.
macintosh@Macintoshui-MacBookPro ~ % docker exec <컨테이너ID> ifconfig
zsh: no such file or directory: 컨테이너ID
macintosh@Macintoshui-MacBookPro ~ % docker exec 865eaac3a6cf ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:14:00:03  
          inet addr:172.20.0.3  Bcast:172.20.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:25 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1914 (1.8 KiB)  TX bytes:496 (496.0 B)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:36 errors:0 dropped:0 overruns:0 frame:0
          TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2576 (2.5 KiB)  TX bytes:2576 (2.5 KiB)
컨테이너의 IP가 172.20.0.3인 것을 알았다. 그럼 이제 다른 컨테이너에서 ping 명령어를 날려보자.
macintosh@Macintoshui-MacBookPro ~ % docker exec 7aba153cd49d ping 172.20.0.3
PING 172.20.0.3 (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.857 ms
64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.361 ms
64 bytes from 172.20.0.3: seq=2 ttl=64 time=0.557 ms
64 bytes from 172.20.0.3: seq=3 ttl=64 time=0.354 ms
...
정상적으로 통신이 되는것을 볼 수 있다. 추가로, 도커는 서로 같은 네트워크안에선 아이피 주소가 아닌 서비스 이름으로도 서로 통신을 할 수 있다. yaml파일에서 생성한 service1이라는 이름으로 ping 통신을 날려보자.
macintosh@Macintoshui-MacBookPro ~ % docker exec 7aba153cd49d ping service1  
PING service1 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.405 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.195 ms
64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.395 ms
64 bytes from 172.20.0.2: seq=3 ttl=64 time=0.302 ms
역시 통신이 가능한 것을 볼 수 있다.

