일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- network
- aws codecommit
- 실사용
- 토스카드
- MongoEngine
- 리뷰
- MongoDB
- 리워드앱
- Container
- 후기
- 앱테크
- python3
- Python
- built-in
- 포인트앱
- clone
- DocumentDB
- 재테크
- Linux
- AWS
- VPC
- namespace
- codecommit
- S3
- 하나머니
- mininet
- docker
- 도커
- docker network
- 커피머니불리기
- Today
- Total
ㅍㅍㅋㄷ
Docker Network 구조(4) - container link 구조 본문
Docker Network 구조 (4) - Container link 구조
[Contents]
1. Docker Network 구조(1) - docker0와 container network 구조
2. Docker Network 구조(2) - Container network 방식 4가지
3. Docker Network 구조(3) - Container 외부 통신 구조
4. Docker Network 구조(4) - Container link 구조
web 서버 역할의 컨테이너와 DB 서버 역할의 컨테이너가 있다고 가정해 보자.
만약, 이 두 container 사이를 연동하고 싶을때는 어떻게 해야 할까.
이번 포스팅에는 container 사이 연동에 필요한 link 옵션에 대한 사용법과 동작 구조에 대해 알아보고자 한다.
Container 연동시 link 를 사용해야 하는 이유
사실 동일 host 상에 배포된 container 사이는 Private IP 를 이용해 통신이 가능하다.
아래는 host 상에 running 중인 두개의 container 이다.
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 web01
17b6c5f037a9 mysql "docker-entrypoint.sh" About an hour ago Up 50 minutes 0.0.0.0:3306->3306/tcp mysql
두 컨테이너 mysql 과 web01 의 Private IP 는 아래와 같다.
root@~~# docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.6
root@~~# docker inspect -f "{{ .NetworkSettings.IPAddress }}" web01
172.17.0.3
만약, web01 --> mysql (172.17.0.6) 로 IP를 기반으로 ping 을 보내면 아래와 같이 응답함을 볼 수 있다.
root@~~# docker exec -t web01 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
하지만, Container 사이의 IP 기반 연동은 문제점을 안고 있다.
Container 의 IP 는 언제든 변할 수 있는 유동적인 성격을 띄고 있기 때문이다.
Container 는 일종의 Process 이므로, 언제든 생성/소멸 될 수 있음을 전제로 해야한다.
만약 Container가 중지 되었다가 시작하면, Process가 kill 되었다가 다시 새롭게 생성되는 것과 같다.
이때, Container 에게 부여되는 Private IP는 언제든 변할 수 있다.
따라서, Container 사이 연동을 하려면, IP 기반의 설정은 권고되지 않는다.
그 해결 방법으로 권고 되고 있는 방법이 바로 link 옵션이다.
link를 이용한 container 연동
아래는 link 옵션을 이용해 mysql container 를 연동한 web02 container를 구동하는 명령이다.
root@~~# docker run -d --name web02 --link mysql httpd
14f6f2a16abc8660ba32004c8eff091e5a16f0ace57a3609d770f845485d103f
docker run 을 이용해 webe02 container를 띄울때, --link 옵션을 이용해 mysql container 와 link를 맺을 것을 설정한다. 이렇게 설정하면, web02 container 는 mysql container 를 IP 가 아닌 container의 이름을 이용해 통신할 수 있다.
root@~~# 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
...
위와 같이 ping target을 IP가 아닌 container 이름으로 통신이 가능하다. 만약 link를 맺지 않으면, 아래와 같이 container 명으로는 통신이 불가하다.
root@~~# docker exec -t web03 ping mysql
ping: unknown host
container 이름을 기반으로 통신을 하면, IP가 바뀐다고 해도 문제 없이 통신이 가능하겠다.
link 연동 구조
container 가 구동되면, container 환경 중 일부는 docker daemon에 의해 자동으로 제어 된다.
이 중 한가지가 container 내부의 domain name을 관리하는 hosts 파일이다.
link 연동이 걸린 web02 container의 hosts 파일을 살펴보자.
root@~~# 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가 바뀐다면 어떻게 될까.
root@~~# docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.6 # mysql 컨테이너의 IP가 172.17.0.6 임을 확인
root@~~# docker stop mysql #mysql 컨테이너 중지
mysql
root@~~# docker start mysql #mysql 컨테이너 기동
mysql
root@~~# docker inspect -f "{{ .NetworkSettings.IPAddress }}" mysql
172.17.0.5 # mysql 컨테이너의 IP를 확인해 보니 5로 바뀌었다.
root@ip-10-10-2-240:/home/ubuntu# 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 정보가 수시로 갱신될 수 있는 환경에서도 서로간 문제 없이 통신이 가능하겠다.
그렇다면, docker daemon은 어떻게 container의 hosts 파일을 자동으로 갱신할수 있을까.
사실, container의 hosts 파일을 살펴보면 아래와 같이 dev/disk 에 의해 mount 되어 있는 것을 볼 수 있다.
root@~~# docker exec -t web02 df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-202:1-141101-af75af9f7a44dd66180fc6c1d74bd7a14a53bfe0a2aef77cbe66d41632295dec 9.8G 236M 9.0G 3% /
tmpfs 497M 0 497M 0% /dev
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/disk/by-uuid/736fad7a-387f-4420-b934-4ccbafa26d16 7.8G 2.1G 5.3G 28% /etc/hosts
shm 64M 0 64M 0% /dev/shm
이 /dev/disk/by-uuid/UUID 는 container 안에서는 확인이 되지 않는다. container 외부의 docker host 에서 연동된 것이기 때문이다. 그렇다면 docker host의 어떤 파일이 연동 된 것일까. 이것은 docker inspect 명령을 이용해 확인이 가능하다.
root@~~# docker inspect -f "{{ .HostsPath }}" web02
/var/lib/docker/containers/14f6f2a16abc8660ba32004c8eff091e5a16f0ace57a3609d770f845485d103f/hosts
docker host 에서 실제 이 file을 열어보면 아래와 같이 container의 hosts 파일과 동일하다.
root@~~# cat /var/lib/docker/containers/14f6f2a16abc8660ba32004c8eff091e5a16f0ace57a3609d770f845485d103f/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
172.17.0.2 14f6f2a16abc
link 방식의 한계
container 사이에는 link 를 이용해 연동해야 동적 IP에 따른 이슈를 피할수 있다. 하지만 link 방식만으로는 여전히 한계가 있다.
첫째로, link 옵션은 동일 docker host 에 존재하는 container 사이에서만 유효하다. 만약 다수의 docker host를 운영할 경우에 타 host에 상주하는 container 사이에는 link 옵션 이용이 불가하다. 컨테이너의 hosts 파일의 관리를 docker host가 직접 수행하기 때문이다.
이러한 경우, docker swarm 같은 orchestration 툴을 도입하거나 dynamic DNS 를 구축해 사용해야 한다.
'IT > Docker' 카테고리의 다른 글
Dockerfile Entrypoint 와 CMD의 올바른 사용 방법 (5) | 2019.06.12 |
---|---|
Docker Network 구조(3) - container 외부 통신 구조 (15) | 2016.07.06 |
Docker Network 구조(2) - container network 방식 4가지 (1) | 2016.05.20 |
Docker container IP 확인 (4) | 2016.05.18 |
docker container에 접속하기 (2) | 2015.07.21 |