본문 바로가기
기타

Docker network mode

by 초특급하품 2020. 5. 7.

docker container는 격리된 환경에서 실행되지만 각자의 network가 있다. docker network는 다른 container와의 연결, host와의 연결, 더 나아가 다른 host의 container의 연결까지 관리한다.

$ docker network ls
NETWORK ID          NAME                         DRIVER              SCOPE
249b79cb7a4e        bridge                       bridge              local
b53c426584d6        host                         host                local
667cc038310f        none                         null                local

 

docker network는 기본으로 bridge, host, null 등 3가지 종류가 자동으로 생성된다.

 

 

Bridge

container를 생성할 때 기본 네트워크 옵션이다. 자동으로 생성된 default bridge의 이름은 docker0이다. 

 

container는 생성되면 172.17.0.0/16 대역의 internal ip를 할당받는다. docker0을 네트워크 모드로 container를 여러 개 생성하면 위 그림과 같이 docker0 interface를 공유하게 된다. 이렇게 생성한 container들은 서로 통신할 수 있다.

$ docker run -itd --name=container1 alpine
$ docker run -itd --name=container2 alpine
$ docker network inspect 249b79cb7a4e
...
"Name": "bridge",
"Driver": "bridge",
"Containers": {
  "824ba0f8c91bb47011afb84566ec1070a7912d1b8a6d89a4c6e35d1d8a038b9c": {
    "Name": "container2",
    "EndpointID": "56d77d462f9d336861178d232f41435266324bb2fc8b3c92bc74087faf286dd1",
    "MacAddress": "02:42:ac:11:00:03",
    "IPv4Address": "172.17.0.3/16",
    "IPv6Address": ""
  },
  "fa3ac2fe2acde26dde1cef552550141531053a99668dbb7788f3167b823b1409": {
    "Name": "container1",
    "EndpointID": "cf78cb4291d5fb72128c3e4e9eb30b1948dd5ab316ee4808f947ac838b7f272b",
    "MacAddress": "02:42:ac:11:00:02",
    "IPv4Address": "172.17.0.2/16",
    "IPv6Address": ""
  }
},
...

 

container1에서 container2로 ping을 날려도 잘 응답한다.

$ docker attach container1
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=2.344 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.193 ms

 

이렇게 같은 bridge를 공유하는 container는 서로의 internal ip로 통신할 수 있지만 ip는 재기동할 때마다 달라질 수 있다. docker에서는 container 이름으로 dns를 사용하는 방법이 있다. default bridge network에서는 불가능하지만 새로 생성한 custom bridge에서는 가능하다. custom bridge에서는 built-in DNS server를 통해 container 이름을 resolve 할 수 있다.

 

$ docker network create --driver=bridge custombridge
$ docker network ls -f NAME=custombridge
NETWORK ID          NAME                         DRIVER              SCOPE
33ac4e09ef24        custombridge                 bridge              local

$ docker run -itd --name=container1 --network=custombridge alpine
$ docker run -itd --name=container2 --network=custombridge alpine
$ docker network inspect 33ac4e09ef24
...
"Name": "custombridge",
"Driver": "bridge",
"Containers": {
  "16d807d53f2286de933b0dfa18208205ea01fa7e03a5779cc19dfec0c651ba6e": {
    "Name": "container2",
    "EndpointID": "e35e3aa94c55abda979440633a0f13bf1eabfe055090e0eaf2b9b8a7baf0ede3",
    "MacAddress": "02:42:ac:13:00:02",
    "IPv4Address": "172.19.0.2/16",
    "IPv6Address": ""
  },
  "b65804042fea3401a4616f5d768e56bd8e177d68809e55ffc42d34e6ce112f1e": {
    "Name": "container1",
    "EndpointID": "132938cfd5504762876f881e882d52bd57f8d80a93fb1fd9137a5c1ecfb7b6b0",
    "MacAddress": "02:42:ac:13:00:03",
    "IPv4Address": "172.19.0.3/16",
    "IPv6Address": ""
  }
},
...

 

직접 생성한 custombridge 네트워크 모드로 두 container를 생성했다. 여기서는 dns를 사용해서 container 이름으로 통신도 가능하다.

$ docker attach container1
/ # ping 172.19.0.2
PING 172.19.0.2 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.179 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.187 ms
64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.189 ms

---

/ # ping container2
PING container2 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.149 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.182 ms
64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.188 ms

 

bridge 모드인 container의 내부 요청은 이처럼 처리된다.

 

외부 요청은 host의 eth0으로 통신하기 때문에 source address는 host IP가 된다. 마찬가지로 외부에서 container로 요청을 하려면 host IP에 mapping 등록된 port까지 명시해야 한다.

 

 

overlay

하나의 host가 아닌 여러 host에 docker container를 배포를 했다면 다른 host에 있는 container와 통신을 하기 위해 host:port 정보를 알아야 한다.

overlay는 multi host 환경에서 container를 internal network를 만들어서 연결해준다. overlay network를 생성한 후 container를 attach 하면 된다. docker swam 환경에서는 간단한 서비스 생성으로 이 작업을 전부 대신해준다.

$ docker service create --name webApplication --replicas 3 nginx

 

swam은 위 명령을 통해 ingress network가 overlay로 연결된다. 요청받은 호스트에 해당 container가 없어도 ingress network의 load balancer가 다른 호스트로 보내준다.

 

aws ecs에서는 application load balancer가 이와 비슷한 역할을 한다.

 

 

host

다른 docker container와 분리된다. host network를 사용하기 때문에 -p 옵션으로 host와 container port를 매핑하지 않아도 같은 port로 host에 매핑된다. 따라서 같은 web application container 여러 개를 하나의 host에서 실행할 수 없다.

 

 

null

어떤 network도 attach 되지 않은 상태이다. 외부 요청과 container 사이의 요청도 모두 불가능하다.

'기타' 카테고리의 다른 글

vim plugin 설치 방법  (0) 2021.03.21
[bash] file descriptor redirection 문법  (0) 2020.10.14
Swagger openapi 사용법  (0) 2020.04.02
CSS flex 기본  (0) 2020.03.12
분산 트랜잭션 - 2단계 커밋(two-phase commit)  (0) 2020.02.20

댓글