▶︎ 들어가기 앞서
‣ veth interface
랜카드에 연결된 실제 네트워크 인터페이스가 아닌, 가상으로 생성한 네트워크 인터페이스이다.
일반적인 네트워크 인터페이스와는 달리 패킷을 전달받으면, 자신에게 연결된 다른 네트워크 인터페이스로 패킷을 보내주기 때문에 항상 쌍(pair)으로 생성해야 한다.
‣ NET namespace
리눅스 격리 기술인 namespace 중 네트워크와 관련된 부분을 말한다.
네트워크 인터페이스를 각각 다른 namespace에 할당함으로써 서로가 서로를 모르게끔 설정할 수 있다.
▶︎ 도커 네트워크
‣ 가상 네트워크
네트워크 가상화는 네트워크 기능, 하드웨어 리소스, 소프트웨어 리소스를 하드웨어와 별도의 가상 네트워크로 전달할 수 있게 해주는 것을 의미함.
도커는 가상화 기술을 통해 네트워크 리소스를 가상화 할 수 있다.
물리적으로 존재하지 않고 논리적으로만 존재하는 것이다.
이렇게 논리적으로 네트워크 환경을 구성하는 기술을 **SDN(Software Defined Network)**라고도 부른다.
‣ Bridge
도커 네트워크에서는 브릿지(Bridge)라는 가상의 도커용 네트워크 드라이버가 존재해서 각 컨테이너들에게 IP를 할당하거나 관리할 수 있다.
우선 브릿지는 기본적으로 172.17.0.1
이라는 IP 주소를 기본값으로 사용하며, 사용자가 직접 브릿지를 생성할 수 있으며 IP 대역도 지정이 가능하다.
ifconfig -a | grep -A1 'docker'
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
같은 브릿지 네트워크 망을 사용하는 컨테이너들은 브릿지를 통해서 서로 자유롭게 통신이 가능하다.
같은 네트워크를 공유하고 있으니 당연한 소리이기도 하다.
반대로 서로 다른 브릿지 네트워크 망끼리는 통신이 불가능하다.
‣ 가상 인터페이스
보통 외부 또는 내부와 통신을 하려면
랜선이라 불리는 이더넷 케이블이 컴퓨터의 랜카드의 물리 인터페이스에 연결되고,
해당 라인은 IP 주소를 L3 장비(라우터,공유기 ..)로부터 할당받게 된다.
즉, 사진처럼 192.168.0.10의 IP를 할당 받았다면 앞으로 192.168.0.10 주소로 오는 모든 데이터는 eth0
인터페이스가 전부 수신 받는 것이다.
이 과정은 가상 네트워크 환경에서도 동일하게 적용된다.
하지만 말 그대로 가상이기 때문에 랜선을 꽂고 실제 아이피를 할당해주는 모든 작업이 소프트웨어적으로 발생한다.
우선 도커를 설치하면 도커는 docker0
이라 불리는 가상 네트워크 인터페이스를 호스트 OS에 설치한다.
그리고 컨테이너가 생성될 때 마다 Veth
라 불리는 가상의 인터페이스들이 하나씩 생성되며 아이피 주소도 브릿지로부터 할당 받는다.
확인을 위해 아래와 같이 nginx
컨테이너를 도커 네트워크의 Bridge
를 연결해서 생성해주고 해당 컨테이너의 IP를 확인해보자.
$ docker run -d -it --name nginx --network=bridge nginx:latest
$ docker container inspect nginx | jq '.[].NetworkSettings.Networks.bridge.Gateway
"172.17.0.1"
Bridge로부터 아이피를 할당받은 것을 확인할 수 있었다.
‣ 도커 DNS
도커는 컨테이너들이 기본적으로 사용할 수 있는 DNS 서버를 제공한다.
이 DNS 서버에는 IP 주소와 도메인명이 저장되어 있다.
여기서 도메인은 컨테이너의 이름으로 자동 저장된다.
그래서 컨테이너들은 기본적으로 컨테이너의 IP가 아닌 컨테이너의 이름으로 통신할 수 있는 것이다.
위 사진의 구성처럼
second-bridge
네트워크를 생성하고 컨테이너 A와 컨테이너 B를 생성한 상태라고 가정할 때,
A에서는 요청을 보낼 때 도메인 명을 컨테이너 B로 지정하면
먼저 도커 DNS를 통해서 컨테이너 B의 IP 주소인 10.0.0.3이라는 IP를 받아온다.
그리고 이 IP로 요청을 보내는 것이다.
컨테이너 B가 재시작 되어서 IP가 10.0.0.4로 변경되더라도 도메인 서버에 즉시 업데이트가 되기 때문에
컨테이너 A는 컨테이너 B라는 도메인만 사용하면 요청을 정상적으로 보낼 수 있게된다.
간단한 테스트를 위해 testNet
이라는 도커 네트워크를 생성하고
nginx1
, nginx2
라는 이름을 가진 두 개의 컨테이너를 생성해보도록 하자.
# 도커 네트워크 생성
$ docker network create --driver=bridge --subnet=10.0.0.0/24 testNet
# 도커 컨테이너 생성
$ docker run -d -it --name nginx1 -p 80:80 --network=testNet devwikirepo/pingbuntu
$ docker run -d -it --name nginx2 -p 81:80 --network=testNet devwikirepo/pingbuntu
nginx1
컨테이너에 접속하여 nginx2
컨테이너 이름으로 ping 테스트를 해보도록 하자.
$ docker exec -it nginx1 ping -c 2 nginx2
컨테이너 이름으로도 통신이 가능한 것을 확인하였다.
🔴 Bridge Network
기본으로 생성되는 Bridge 네트워크는 이 DNS 기능이 제공되지 않는다.
사용자가 직접 생성한 브릿지 네트워크만 컨테이너의 이름을 통해서 통신이 가능하다.
‣ 도커 네트워크 구조
도커는 위에서 언급한 veth interface와 NET namespace를 사용해 네트워크를 구성한다.
참고로 mac이나 window는 veth interface가 VM 안에 감춰져 있기 때문에 확인이 어렵다.
도커를 생성하면 3가지 형태의 network가 생김을 확인할 수 있다.
$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
6b6ce553a425 bridge bridge local
81a18bc9cc40 host host local
576b0223f9cf none null local
bridge 네트워크를 확인해보면 172.17.0.0/16 대역을 할당했음을 아래 명령어를 실행하여 확인해볼 수 있다.
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "6b6ce553a425c9392c5a65b8dcd2a57e1665289354b97f430758b745b1dc86a7",
...
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
...
}
...
]
그리고 172.17.0.0/16 대역은 docker0로 매핑되어 있다.
$ ip route | grep 'docker'
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
docker0
는 veth interface와 매핑된 브릿지임을 확인할 수 있다.
# bridge-utils 패키지가 미설치된 경우 아래 명령어 실행하여 설치
$ sudo apt-get install -y bridge-utils
$ brctl show docker0
bridge name bridge id STP enabled interfaces
docker0 8000.02423df329a4 no
$ ip link ls | egrep "docker|veth"
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
18: veth6ccab66@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-39fed30460d7 state UP mode DEFAULT group default
20: veth1d21aac@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-39fed30460d7 state UP mode DEFAULT group default
22: veth62032a7@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
- 컨테이너는 namespace로 격리되고, 통신을 위한 네트워크 인터페이스(eth0)를 할당 받는다.
- host의 veth interface가 생성되고 컨테이너 내의 eth0과 연결된다.
- host의 veth interface는 docker0 이라는 다른 veth interface와 연결된다.
도커 컴포즈로 컨테이너를 띄우는 경우에는 네트워크가 어떻게 구성될까?
테스트를 위해 아래 깃허브 프로젝트를 clone 받아온 후, Docker Compose를 실행 시켜보자.
git clone https://github.com/woowacourse/service-practice.git
cd service-practice && cd lb
docker build -t node-server .
docker-compose -p practice up -d
생성된 lb-lb-1
컨테이너의 디폴트 게이트웨이를 확인해보자.
$ docker container inspect lb-lb-1 | jq '.[].NetworkSettings.Networks.lb_default.Gateway'
"172.18.0.1"
$ ip route
172.18.0.0/16 dev br-754310d33f5c proto kernel scope link src 172.18.0.1
$ ip link ls
4: br-754310d33f5c: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:cd:76:d1:f1 brd ff:ff:ff:ff:ff:ff
docker-compose로 띄우면 다른 네트워크 대역을 가진다. docker-compose로 컨테이너를 띄우면 compose로 묶은 범위에 맞춰 브릿지를 하나 더 생성하기 때문이다. 따라서 서로 경유하는 브릿지가 다르므로 docker-compose로 띄운 컨테이너와 일반 컨테이너간의 통신은 불가능하다.
그러나 위와 같은 상황에서도 방법은 하나 있다.
먼저 docker network create
로 'external' 이라는 도커 네트워크를 생성해보자.
$ docker network create external
그리고 docker-compose에 아래 내용을 추가해주자.
version: "3.3"
services:
image: nginx
networks:
- "external-net"
...
networks:
- external-net:
name: external
external: true
docker network create
로 생성된 'external' 이라는 외부 도커 네트워크를 사용하겠다고 docker-compose에 networks
옵션을 사용하여 명시해주면 된다.
그리고 통신하고자 하는 다른 일반 컨테이너도 'external' 이라는 도커 네트워크로 묶어주면 docker-compose로 생성된 컨테이너와 일반 컨테이너 간 통신이 가능해지기는 한다.
# 포트포워딩 설정과 함께 컨테이너를 생성합니다.
$ docker container run -d -p 8081:80 nginx
16cd67c48e5721a6b666192b8960875c720168bf6c5e3ed2138fb04c492447c6
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16cd67c48e57 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:8081->80/tcp trusting_bhabha
# Host의 8081포트가 listen 임을 확인합니다.
$ sudo netstat -nlp | grep 8081
tcp6 0 0 :::8081 :::* LISTEN 10009/docker-proxy
# docker-proxy 라는 프로세스가 해당 포트를 listen 하고 있음을 볼 수 있습니다.
# docker-proxy는 들어온 요청을 해당하는 컨테이너로 넘기는 역할만을 수행하는 프로세스입니다.
# 컨테이너에 포트포워딩이나 expose를 설정했을 경우 같이 생성됩니다.
$ iptables -t nat -L -n
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8081 to:172.17.0.2:80
# 보시다시피 모든 요청을 DOCKER Chain 으로 넘기고, DOCKER Chain 에서는 DNAT를 통해 포트포워딩을 해주고 있음을 볼 수 있습니다.
# 이 iptables 룰은 docker daemon이 자동으로 설정합니다.
기본적으로 컨테이너는 외부와 통신이 불가능하다.
그러나 포트포워딩을 설정하여 외부에 컨테이너를 공개할 수 있다.
docker container의 네트워크 모드는 bridge
, host
, container
, none
등 총 4개가 존재한다.
▶︎ 도커 네트워크 실습
Info. 네트워크 조회
docker network ls
커맨드를 사용하여 현재 생성되어 있는 Docker 네트워크 목록을 조회할 수 있다.
docker network ls
NETWORK ID NAME DRIVER SCOPE
01148fff8c35 bridge bridge local
0a5d707b4146 host host local
c3356923ba47 none null local
bridge
, host
, none
은 docker 데몬이 실행되면서 디폴트로 생성되는 네트워크이다.
A. 네트워크 종류
Docker 네트워크는 bridge
, host
, overlay
등 목적에 따라 다양한 종류의 네트워크 드라이버를 지원한다.
브릿지(bridge)
네트워크: 도커 브릿지를 활용해 컨테이너간 통신, NAT 및 포트포워딩 기술을 활용해 외부 통신 지원호스트(host)
네트워크: 호스트의 네트워크를 공유- 모든 컨테이너는 호스트 머신과 동일한 IP를 사용
- 포트 중복 불가능
오버레이(overlay)
네트워크: Kubernetes에서 사용- 호스트 머신이 다수일 때 네트워크 관리 기술
Macvlan
네트워크: 컨테이너에 MAC 주소를 할당하여 물리 네트워크 인터페이스에 직접 연결
B. 네트워크 생성
docker network create
커맨드를 사용하여 새로운 Docker network를 생성해보자
$ docker network create --driver=bridge my-net
1e5ad60b467c3dd5e0ff9582bd2be6af0fb0cea2cd78fac45396349093811a77
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
01148fff8c35 bridge bridge local
0a5d707b4146 host host local
1e5ad60b467c my-net bridge local
c3356923ba47 none null local
도커 네트워크에 특정 서브넷 대역을 지정하고 싶다면 아래와 같이 실행하면 된다.
$ docker network create --driver=bridge --subnet 10.0.0.0/24 --gateway 10.0.0.1 my-net
C. 네트워크 상세 정보
방금 추가한 네트워크의 상세 정보를 docker network inspect
커맨드로 확인이 가능하다
$ docker network inspect my-net
[
{
"Name": "my-net",
"Id": "1e5ad60b467c3dd5e0ff9582bd2be6af0fb0cea2cd78fac45396349093811a77",
"Created": "2023-04-19T04:25:32.234055588Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
D. 네트워크 연결
컨테이너 하나를 test
라는 이름으로 실행해보자
$ docker run -d -it --name test busybox
컨테이너를 실행할 때 --network
옵션을 명시해주지 않으면 디폴트로 bridge
라는 이름의 디폴트 네트워크에 붙게된다.
$ docker network inspect bridge
(...생략...)
"Containers": {
"e45d2943d90f3f4bf0495c161555f610005f5daef8cd27925ff58818f9371849": {
"Name": "test",
"EndpointID": "d31d5236b1093f967a3ab1eab2f9ea3ad8ea184f48f1a1619c5bddb9fcbb653b",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
(...생략...)
이 test
컨테이너를 위에서 생성한 my-net
네트워크에 연결해보자.
$ docker network connect my-net test
my-net
네트워크의 상세정보를 다시 확인해보면 Containers
항목에 test
컨테이너가 추가된 것을 볼 수 있다.
$ docker network inspect my-net
[
{
"Name": "my-net",
"Id": "1e5ad60b467c3dd5e0ff9582bd2be6af0fb0cea2cd78fac45396349093811a77",
"Created": "2023-04-19T04:25:32.234055588Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"e45d2943d90f3f4bf0495c161555f610005f5daef8cd27925ff58818f9371849": {
"Name": "test",
"EndpointID": "a4763c61db9d595ffcbc6d68314c100d6fff57c724b07f187042853885ed6295",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
그리고 test
컨테이너에 IPv4
도 할당이 되었는데 주소는 172.187.0.2/16
이다.
E. 네트워크 연결 해제
하나의 컨테이너는 여러 개의 네트워크에 동시에 연결이 가능하다.
최초에 test
컨테이너를 생성할 때 붙은 bridge
네트워크를 떼어내버리자
컨테이너 연결을 끊을 때는 docker network disconnect
커맨드를 사용한다
$ docker network disconnect bridge test
F. 두번째 컨테이너 연결
네트워크에 홀로 있는 컨테이너는 큰 의미가 없을 것이다.하나의 컨테이너를 더 my-net
네트워크에 연결해보도록 하자
이번에는 --network
옵션을 사용하여 컨테이너를 실행하면서 바로 연결할 네트워크를 지정해보도록 하자
$ docker run -d -it --name test2 --network my-net busybox
my-net
네트워크의 상세 정보를 확인해보면 test2
컨테이너에 IP 172.19.0.2
가 할당되어 연결되어 있는 것을 확인할 수 있다!
$ docker network inspect my-net
[
{
"Name": "my-net",
"Id": "986bf74da652868feac39e426f44f6c6c2016d33b047565652c8d84d8bd8c35d",
"Created": "2023-04-24T12:01:37.037581923Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"331010f87747ecc5c003cf564ad66342dda4e18feb632e8e588862e7be334a30": {
"Name": "test2",
"EndpointID": "b34e47acfa97312f15b0568634ba6a017552b385f03dbe84f27c020e534f49c1",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
},
"9377c7ab50b615732233a71d5eb22d04532c0c35b5eb4ff04e4b457d74ffc52f": {
"Name": "test1",
"EndpointID": "104d516b2a1ef915937ef4c4edb27a8eef8af6acf408e75338b608a29010e55e",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
G. 컨테이너 간 네트워킹
이제 두 개의 컨테이너가 네트워크를 통해 서로 소통이 가능한지 테스트를 진행해보자.
먼저 test1
컨테이너에서 test2
컨테이너를 상대로 ping
명령어를 날려보자
컨테이너 이름을 호스트네임(hostname)처럼 사용할 수도 있다!
$ docker exec test1 ping test2
PING test2 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.249 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.197 ms
64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.209 ms
64 bytes from 172.19.0.2: seq=3 ttl=64 time=0.320 ms
64 bytes from 172.19.0.2: seq=4 ttl=64 time=0.364 ms
반대로 test2
컨테이너에서 test1
컨테이너를 상대로 ping
명령어를 날려보자. 이번에는 컨테이너 이름 대신 IP를 사용해보자
$ docker exec test2 ping 172.19.0.3
PING 172.19.0.3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.169 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.351 ms
64 bytes from 172.19.0.3: seq=2 ttl=64 time=0.257 ms
64 bytes from 172.19.0.3: seq=3 ttl=64 time=0.367 ms
64 bytes from 172.19.0.3: seq=4 ttl=64 time=0.413 ms
H. 네트워크 제거
마지막으로 docker network rm
커맨드를 사용하여 my-net
네트워크를 삭제해보자.
$ docker network rm my-net
Error response from daemon: error while removing network: network my-net id 1e5ad60b467c3dd5e0ff9582bd2be6af0fb0cea2cd78fac45396349093811a77 has active endpoints
위와 같이 제거하려는 네트워크 상에서 실행 중인 컨테이너가 존재할 시 제거 되지 않는다.
해당 네트워크에 연결되어 실행 중인 모든 컨테이너를 먼저 중지시키고 네트워크를 삭제하면 된다.
$ docker kill $(docker ps -q)
$ docker network rm my-net
I. 네트워크 청소
하나의 호스트 컴퓨터에서 다수의 컨테이너를 돌리다 보면 아무 컨테이너도 연결되어 있지 않은 네트워크가 생기기 마련이다.
이럴 때는 docker network prune
커맨드를 사용하여 불필요한 네트워크를 한 번에 정리하도록 하자
$ yes | docker network prune # 'y' 를 docker network prune 커맨드의 입력으로 넘김
J. 디폴트 네트워크 연결하기
디폴트 네트워크(bridge,host,none
)을 Docker Compose에서 연결하려면 어떡해야 할까?
version: "3"
services:
test:
image: test/test
network_mode: <디폹트네트워크명>
위 처럼 network_mode 옵션을 사용한다 값으로는 디폴트네트워크 이름을 넣어주면 된다
version: "3"
services:
test:
image: test/test
network_mode: bridge
위 컨테이너는 bridge 네트워크에 연결된다
▶︎ 도커 네트워크 연습
‣ 예제 (1)
swapi-net
이라는 도커 네트워크를 생성하고 swapi 컨테이너와 mongodb 컨테이너를swapi-net
도커 네트워크에 소속 시키자swapi
라는 컨테이너 이름으로 node.js 기반 컨테이너를 하나 생성하고 mongodb 컨테이너도 생성하도록 하자.
도커 네트워크 생성하기
$ docker network create swapi-net
컨테이너 배포 및 도커 네트워크 연결
# node.js 프로젝트 배포
$ docker run -d -it --name swapi -p 80:3000 --network swapi-net yshrim12/favorite-api:latest
# mongodb 배포
$ docker run -d -it --name mongodb --network swapit-net mongo:latest
swapi-net 네트워크에 연결된 컨테이너 조회하기
$ docker network inspect swapi-net
...(생략)...
"Containers": {
"b048620cabaf2a212422d8e7a05800a578c9c1ba38a510c8e5ce22066c065e5c": {
"Name": "mongodb",
"EndpointID": "9824df174db1af19280199b413dcb5e890332601fa6f7322c89caa95d2dc8d43",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"b6c19e63fb96e966605f9a9340da4fd547cb0933ebc73533be64ee0a2bfaa3bb": {
"Name": "swapi",
"EndpointID": "c14ffc1f0f7ca8f7e3fa1a95835889fabdbb83944c0b2386086c5fbe11ec7b5b",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
...(생략)...
다른 컨테이너의 이름을 사용하기 위하여 두 컨테이너를 동일한 네트워크에 소속시켜야 한다!
swapi 컨테이너의 로그를 확인해보자
$ docker logs swapi
(node:1) [MONGODB DRIVER] Warning: Current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
(Use `node --trace-warnings ...` to show where the warning was created)
정상적으로 동작하는 로그이다.
🚦 Why ?
mongodb 컨테이너를 배포할 때 포트를 게시하지 않은 이유는 무엇일까?
현재 내가 노출할 서비스는 node.js
프로젝트 하나이다.
즉 swapi
컨테이너만 외부로 노출하면 되고 데이터베이스의 경우 외부로 노출할 필요가 없기 때문이다.
swapi
컨테이너가 내부적으로 mongodb
컨테이너와 통신을하고 데이터를 받아오고 받아온 데이터를 외부에 뿌려주는 형식이라고 보면될 것 같다.
생각해보면 데이터베이스 하나만 배포하는 경우는 거의 없고 서비스와 DB를 같이 연동하여 배포하기 때문에 보안적으로도 DB를 외부에 노출시키는 것은 바람직하지 않을 것 같다
‣ 예제 (2)
- 커스텀 도커 네트워크 생성
- nginx를 새로 생성한 커스텀 도커 네트워크에 연결
--net-alias=web
: bridge 네트워크에서만 사용할 수 있는 옵션이다- bridge 네트워크 안에서
web
라는 도메인 이름으로 컨테이너 IP를 서치할 수 있도록 내부 도메인에 저장을 해줌
- bridge 네트워크 안에서
도커 네트워크 생성
# 도커 네트워크 driver를 bridge로 지정
$ docker network create --driver=bridge devops
nginx 컨테이너 생성 및 네트워크 연결
$ docker run -d -it --name nginx \
--rm \
--net-alias=web \
nginx:latest
grafana 컨테이너 생성 및 네트워크 연결
$ docker run -d -it --name grafana \
--rm \
--net-alias=hello \
grafana/grafana
grafana 컨테이너로 접속해 wget
커맨드로 --net-alias
로 명령어로 지정해둔 web 도메인으로 접근 테스트하기
$ docker exec -it grafana wget web
$ wget web