이전에 기본 설정인 bridge 모드와 host 모드 그리고 null 모드까지 모두 봤어요.

그런데 어떠한 필요에 의해서 컨테이너의 서비스들이 같은 IP를 써야 하는 경우가 있을 수 있어요. 그럴 때는 어떻게 해야 할까요? 간단한지는 잘 모르겠지만 컨테이너 하나에 2개의 서비스를 넣는 방법이 있을 수 있겠네요. 하지만 이런 방법은 무슨무슨 법 위반이래요.

 

이럴 때 사용할 수 있는 좋은 방법이 있는데 바로 IP를 공유하는 거예요.

시간 날 때 그림을 그려서 올려보도록 할게요. 우선은 설명하자면

 

  1. 도커가 컨테이너를 생성하면서 그 컨테이너를 위한 네트워크 네임스페이스를 생성하고 가상 인터페이스도 만들어서 그 인터페이스에 IP도 할당해요.
  2. 서비스 1이 돌아가는 컨테이너를 만들면서 네트워크를 bridge도 아니고 host도 아니고 null도 아닌 1에서 만든 컨테이너의 네트워크를 할당해줘요. 붙여준다고 이야기하는 게 더 좋을까요?
  3. 또 다른 서비스 2가 돌아가는 컨테이너를 만들면서 아까 1번에서 만들었던 컨테이너의 네트워크를 또 붙여줘요.
  4. 끝.

설명이 길면 지루하니까 바로 볼게요.

➜  ~ docker container run -d -it --name containerofcontainer alpine 
ed6836c9dc8c4c535df2114c22d3ee92d8721e181994b950408984f536bcda7d

➜  ~ docker exec containerofcontainer ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
120: eth0@if121: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
       
➜  ~ docker container run -d -it --network container:containerofcontainer nginx:1.14
8d90959f158020af2b1f15799015ecf2640c5fbf9d9dc3fcc0de644b5cb5ab34

➜  ~ curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

➜  ~ docker container run -d -it --network container:containerofcontainer xodwkx2/show-me-host:2.0.0
bed64aa02a3d5e864d4ef8da9a11cda328655145e6614ee5a00560c9b3c77385

➜  ~ docker ps 
CONTAINER ID   IMAGE                        COMMAND                  CREATED              STATUS              PORTS     NAMES
bed64aa02a3d   xodwkx2/show-me-host:2.0.0   "docker-entrypoint.s…"   3 seconds ago        Up 3 seconds                  peaceful_bhaskara
8d90959f1580   nginx:1.14                   "nginx -g 'daemon of…"   About a minute ago   Up About a minute             interesting_kare
ed6836c9dc8c   alpine                       "/bin/sh"                8 minutes ago        Up 8 minutes                  containerofcontainer

➜  ~ curl 172.17.0.2:8080
Your app is running on Host: ed6836c9dc8c

alpine 이미지를 사용해서 첫 번째 컨테이너를 bridge 네트워크 모드로 하나 생성했어요. 이름은 컨테이너의 컨테이너라는 의미로 containerofcontainer라고 지어봤어요. 그리고 IP를 확인해보니 172.17.0.2/16으로 나오네요.

 

그리고 바로 이름은 따로 주지 않고 nginx:1.14 이미지로 두 번째 컨테이너를 생성했어요. 이때 네트워크 옵션을

--network container:containerofcontainer라고 줬어요. 포트는 따로 개제하지 않고 생성했어요. 그러면 컨테이너의 IP:PORT 조합으로만 접속할 수 있겠죠? 아이피 확인 없이 믿음으로 바로 172.17.0.2(:80)로 curl 명령을 날려봤어요.

예상대로 Welcome to nginx!라는 반가운 메시지가 떴어요.

 

이번에는 너의-호스트-이름을-보여줘:2.0.0 이미지를 사용해서 세 번째 컨테이너를 생성했어요 마찬가지로 네트워크는 컨테이너의 컨테이너 컨테이너 네트워크를 붙여줬어요. 이 이미지는 8080 포트를 기본으로 열고 서비스하는 nodejs 애플리케이션이 돌아가고 있어요. 그래서 alpine 컨테이너의 8080 포트로  curl 명령을 때려봤어요.

 

여기서 돌아오는 대답이 ed6836.. 너의-호스트-이름을-보여줘:2.0.0 컨테이너의 ID가 아니라 컨테이너의 컨테이너 컨테이너 ID가 나왔어요. 그래서 한번 확인해봤어요.

➜  ~ docker exec bed64aa02a3d hostname
ed6836c9dc8c

 

그리고 하나 더 너의-호스트-이름을-보여줘:2.0.0 컨테이너에서 curl localhost(:80)을 해봤어요. 그리고 8080은 당연히 될 거구요. 내친김에 어떤 포트들이 열려있는지 확인해봤습니다. 그리고 nginx 컨테이너에서도 어떤 포트들이 열려있는지 확인해봤어요. 각각 컨테이너에서 오픈된 포트는 모두 보여주면서 다른 컨테이너에서 실행되고 있는 프로세스의 ID는 - 로 나오는 게 인상 깊었어요.

root@ed6836c9dc8c:/usr/src/app# curl localhost   
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

root@ed6836c9dc8c:/usr/src/app# curl localhost:8080
Your app is running on Host: ed6836c9dc8c

root@ed6836c9dc8c:/usr/src/app# netstat -nlpt 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1/node              
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -

# netstat -nlpt 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro

 

이렇게 쓰는 데가 도대체 어디 있냐구요?

그 건 쿠버네티스 파드에 대해서 파헤쳐볼 때 마저 이야기해보도록 하지요.

 

끝!