-
[Docker] Docker Network 와 Bridge Type Network Interface 알아보기 ( ip link )Docker 2024. 6. 21. 07:18반응형
- 목차
들어가며.
이번 글에서는 Docker Network 와 Linux 의 Bridge Type 의 Network Interface 에 대해서 알아보도록 하겠습니다.
흔히 사용되는 "docker network create XX" 와 같은 도커 명령어는 Bridge Type 의 Docker Network 를 생성합니다.
docker network ls NETWORK ID NAME DRIVER SCOPE 54bd3df3a059 bridge bridge local 8e98086700d8 host host local 6235cc583642 none null local
위의 명령어는 기본적으로 제공되는 Docker Network 의 목록입니다.
위 3개의 Docker Network 중에서 Bridge Type 의 Docker Network 가 존재하며, 이 Network 가 이번 글의 주제인 Bridge Type 의 Network 에 해당합니다.
그리고 docker network create n1 와 같은 형식으로 추가적인 Bridge Type Docker Network 를 추가할 수 있습니다.
NETWORK ID NAME DRIVER SCOPE 54bd3df3a059 bridge bridge local 8e98086700d8 host host local 262c5d648902 n1 bridge local f78732c4e81a n2 bridge local 6235cc583642 none null local
이러한 Docker Network 는 실제 Linux 내부에서 Bridge Type 의 Network Interface 를 생성하게 됩니다.
그리고 Container 내부의 Virtual Ethernet Network Interface 와 연결됩니다.
아래의 링크는 Docker Container 와 Virtual Ethernet Network Interface 의 관계를 정리한 글입니다.
https://westlife0615.tistory.com/913
[Docker] Docker Container 와 veth ( Virtual Ethernet Network Interface ) 알아보기
- 목차 들어가며.이번 글에서는 Docker Container 와 Network Namespace 격리에 대해서 알아보려고 합니다.Docker Container 는 Linux 의 Network Namespace 를 활용하여 Network 를 격리합니다.그 외에 PID, UTS, MOUNT 등의
westlife0615.tistory.com
이번 글에서는 Docker Network 와 Bridge Type 의 Interface 에 대해서 상세히 알아보는 시간을 가지려고 합니다.
Bridge Network Interface 란 ?
Bridge Network Interface 에 대해서 알아보기 이전에 기본적인 Ethernet Network Interface 에 대해서 먼저 알아봅니다.
외부 인터넷과 연결된 eth0 또는 wlan 과 같은 Network Interface.
흔히 eth0 나 wlan 와 같이 Internet Gateway 와 연결된 Network Interface 가 존재합니다.
그리고 일반적인 컴퓨터들은 이러한 Network Interface 와 연결됩니다.
eth0 는 Ethernet Network Interface 그리고 wlan 은 Wireless LAN 통신을 위한 Network Interface 를 의미합니다.
실제로 아래의 이미지와 같이 각 서버들은 자신의 Network Interface 를 통해서 외부 인터넷과 연결됩니다.
Switch 가 연결된 서버들.
그리고 Router 에 의해서 형성된 Private Network 내부에 Switch 장비를 둘 수 있습니다.
아래의 이미지는 상당히 단순화된 모습이긴 하지만 핵심은 Switch 를 중심으로 여러 서버들을 배치할 수 있습니다.
이렇게 함으로써 Switch 내부의 서버들은 라우터를 거치지 않는 효율적인 통신을 할 수 있습니다.
여기서 Switch Network Device 를 설명드리는 이유는 Bridge Network Interface 가 마치 가상의 또는 소프트웨어적인 Switch 로 동작하기 때문입니다.
아래의 이미지는 Docker Host 와 Container 내부에서 Network 관계를 설명하는 그림입니다.
Container 의 Ethernet Interface 와 Host 의 Virtual Ethernet Interface 는 서로 연결됩니다.
그리고 Bridge Type Interface 가 두 veth 를 연결합니다.
만약 Bridge Type Interface 가 없다면 각 Container 는 네트워크적으로 고립될 가능성이 있습니다.
Bridge Network 을 통한 Container 의 Network 전송.
만약 Container 1 에서 Container 2 로 네트워크 트래픽을 전송한다면 그 경로는 아래와 같습니다.
Container1 Eth --> Host Veth1 --> Host Bridge --> Host Veth2 --> Container2 Eth
만약 Host 의 Bridge Network Interface 가 존재하지 않는다면, Container2 로 네트워크 트래픽을 전달할 수 없습니다.
Container1 Eth --> Host Veth1 --> X (단절됨.)
Docker Network 과 실제 Linux Bridge Network Interface 관계 파악하기.
아래와 같이 5개의 Docker Network 가 존재합니다.
그리고 Bridge Type 의 Docker Network 는 3개가 존재합니다.
docker network ls NETWORK ID NAME DRIVER SCOPE 54bd3df3a059 bridge bridge local 8e98086700d8 host host local 262c5d648902 n1 bridge local f78732c4e81a n2 bridge local 6235cc583642 none null local
그리고 ip addr show 명령어를 통해서 생성된 모든 Network Interface 목록을 확인할 수 있습니다.
아래의 출력 결과는 Bridge Type 의 Network Interface 만 추려서 가져온 결과입니다.
11번 Interface 인 docker0 는 기본적으로 제공되는 Bridge Type Docker Network 입니다.
그리고 12번과 13번에 해당하는 br-XXXX 네트워크 인터페이스는 명시적으로 생성한 n1, n2 네트워크입니다.
11: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN link/ether 02:42:0a:e4:13:ca brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0 valid_lft forever preferred_lft forever 12: br-262c5d648902: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN link/ether 02:42:4a:6b:93:50 brd ff:ff:ff:ff:ff:ff inet 172.19.0.1/16 brd 172.19.255.255 scope global br-262c5d648902 valid_lft forever preferred_lft forever 13: br-f78732c4e81a: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN link/ether 02:42:0d:2f:ff:11 brd ff:ff:ff:ff:ff:ff inet 172.20.0.1/16 brd 172.20.255.255 scope global br-f78732c4e81a valid_lft forever preferred_lft forever
각 인터페이스는 inet 172.X.0.1 와 같이 IPv4 수준의 IP 를 소유합니다.
Docker Container 와 Network 연결하기.
아래의 명령어를 통해서 아주 간단한 Docker Container 를 2개 실행하였습니다.
docker run --network n1 -d busybox sleep 100000
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e25e21b0f7f busybox "sleep 100000" 22 seconds ago Up 22 seconds quizzical_austin 5e40782136df busybox "sleep 100000" 34 seconds ago Up 34 seconds agitated_cannon
그리고 ps aux 명령어를 통해서 생성된 Process List 를 확인할 수 있습니다.
dockerd, containerd, containerd-shim 등을 일단 제외하고, sleep 10000 인 Container Process 에 주목합니다.
이 Container Process 가 바로 Linux Namespace Isolation 이 적용된 실제 Docker Container 에 해당합니다.
PID USER TIME COMMAND 1 root 0:00 docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 56 root 0:01 dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify -- 68 root 0:04 containerd --config /var/run/docker/containerd/containerd.toml 254 root 0:00 sh 424 root 0:00 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 5e40782136dfcb23bdc8ee9c 445 root 0:00 sleep 100000 496 root 0:00 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 6e25e21b0f7ff1306bd2d7d4 515 root 0:00 sleep 100000 560 root 0:00 ps aux
첫번째 Container Process 의 PID 는 445 , 두번째 Container Process 의 PID 는 515 입니다.
그리고 각 Docker Container 의 IP 정보를 찾아보도록 하겠습니다.
개별적인 환경에 따라서 IP 정보나 Network Interface 의 ID 값이 반드시 다르겠지만,
아래의 절차에 의해서 각 Container 의 IP 값을 획득할 수 있습니다.
nsenter --net=/proc/445/ns/net ip addr show | grep eth0
nsenter --net=/proc/515/ns/net ip addr show | grep eth0
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0 16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP inet 172.19.0.3/16 brd 172.19.255.255 scope global eth0
위 내용을 잠시 정리해보면, nsenter 는 Network Namespace 내부로 진입할 수 있는 명령어입니다.
각 Docker Container 는 Network Namespace 에 의해서 격리되어 있습니다.
따라서 각 Process ID 를 기준으로 개별적인 Network Namespace 를 가지는데요.
이 /proc/$$/ns/net 파일에 저장된 Network Namespace 정보를 기준으로 Network Namespace 내부에 격리된 인터페이스를 조회할 수 있습니다.
이 상황에서 아래의 명령어를 통해서 Container 간의 통신이 가능합니다.
515 PID 의 Process 는 172.19.0.3 이라는 IP 를 가집니다.
그리고 445 PID 의 Process 는 172.19.0.2 IP 를 가집니다.
아래의 명령어는 nsenter 를 통해서 각 Process 의 Network Namespace 에 진입한 후에 다른 Container Process 에게 ping 요청을 수행합니다.
nsenter --net=/proc/515/ns/net ping 172.19.0.2
nsenter --net=/proc/445/ns/net ping 172.19.0.3
Bridge Network 제거해보기.
2개의 Docker Container 는 하나의 Bridge Network Interface 에 연결되어 있습니다.
아래는 각 Docker Container 의 veth Network Interface 정보입니다.
이 출력값을 확인해보면, master br-262c5d648902 라고 표현된 결과가 보입니다.
15: vethc24d9d3@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master br-262c5d648902 state UP 17: vethe7baad9@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master br-262c5d648902 state UP
"master br-262c5d648902" 의 의미는 "master br-262c5d648902" 로 표시된 네트워크 인터페이스가 "br-262c5d648902 인터페이스" 의 하위의 Interface 라는 것을 뜻합니다.
즉, 아래와 같이 veth Type 인터페이스는 동일한 Bridge Type Interface 에 계층적으로 속하게 됩니다.
Bridge Type Interface / Veth Type Interface br-262c5d648902 -> vethc24d9d3@if14 br-262c5d648902 -> vethe7baad9@if16
Veth Network Interface 와 Bridge Network Interface 의 연결을 제거해봅니다.
아래의 ip link set nomaster 명령어를 통해서 vethc24d9d3 인터페이스와 Bridge Network Interface 의 연결을 끊을 수 있습니다.
ip link set vethc24d9d3 nomaster
15: vethc24d9d3@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
그리고나서 아래의 명령을 통해서 Ping 요청을 하게되면 Network 요청이 전달되지 않습니다.
그 이유는 Bridge Connection 이 해제되었기 때문이죠.
nsenter --net=/proc/515/ns/net ping -c 3 172.19.0.2
nsenter --net=/proc/515/ns/net ping 172.19.0.2 PING 172.19.0.2 (172.19.0.2): 56 data bytes ^C --- 172.19.0.2 ping statistics --- 38 packets transmitted, 0 packets received, 100% packet loss
다시 아래와 같이 Bridge 와 Veth 인터페이스들을 연결해주면 정상적으로 통신이 가능해집니다.
ip link set vethc24d9d3 master br-262c5d648902
nsenter --net=/proc/515/ns/net ping -c 3 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.239 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.394 ms 64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.411 ms --- 172.19.0.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.239/0.348/0.411 ms
반응형'Docker' 카테고리의 다른 글
[Docker] Docker Container 와 PID Namespace 알아보기 (0) 2024.06.21 [Docker] Docker Container 와 veth ( Virtual Ethernet Network Interface ) 알아보기 (0) 2024.06.20