본문 바로가기
클라우드 Cloud/Docker

도커가 결국 리눅스인 이유 (Docker 컨테이너 네트워크 격리의 원리)

by 비타민찌 2025. 9. 17.
728x90

저번 포스팅 에서는 리눅스에서 네트워크 격리와 연결을 직접 다뤄보며 

컨테이너 네트워크가 어떻게 구현되는지를 확인했습니다. ​

 

 

도커 리눅스 비교 (Docker 컨테이너 네트워크 격리의 원리)

도커란, 결국 하나의 리눅스 커널 위에서여러 개의 격리된 실행 환경을 제공하는 기술입니다. docker run 한 줄로 띄우는 컨테이너도 사실리눅스 내부에서 이미 존재하던 기능들이 자동으로 설정

sudo-minz.tistory.com

 

이번 포스팅에서는 실제로 도커를 설치해서

정말 수동으로 설정했을 때와 비슷하게 네트워크가 격리가 되어있는지 확인해 보겠습니다.

 

 

준비

가상머신 두 대를 준비해서 한 대에는 도커를 설치하고,

한 대에는 도커를 설치하지 않은 상태로 만든 후

둘을 비교해 보겠습니다.

 

  1. VM A (도커 설치 리눅스): docker run 한 줄로 동일한 구성을 자동화
  2. VM B (도커 미설치 리눅스): 네임스페이스/브리지/veth를 수동으로 구성

 

 

1. Docker VM

1-1. 도커 네트워크 확인

처음에는 컨테이너가 실행되지 않아서 인터페이스가 비어 있습니다.

 

 

 

docker0는 Docker 데몬이 기본 네트워크(bridge)를 위해 만들어 둔 가상의 스위치(브리지)예요.

아직 어떤 컨테이너도 붙지 않아 포트(interfaces 열)가 비어 있는 것을 확인할 수 있습니다.

다음 명령어로 컨테이너를 실행합니다.

 

 

1-2. 컨테이너 실행

docker run -d --name web nginx:latest

 

 

컨테이너 실행 후 다시 확인해 봅니다.

 

 

 

 

자동으로 인터페이스가 생겼습니다!

 

 

ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdi ...
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ...
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ...
5: veth60862f3@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu ...

 

 

VM(hostPC)에서 ip addr로 확인해 보면 브리지(interfaces) 5번으로 인식되어 있는 것을 확인할 수 있습니다.

그리고 5번 interfaces는 if4와 연결되어 있습니다.

 

네임스페이스와 NIC 확인

lsns -t net

# 결과
        NS TYPE NPROCS   PID USER    NETNSID NSFS                           COMMAND
4026531840 net     226     1 root unassigned                                /sbin/i
4026532607 net       3  4090 root          0 /run/docker/netns/dfda7116e14d nginx: 


ln -s /proc/4090/ns/net /var/run/netns/mycontainer
ip netns exec <컨테이너-ns> ip addr

# 결과
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

 

 

네임스페이스 안에서 ip addr로 확인해 보면,

4번 interface는 host pc의 5번 interface와 연결된 것을 확인할 수 있죠.

(4: eth0@if5)

즉, 컨테이너 안에서 호스트 pc의 브리지를 통해 외부와 통신하는 것을 확인하였습니다.

 

 

2. 도커 미설치 수동 구성 VM

목표
  1. my_container라는 네트워크 네임스페이스를 만들고,
  2. 호스트에 가상 브리지 my_bridge를 만든 뒤,
  3. veth 페어로 호스트와 네임스페이스를 직접 연결한다.
  4. 동일 대역 IP를 부여해 통신 가능한 경로를 완성한다.

 

 

2-1. 네임스페이스와 브리지 만들기

아래 명령어로 네임스페이스(격리된 네트워크 공간), 브리지(내부 스위치 역할) 생성 후, brctl show로 확인

 

ip link add my_bridge type bridge

 

이 부분은 아래의 도커를 설치한 VM(1-1 순서) 부분과 동일합니다.

 

 

2-2. 호스트 <-> 네임스페이스 veth로 연결

호스트와 네임스페이스 사이를 이어 줍니다.

# 1.네임스페이스 생성
ip netns add my_container

# 2. veth 페어 생성 (이름은 15자 이내만 가능)
ip link add my-cont-veth type veth peer name my-brid-veth

# 3. my-cont-veth 를 my_container 네임스페이스로 이동
ip link set my-cont-veth netns my_container

# 4. 호스트 쪽 NIC를 브리지 포트로 연결, 활성화
ip link set my-brid-veth master my_bridge

 

 

 

 

2-3. IP 설정 및 인터페이스 활성화

네임스페이스 쪽 NIC에 컨테이너 IP(100.100.100.100/24),

호스트 쪽 NIC에 상대 IP(100.100.100.1/24)를 부여하여,

동일 대역 IP를 양쪽에 부여해 통신이 가능하도록 합니다.

 

# 네임스페이스 내부: veth에 IP 부여
ip netns exec my_container ip addr add 100.100.100.100/24 dev my-cont-veth

# 호스트: 브리지 포트에 IP 부여
ip addr add 100.100.100.1/24 dev my-brid-veth

# 링크 활성화 (브리지와 두 veth 인터페이스를 동작 상태(UP)로 전환)
ip link set my_bridge up
ip link set my-brid-veth up
ip netns exec my_container ip link set my-cont-veth up

 

 

2-4. 확인

먼저 brctl show로 브리지(mt_bridge)와 포트 연결(my-brid-veth)을 확인합니다.

 

 

 

그리고 ip netns exec my_container ip addr로

네임스페이스 내부 NIC와 IP를 확인해 봅시다.

 

도커 리눅스 컨테이너

 

 

본체와 격리된 네임스페이스가 연결되어 있는 것을 확인할 수 있습니다.

즉, 수동으로 구성해도 컨테이너와 같은 격리된 네트워크 환경을 만들 수 있었습니다.

 

 

 
Docker가 자동으로 하는 일
  1. 컨테이너용 네트워크 네임스페이스 생성
  2. veth 페어 생성
    1. 컨테이너 안: 한쪽 끝이 eth0로 보임
    2. 호스트: 다른 쪽 끝이 veth60862f3 같은 이름으로 생김(매번 달라질 수 있는 임시 이름)
  3. 호스트 쪽 veth를 docker0 브리지에 포트로 접속 → brctl show에 veth60862f3 표시
  4. 컨테이너 eth0에 IP/라우팅 설정(기본 bridge 네트워크)
  5. NAT/DNAT 등 포워딩 규칙(iptables/nftables) 자동 구성

 

 

3. 결론

제가 말하고자 하는 것은, 도커는 그냥 리눅스 프로그램이라는 것입니다.

격리된 환경에서 프로그램을 실행하는 리눅스 기반 프로그램 이죠.

 

많은 사람이 도커 사용법은 알지만

컨테이너 내부 동작(파일시스템/격리/자원관리 등)을 모르는 경우가 많습니다.

문제가 생기면 애플리케이션만 보는 것으로는 해결이 어렵습니다.

 

그래서 이번 포스팅에서는 도커가 내부적으로 어떻게 네트워크 격리를 구현하는지,

리눅스 네임스페이스/브리지/veth를 수동 구성한 방식과 비교하며 살펴보았습니다.

 

결국 도커는 리눅스를 이해할수록 더 잘 쓸 수 있는 도구입니다.

 

 

 

참고

https://youtu.be/SQ2Z1vKVaU8?si=IfFdu_-EcPPGoJFZ

https://blog.naver.com/ghdalswl77/224011193911

728x90

댓글