docker0 - Software Bridge

Server에 apt install docker 만 설치하고 컨테이너를 안 띄움

이 상태에서 ip a 를 확인하면

1: lo: <LOOPBACK> 
   inet 127.0.0.1/8
2: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP>
   inet 192.168.56.100/24 진짜 NIC (외부랑 연결)
3: docker0: <BROADCAST,MULTICAST,UP>
   inet 172.17.0.1/16 Docker가 자동으로 만든 브리지

docker0는 Docker가 설치되는 순간 자동으로 생성됨 (컨테이너 생성과는 무관)

container 생성 흐름

1. nginx 컨테이너 하나 띄운다고 가정

docker run -d --name web1 nginx

2. Docker가 컨테이너의 network namespace를 생성

[Container web1]
   └─ 자기만의 network namespace (텅 비어있음)

3. Docker가 veth pair 생성

Linux kernel한테 “가상 케이블 하나 만들어줘” 요청

veth pair:
  ├─ 한쪽 끝: veth1234abc (호스트에 보임)
  └─ 다른 끝: eth0        (컨테이너 안에 들어갈 예정)

4. veth 한쪽 끝을 컨테이너 안으로 이동

Docker가 한쪽 끝(eth0)을 컨테이너의 network namespace 안으로 옮김

이제 컨테이너 안에서 ip a 를 치면 eth0가 보임

컨테이너 입장에서는 자기만의 일반적인 네트워크 카드가 있는 것처럼 보임

[Container web1]
   └─ eth0 (veth pair의 한쪽 끝)

5. 나머지 한쪽 끝을 docker0 브리지에 연결

호스트에 남은 다른 쪽 끝(veth1234abc)을 docker0 브리지에 꽂음

[docker0 브리지]
   ├─ 포트 1: veth1234abc ← 방금 꽂힘
   └─ (다른 포트들은 비어있음)

6. 컨테이너에 IP 할당

Docker가 docker0 대역에서 IP 하나를 순차적으로 eth0에 할당

[Container web1]
   └─ eth0: 172.17.0.2 ← 새 IP

7. 컨테이너 안에 라우팅 테이블 설정

컨테이너 안에서 ip route 확인

default via 172.17.0.1 dev eth0   ← 기본 게이트웨이 = docker0
172.17.0.0/16 dev eth0

결론

  • Docker는 docker0이라는 가상 스위치(브리지)를 호스트에 만들고, 모든 컨테이너를 veth pair로 이 스위치에 연결함
  • 컨테이너끼리는 L2(브리지)로 빠르게 통신하고, 외부로 나갈 땐 호스트 라우팅으로 올라가 iptables의 MASQUERADE/DNAT 규칙으로 IP를 변환해서 통신함