본문 바로가기

카테고리 없음

docker network

docker network는 docker 컨테이너간 그리고 컨테이너 외부와의 통신 기능을 제공하는데 쓰입니다.

 

docker daemon을 실행하면 3개의 기본 network와 virtual network interface인 docker0가 생성됩니다. 

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
1edf6f027a5a   bridge    bridge    local
3807b42fe5f2   host      host      local
e19d633c09eb   none      null      local

$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::ac5f:2bff:fe78:a8a4  prefixlen 64  scopeid 0x20<link>
        ether ae:5f:2b:78:a8:a4  txqueuelen 0  (Ethernet)
        RX packets 12  bytes 448 (448.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5  bytes 526 (526.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
(이하 생략)

 

컨테이너를 생성할 때 별다른 network 설정을 하지 않으면 이 중 bridge에 붙고,

기본적으로 생성된 bridge인 docker0의 subnet 172.17.0.0/16 에서 ip를 자동 할당받습니다.

 

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "1edf6f027a5a9191f0c22d5f65bf7943486bd7eea9bbf8f46cf79831ec85eea8",
        "Created": "2025-04-17T02:28:05.326458041+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "160ca3dd1194017f88b679f8c158d07c25dc2a9db83cdbede7fbbf56ba2c3f75": {
                "Name": "apple",
                "EndpointID": "f4e94fd26a44962d82a87e74ef9f6046d614e8d2076eb79953a690260307bd50",
                "MacAddress": "46:81:c1:ae:92:a2",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "f51c256e802528167da4f35275306333e5d7c801e6ef85b52c195b1a444f2c58": {
                "Name": "banana",
                "EndpointID": "7417a8619561da2203d8a31903d5982d941abe5f22b5f0a3410ebb750fcf91cb",
                "MacAddress": "6a:90:48:e1:e7:af",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

 

위 예시에서 컨테이너 apple은 172.17.0.2, banana는 172.17.0.3를 할당받았습니다.

 

컨테이너간 통신 테스트차 apple에서 banana로 ping을 날리면

apple 그리고 패킷 로그

위 이미지 하부 패킷 로그에서

두번째 줄 Reply 172.17.0.3 is-at 뒤에 있는 주소는 banana에 할당된 ethernet 카드의 하드웨어 주소(MAC address)입니다.

여섯번째 줄에 있는 건 위 이미지 상부 eth0 interface 정보에서 확인할 수 있듯이 apple의 주소입니다.

banana

 

따라서 docker0에 속한 컨테이너간 통신이 아래와 같은 경로로 docker0을 거쳐 진행된 걸 확인할 수 있습니다.

apple의 eth0 -> docker0 -> banana의 eth0 -> docker0 -> apple의 eth0

 

여기서 컨테이너의 eth0와 docker0를 맺어주는 건 컨테이너 실행시 자동으로 생성되는 virtual ethernet interface입니다.

veth로 시작하는 이름의 interface가 컨테이너 생성시마다 만들어지고, docker0에 바인딩 됩니다.

 

veth의 정보는 아래와 같이 생겨서 연결된 컨테이너를 바로 알긴 어렵습니다.

 

그럼 각 veth가 어떤 컨테이너와 연결되어있는지를 어떻게 찾느냐,

이건 이래저래 다른 길로 새다가 날이 새버려서 다음에 하겠습니다.

 

 

참고자료

https://yoo11052.tistory.com/208

https://bluese05.tistory.com/15

https://jangseongwoo.github.io/docker/docker_container_network/

 

veth 찾기 시작

https://superuser.com/a/1315378

https://www.baeldung.com/linux/docker-network-namespace-invisible

https://stackoverflow.com/questions/21724225/docker-how-to-get-veth-bridge-interface-pair-easily

대충 동일 네트워크 장치 쓰는 걸 컨테이너와 호스트 각기 찾는가보다 했는데 ip netns list가 안 나옴

같은 길을 걸어간 사람을 찾았다 다음에 봐야겠음

https://doitnow-man.tistory.com/entry/CKA-25-Docker-Network

 

 

샛길

 

IDC에 컨테이너 띄워둔 회사 서비스 레거시 환경을 보니까 docker network를 분리해두었길래 목적 유추

network 분리 목적 예시 : db랑 app을 하나의 private network로 묶고 app이 외부통신하는 건 다른 network에 넣기 -> db 보호

https://forums.docker.com/t/ping-container-in-different-network-on-the-same-docker-host-using-docker-user/132078/4

 

근데 한 컨테이너가 여러 network에 속할 수도 있고

https://docs.docker.com/engine/network/#connecting-to-multiple-networks

https://collabnix.com/connecting-containers-to-multiple-networks-in-docker-a-complete-guide/

 

이미 존재하는 컨테이너를 network flag 값으로 주는 방식도 있음

https://docs.docker.com/engine/network/#container-networks