$ docker network ls
NETWORK ID NAME DRIVER SCOPE
0cc1f7646f4d bridge bridge local
9b68a5cd408f host host local
9c19ba299af1 none null local
도커는 기본적으로 위 3개의 네트워크가 제공된다
Bridge
bridge network는 하나의 호스트에서 여러개의 네트워크 공간을 형성하도록 합니다
다른 bridge에 있는 컨테이너끼리는 통신할 수 없습니다
NAME이 bridge인 네트워크는 도커가 default하게 제공하는 네트워크입니다
아무런 설정을 하지 않았을때 컨테이너는 default bridge안에 속하게 됩니다
bridge 모드로 생성된 컨테이너는 각 bridge안에서 고유한 IP를 가집니다
bridge 네트워크는 docker 내부적으로 iptables를 통하여 외부와 통신하거나 포트 포워딩을 합니다
iptables로 docker가 생성한 네트워크를 확인할수있습니다
$ sudo iptables -t nat -L -v -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 628 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
10 602 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
Alpine 리눅스를 ash(default shell)로 실행하는 4개의 컨테이너를 만들어봅시다
2개는 default bridge, 2개는 custom bridge에 생성합시다
docker network create --driver bridge custom_bridge
docker run -dit --name alpine1 alpine ash
docker run -dit --name alpine2 alpine ash
docker run -dit --name alpine3 --network alpine-net alpine ash
docker run -dit --name alpine4 --network alpine-net alpine ash
아래 명령어로 네트워크에 대한 정보를 확인할수있습니다
docker network inspect custom_bridge
[
{
"Name": "custom_bridge",
"Id": "c27e3f418c48910c75c9490bd3cb571367da686be7756cf12462823393e0cede",
"Created": "2024-07-19T21:43:43.252290125+09:00",
"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": {
"37fa6348f72201ddd76abd8e023181d5d0ed2347035965a0d5569ed8bdfb943e": {
"Name": "alpine3",
"EndpointID": "4c17a7170db11c42651d7d3186b6e7d89c4efe556604e4a56d3ff19ab31a8de3",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"92cda7a73f0c781a0d631e4e0010231644c78352c6103bc019586bdfee2db7ab": {
"Name": "alpine4",
"EndpointID": "9727d64c9576aee0c3c382356893cee20f95fd531476cf0c14b4d2343fe10080",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
custom bridge 안에는 두개의 컨테이너가 있고 각각 mac과 ip가 있습니다
다음과 같이 네트워크가 격리됩니다
- 동일 bridge 안에서 통신 : 가능
- 다른 bridge 로 통신 : 불가
- bridge에서 host로 아웃바운드 : 가능
- host로 bridge로 인바운드 : 불가
참고로 default bridge에서는 컨테이너이름으로 통신이 안되고(DNS에 의해), custom bridge에서는 컨테이너 이름으로 통신이 가능합니다
docker attach alpine4
ping -c 2 alpine3
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.121 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.107 ms
--- alpine3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
두 bridge가 격리를 해제하려면 컨테이너를 통해 두 bridge를 연결하면 됩니다
docker network connect bridge alpine4
이렇게 하면 두개의 bridge가 alpine4를 통하여 통신가능해집니다
host에서 bridge로 인바운드 하려면 포트바인딩을 하면 됩니다
docker run -d --name nginx --network my_custom_bridge -p 8080:80 nginx
호스트로 8080번 포트를 호출하면 nginx 도커의 80번 포트로 바인딩 된다
Host
컨테이너는 독립된 ip주소를 할당받지 않는다
Host와 동일한 포트와 ip주소를 사용한다
docker run --rm -d --network host --name my_nginx nginx
docker run --rm -d --network host --name my_nginx nginx
curl localhost:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
별도의 포트바인딩을 하지 않아도 된다
None
아무런 네트워크를 사용하지 않는다
인바운드, 아웃바운드 모두 불가하다
docker run -dit --name alpine5 --network none alpine ash
Macvlan
Macvlan을 사용하면 하나의 NIC(Network Interface Card)에 여러 개의 MAC 주소를 할당하여 사용할 수 있습니다.
macvlan의 default는 bridge모드이고, macvlan에 있는 모든 endpoint들은 서로 통신이 가능합니다
docker network create -d macvlan \
--subnet=192.168.35.0/24 \
--gateway=192.168.35.1 \
-o parent=enxXXXXXXX \
my-macvlan-net
네트워크 인터페이스/서브넷/게이트웨이를 확인하려면
ifconfig
ip route
두 명령어를 통해 찾을 수 있습니다
아래 명령어를 통해 macvlan에 컨테이너를 만들 수 있습니다
docker run --rm -dit \
--network my-macvlan-net \
--name my-macvlan-alpine \
alpine:latest \
ash
네트워크가 host의 물리적 네트워크와 동일하다는 것을 아래 명령어로 알수있습니다
$ docker exec my-macvlan-alpine ip addr show eth0
30: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:c0:a8:23:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.35.2/24 brd 192.168.35.255 scope global eth0
valid_lft forever preferred_lft forever
$ docker exec my-macvlan-alpine ip route
default via 192.168.35.1 dev eth0
192.168.35.0/24 dev eth0 scope link src 192.168.35.2
IPvlan
IPvlan은 Macvlan과 비슷하지만 mac주소가 동일하고 ip주소만 다릅니다
IPvlan은 l2와 l3 모드가 있습니다
l2는 parent interface가 bridge처럼 동작합니다
l3는 parent interface가 router처럼 동작합니다
l3모드로 network를 만들어보겠습니다
docker network create -d ipvlan \
--subnet=10.1.214.0/24 \
-o ipvlan_mode=l3 my-ipvlan-l3-net
docker run -dit --name alpine6 --network my-ipvlan-l3-net alpine ash
컨테이너에서 호스트IP로 ping을 하려면 통신이 안됩니다(같은 ipvlan끼리만 가능)
https://docs.docker.com/network/
Networking overview
Learn how networking works from the container's point of view
docs.docker.com
https://docs.docker.com/engine/tutorials/networkingcontainers/
Network containers
How to network Docker containers.
docs.docker.com
Introduction to Linux interfaces for virtual networking | Red Hat Developer
Get an introduction to Linux virtual interfaces, including commonly used interfaces, when to use them, and how to create them.
developers.redhat.com
'개발업무 > 개발' 카테고리의 다른 글
Java SimpleDateFormat YYYY vs yyyy (0) | 2025.01.12 |
---|---|
헬스체크 캐싱 적용 (0) | 2024.11.24 |
Apache web server request body 로깅 (0) | 2024.05.30 |
Apache Server 설치 (0) | 2024.05.29 |
Java 대용량 엑셀 다운로드 (SXSSF) (0) | 2024.04.10 |