개발업무/개발

docker network

NickTop 2024. 7. 21. 17:48

 

$ 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 구조

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구조

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

 

https://developers.redhat.com/blog/2018/10/22/introduction-to-linux-interfaces-for-virtual-networking#macvlan

 

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