web 서버 역할의 컨테이너와 DB 서버 역할의 컨테이너가 있다고 가정해 보자.
만약, 이 두 container 사이를 연동하고 싶을때는 어떻게 해야 할까?
이번 포스팅에는 container 사이 연동에 필요한 link 옵션에 대한 사용법과 동작 구조에 대해 알아보자.
Docker 의 Private IP
Web 서버 역할의 컨테이너와 DB 서버 역할의 컨테이너가 있다고 생각해 보자.
앞서 살펴보았듯이 배포된 컨테이너는 Private IP 를 가지고 있다.
그래서 web 에서 mysql 컨테이너로 ping 을 보내면 아래와 같이 응답함을 확인할 수 있다.
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca7f026ff0ad httpd "httpd-foreground" 55 minutes ago Up 55 minutes 0.0.0.0:80->80/tcp web
17b6c5f037a9 mysql "docker-entrypoint.sh" About an hour ago Up 50 minutes 0.0.0.0:3306->3306/tcp mysql
$ docker inspect --format "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.6
$ docker inspect --format "{{ .NetworkSettings.IPAddress }}" web
172.17.0.3
$ docker exec -t web ping 172.17.0.6
PING 172.17.0.6 (172.17.0.6): 56 data bytes
64 bytes from 172.17.0.6: icmp_seq=0 ttl=64 time=0.103 ms
64 bytes from 172.17.0.6: icmp_seq=1 ttl=64 time=0.117 ms
64 bytes from 172.17.0.6: icmp_seq=2 ttl=64 time=0.111 ms
64 bytes from 172.17.0.6: icmp_seq=3 ttl=64 time=0.114 ms
64 bytes from 172.17.0.6: icmp_seq=4 ttl=64 time=0.111 ms
64 bytes from 172.17.0.6: icmp_seq=5 ttl=64 time=0.116 ms
|
IP 기반 연동의 문제점
Container 사이의 IP 기반 연동은 문제점을 안고 있다.
Container 의 IP 는 언제든 변할 수 있는 유동적인 성격을 띄고 있기 때문이다.
Container 는 일종의 Process 이므로, 언제든 생성/소멸 될 수 있음을 전제로 해야한다.
만약 Container가 중지 되었다가 시작하면, Process가 kill 되었다가 다시 새롭게 생성되는 것과 같다.
이때, Container 에게 부여되는 Private IP는 언제든 변할 수 있다.
따라서, Container 사이 연동을 하려면, IP 기반의 설정은 권고되지 않는다.
그 해결 방법으로 권고 되고 있는 방법이 바로 link 옵션이다.
$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.6
$ docker stop mysql #mysql 컨테이너 중지
$ docker start mysql #mysql 컨테이너 기동
$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.5 # mysql 컨테이너의 IP를 확인해 보니 5로 바뀌었다.
|
link
docker run 을 이용해 webe02 container를 띄울때,
--link 옵션을 이용해 mysql container 와 link를 맺을 것을 설정한다.
이렇게 설정하면, web02 container 는
mysql container 를 IP 가 아닌 container의 이름을 이용해 통신할 수 있다.
도커는 link 옵션을 설정할 때 컨테이너의 이름을 도메인 이름으로 사용한다.
$ docker run -d --name web02 --link mysql httpd
14f6f2a16abc8660ba32004c8eff091e5a16f0ace57a3609d770f845485d103f
$ docker exec -t web02 ping mysql
PING mysql (172.17.0.6): 56 data bytes
64 bytes from 172.17.0.6: icmp_seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.6: icmp_seq=1 ttl=64 time=0.091 ms
64 bytes from 172.17.0.6: icmp_seq=2 ttl=64 time=0.104 ms
...
|
link 동작원리
container 이름을 기반으로 통신을 하면, IP가 바뀐다고 해도
문제 없이 통신이 가능한 이유를 확인해 보자.
container 가 구동되면, container 환경 중 일부는 docker daemon에 의해 자동으로 제어 된다.
이 중 한가지가 container 내부의 domain name을 관리하는 hosts 파일이다.
link 연동이 걸린 web02 container의 hosts 파일을 살펴보자
$ docker exec -t web02 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.6 mysql 17b6c5f037a9
172.17.0.2 14f6f2a16abc
|
위와 같이 web02 container의 /etc/hosts 파일에 mysql container 의 IP 주소와 host명이 등록되어 있다.
link를 걸지 않으면, 이 정보가 없다.
만약, link가 걸린 상태에서 mysql container가 재 기동되어 IP가 바뀐다면 어떻게 될까?
$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.6 mysql 17b6c5f037a9
172.17.0.2 14f6f2a16abc
$ docker stop mysql
$ docker start mysql
$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.5 # mysql 컨테이너의 IP를 확인해 보니 5로 바뀌었다.
$ docker exec -t web02 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.5 mysql 17b6c5f037a9 # web02의 hosts 파일 자동 갱신
172.17.0.2 14f6f2a16abc
|
위와 같이 MySQL 컨테이너와 link 가 걸린 web02 컨테이너의
hosts 파일 정보가 자동으로 갱신됨을 볼 수 있다.
즉, link 옵션을 이용하면, container 의 IP 정보가 수시로 갱신될 수 있는 환경에서도
서로간 문제 없이 통신이 가능하겠다.
link 방식의 한계
container 사이에는 link 를 이용해 연동해야 동적 IP에 따른 이슈를 피할수 있다.
하지만 link 방식만으로는 여전히 한계가 있다.
첫째로, link 옵션은 동일 docker host 에 존재하는 container 사이에서만 유효하다.
만약 다수의 docker host 를 운영할 경우에
타 host에 상주하는 container 사이에는 link 옵션 이용이 불가하다.
컨테이너의 hosts 파일의 관리를 docker host가 직접 수행하기 때문이다.
이러한 경우, docker swarm 같은 orchestration 툴을 도입하거나 dynamic DNS 를 구축해 사용해야 한다.
'Container > Docker' 카테고리의 다른 글
16. Docker Storage (0) | 2020.01.14 |
---|---|
15. Docker Network DNS (0) | 2020.01.14 |
13. Docker Network Overview (0) | 2020.01.14 |
12. Docker Compose (0) | 2020.01.14 |
11. Docker Container Life Cycle (0) | 2020.01.14 |