해당 글은 도커 컨테이너 생성 및 수정에 대한 자세한 설명은 없습니다.
1. 도커 컨테이너 네트워크 구조
1. 두개의 컨테이너 생성
docker run -it --name client ubuntu:14.04
docker run -it --name server ubuntu:14.04
두 개의 터미널을 열어 각각 컨테이너를 실행한 후에 ifconfig 명령어를 입력해보면 다음과 같이 eth0 와 lo라는 네트워크 인터페이스가 존재한다.
eth0는 실제로 Ethernet과 같이 IP가 할당되어서 외부와 통신할 수 있는 네트워크이고, lo는 로컬 네트워크이다.
root@42588a0aca5a:/ ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:04
inet addr:172.17.0.4 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1426 errors:0 dropped:0 overruns:0 frame:0
TX packets:981 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1972421 (1.9 MB) TX bytes:67537 (67.5 KB)
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:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
etho는 utun 혹은 veth라는 호스트 네트워크 인터페이스와 연결되어 호스트 외내부를 통해 네트워킹을 하게 된다.
그리고 이러한 각각의 네트워크들을 bridge0 혹은 docker0이 중앙에서 라우팅 하게 된다. 이를 도식화하면 다음과 같다.
2. 도커 컨테이너 네트워크 예제
1. 컨테이너 간 통신하기
컨테이너 간에는 같은 private 네트워크를 사용하기 때문에, 별다른 설정없이 통신이 가능하다. 각각의 컨테이너에 다음 명령어를 통해 어플리케이션을 설치하자.
클라이언트
apt-get update
apt-get install -y curl
서버
apt-get update
apt-get install -y apache2
service apache2 start
이후에 클라이언트 컨테이너에서 서버 컨테이너로 요청하면 데이터를 응답받을 수 있다.
# curl 서버 컨테이너 eth0 ip 주소
curl 172.17.0.3
3. 컨테이너 외부에서 통신하기
도커 컨테이너 네트워크는 호스트가 생성했지만, 호스트가 접근할 수 없다. 더 정확히는 어디로 접근해야 할 지 알려줘야한다.
도커 외부 즉 호스트의 포트와 연결하려면 docker0브릿지가 도커 내부의 네트워크로 호스트의 etho0의 포트와 바인딩 해주어야 한다.
호스트의 80번 포트와 바인딩하는 컨테이너를 생성하자
# -p [호스트의포트]:[컨테이터포트]
docker run -it --name external_server -p 80:80 ubuntu:14.04
#생성 후 아파치 서버 설치
apt-get update
apt-get install -y apache2
service apache2 start
이후에 호스트에 localhost에 접속하면 아파치 서버가 실행되는것을 확인할 수 있다.
호스트 포트를 생략한다면 ( -p [컨테이너포트] ) 임의의 호스트 포트를 등록한다. 등록된 포스트는 docker ps나 inspect로 확인 가능하다.
4. 실제 어플리케이션 컨테이너에 적용하기
하나의 웹서버와 데이터베이스를 연결해보자
데이터베이스
docker run -d \
--name my_db_container \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=my_db \
mysql:5.7
wordpress 웹서버
docker run -d \
--name my_server_container \
-e WORDPRESS_DB_PASSWORD=password \
--link my_db_container:mysql \
-p 80 \
wordpress
각각의 이미지에 필요한 옵션들은 해당 페이지를 참조하자.
여기서 알아볼 것은 --link 옵션이다.
일반적으로 컨테이너끼리는 같은 내부망에 있기 때문에 통신이 가능하다. 다만 매번 동적으로 IP가 바뀌기 때문에, 연결을 매번 수정 해야 할 수도 있다. 그렇기 때문에 link옵션을 사용하여, 컨테이너를 ip주소가 아닌 별칭으로 연결해서 사용할 수 있다.
--link [컨테이너명:별칭]
과 같은 포맷인데 위의 예시에서 별칭으로 mysql을 쓴 이유는 wordpress내부에서 mysql이라는 별칭을 가지고 디비에 연결하려고 하기 때문이다.
3. 도커 컨테이너 네트워크 기능
일반적으로 토커 컨테이너는 docker0 브릿지를 통해 통신을 주고 받지만, 추가 명령어를 통해서 호스트는 여러가지 서브네트워크를 생성하여 독립된 네트워크 공간을 구성 할 수 있다.
해당 명령어를 통해 사용할 수 있는 네트워크를 확인할 수 있다.
docker network ls
## 결과
NETWORK ID NAME DRIVER SCOPE
4aceeb3df0ad bridge bridge local
05551c4b29bd host host local
4869b057c6bd none null local
1. 브리지 네트워크
일단 생성해보자
# 브리지 생성
docker network create --driver bridge my_bridge
# 생성된 네트워크 확인
docker network inspect my_bridge
## 결과
...
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
...
}
서브넷이이 172.17.0.0/16과 겹치지 않는 다음 주소인 172.18.0.0/16으로 배정되어 진 것을 확인할 수 있다.
docker run -it --name new_bridge_container --net my_bridge ubuntu:14.04
## 생성 후 ifconfig
root@3d8d7edf028c:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
172.18 서브넷에 172.18.0.2 IP를 할당받았다. 이 컨테이너는 docker0브릿지(172.17) 네트워크와 독립되어 있어서, 서로 간의 통신은 불가능하다.
브릿지 생성시에 추가적인 옵션으로 서브넷과 ip범위등을 임의설정할 수 있다.
docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network
2. 호스트 네트워크
호스트 네트워크는 새로 생성 할 필요 없다. 호스트 네트워크를 사용하면 호스트와 같은 네트워크망을 공유하게 된다. 이 때문에 별도의 포트포워딩(바인딩) 없이 컨테이너의 포트에 바로 접근하는 것도 가능하다.
# https://hub.docker.com/_/httpd
docker run -it --name network_host --net host httpd
하지만 추천하는 방법은 아닌데, 기존 네트워크 설정과 충돌하는 문제 때문에 추가적인 서버 설정이 필요한 경우가 많아, 오히려 관리 포인트가 많아지기 때문이다.
3. 논 네트워크
논 네트워크는 ethernet을 사용하지 않는다. 오로지 local 네트워크만 있기 때문에, 다른 컨테이너 및 호스트와 통신이 불가능하다.
docker run -it --name my_none --net none ubuntu:14.04
# 확인 eth0은 없다.
root@ad4944d63345:/# ifconfig
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:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
4. 컨테이너 네트워크
컨테이너 생성시에 lo와 eth 를 각각 생성한다. 이 때, 컨테이너 네트워크를 사용하면 별개의 네트워크를 생성하지 않고 기존의 컨테이너의 네트워크와 공유한다.
# 터미널 1
docker run -it --name my_container_1 ubuntu:14.04
# 터미널 2
docker run -it --name container_2 --net container:my_container_1 ubuntu:14.04
두 네트워크에서 ifconfig를 실행해보면 같은 아이피와 MAC Adress를 공유하고 있음을 확인 할 수 있다.
'Develop' 카테고리의 다른 글
SVG (0) | 2021.02.01 |
---|---|
Docker 컨테이너 생성, 실행 및 삭제 (0) | 2021.01.31 |
AWS VPC 및 간단한 IPv4 (0) | 2021.01.30 |
AWS Lambda 기본 기능 파악하기 (1) (0) | 2021.01.27 |
API Gateway를 사용하여 API 구축하기 (3) REST API 생성 (0) | 2021.01.26 |