Network Namespace

2025. 5. 15. 19:09·DevOps/✏️ Cloud
반응형

컨테이너가 어떻게 네트워킹을 구성하고, 호스트 부터 외부 인터넷까지 통신 되는지 이해가 너무 안되서 정리.
도커가 구성하는 방법을 알려면 리눅스의 네트워크 네임스페이스 개념부터 알아야 한다.

network namespace

리눅스에는 network namespace 라는 기능이 존재함.
컨테이너는 격리된 환경이기 때문에, 컨테이너가 생성되면 Network namespace 가 생성됨.
네임스페이스 안에서는 고유의 가상 인터페이스 라우팅, ARP 테이블을 가진다. 즉 host의 정보와 격리됨.

# 리눅스 네트워크 네임스페이스 생성 방법(name : red, blue)
ip netns add red

ip netns add blue

# network namespace 조회 방법

$ ip netns
red
blue

생성된 네임스페이스 안에서 네트워크 인터페이스를 조회하려면 아래 명령어 처럼 수행해야 함.
격리되어 있기 때문에 네임스페이스 안에서 조회하면 호스트의 인터페이스는 보이지 않는다.
arp, 라우팅 테이블 도 마찬가지로 아래와 같은 형식으로 조회된다.

# ip link
// 호스트의 인터페이스만 표시

# ip netns exec red ip link
// red 네임스페이스의 인터페이스 표시

# ip -n red link
// red 네임스페이스의 인터페이스 표시

만들어진 네트워크 네임스페이스 끼리 통신하려면 가상 인터넷 인터페이스 쌍 만들어서 각각 연결해줘야 한다.
가상 이지만 쉽게 말하면 두 네임스페이스를 연결하는 케이블을 소프트웨어 적으로 생성한다고 볼 수 있다.

// 가상 인터넷 케이블 생성
# ip link add veth-red type veth peer name veth-blue

//chat gpt 설명
# ip link add: 네트워크 링크(인터페이스)를 추가하는 명령어입니다.
# veth-red: 새로 만들 가상 이더넷 인터페이스 중 하나의 이름입니다. 사용자가 임의로 지정할 수 있습니다. 이 예시에서는 "veth-red"라고 이름을 지은 거예요.
# type veth: 만들 인터페이스의 종류를 지정합니다. 여기서는 "veth" 타입, 즉 가상 이더넷 인터페이스를 만들겠다는 의미입니다.
# peer name veth-blue: veth-red 인터페이스와 쌍으로 연결될 또 다른 가상 이더넷 인터페이스의 이름을 지정합니다. 이 예시에서는 "veth-blue"라고 이름을 지었습니다.

 케이블을 생성했으면 각 네트워크 네임스페이스에 해당 케이블을 연결하는 작업을 수행해줘야 한다. 

// red namespace 에 veth-red 인터페이스를 연결
# ip link set veth-red netns red

// blue namespace 에 veth-blue 인터페이스를 연결
# ip link set veth-blue netns blue

// chatgpt
# ip link set: 이미 존재하는 네트워크 링크(인터페이스)의 설정을 변경하는 명령어입니다. 이전에는 add를 사용해서 새로운 인터페이스를 만들었지만, 이번에는 set을 사용해서 기존의 veth-red 인터페이스의 속성을 변경하는 것입니다.
# veth-red: 설정을 변경할 대상 인터페이스의 이름입니다. 앞선 명령어에서 생성했던 veth-red 인터페이스를 지정하는 것이죠.
# netns red: veth-red 인터페이스를 이동시킬 대상 네트워크 네임스페이스를 지정합니다. 여기서는 red라는 이름을 가진 네트워크 네임스페이스로 옮기라는 의미입니다.

이제 네트워크 네임스페이스를 연결하는 케이블을 연결했지만, 각 인터페이스에 IP가 할당되지 않았다.
아래 명령어로 IP 를 할당하면 해당 Ip 를 통해 각 네트워크 네임스페이스 끼리 통신이 가능해진다.
dev 는 왜 dev 일까 궁금했는데, device 의 약자라고 한다. ( 개발계 를 나타내는건가 했음.. )
ip를 할당 했으면 이제 인터페이스를 기동시켜야 한다. 
완료 했으면 arp 테이블을 조회하면 상대방의 IP 정보를 알 수 있다.

# ip -n red addr add 192.168.15.1 dev veth-red

# ip -n blue addr add 192.168.15.2 dev veth-blue

# ip -n red link set veth-red up
# ip -n blue link set veth-blue up

가상 스위치

2개의 네임스페이스라면 위에 케이블 처럼 직접 연결 할 수 있지만, 네임스페이스가 많아지면 스위치를 이용해야 한다.
Linux bridge 기능을 이용한다.

# ip link add v-net-0 type bridge

v-net-0이라는 이름의 브릿지 네트워크 인터페이스를 생성

브릿지 인터페이스란 하나 이상의 네트워크 인터페이스를 논리적으로 연결하여 마치 하나의 더 큰 네트워크 세그먼트처럼 동작하게 하는 가상의 스위치 라고 한다. 
여러개의 네트워크 네임스페이스가 생기면 각각 연결하기 어려우니 모두 스위치에 연결해서 통신이 가능하도록 한다고 생각.

// bridge 타입의 v-net-0 인터페이스를 기동하는 명령어
# ip link set dev v-net-0 up

이제 해당 브릿지 인터페이스에 각 네트워크 네임스페이스의 인터페이스를 연결해주면 된다.

// veth-red 와 veth-red-br 을 연결하는 케이블 생성
# ip link add veth-red type veth peer name veth-red-br

// red 네트워크 네임스페이스에 veth-red 를 연결
# ip link set veth-red netns red

// bridge 네트워크에 연결
# ip link set veth-red-br master v-net-0

 veth-red 라는 네트워크 인터페이스를 red namespace 에 등록하고 veth-red-br 에 연결하는 것이다.
마찬가지로 veth-red-br 은 브릿지 네트워크에 연결하면 된다.
이제 veth-red 인터페이스에 ip 를 할당하고 up 해주면 된다.

// ip 할당
# ip -n red addr add 192.168.15.1 dev veth-red

// up 인터페이스
ip -n red link set veth-red up

각 네트워크 인터페이스 마다 bridge 네트워크에 연결해주면 된다!

이렇게 bridge network 에 연결하더라도 host 에서 veth-red 에 할당한 ip 로 ping 을 날려도 찾을수가 없다.
왜냐하면 host 에서 bridge network 로 연결할 방법이 없기 때문이다. 그래서 bridge network 에 ip 를 할당해준다.
이렇게 하면 ping이 가능하다. 하지만 host 내부에서만 가능하다.

// ip 할당
# ip addr add 192.168.15.5/24 dev v-net-0

 

가상스위치 내부 네트워크에서 인터넷과 통신을 위한 방법

구성된 bridge 네트워크 내부에서 인터넷과 통신하기 위해서는 어떻게 해야할까?
host 네트워크의 eth0 인터페이스를 이용해야 한다.
예를 들어 eth0 과 연결된 외부 호스트 (192.168.1.3) 과 통신하기 위해 red 네트워크 네임스페이스 내부에서 ping 을 날리면 찾을 수가 없다. 
다른 네트워크이기 때문이다. (192.168.15.* / 192.168.1.*)
이러한 경우 다른 네트워크에 접속해야 하기 때문에 게이트웨이를 등록해줘야 한다. 

// 게이트웨이 등록
ip -n red ip route add 192.168.1.0/24 via 192.168.15.5

앞서 v-net-0 의 ip 를 192.168.15.5 로 할당 했었는데 192.168.1.0/24 의 host 와 통신하기 위해서는 해당 문을 통과하여 통신하라고 지정해주는 명령어이다. 하지만 여기까지 해도 ping 의 응답이 오지 않는다.
목적지에서는 출발지 네트워크를 모르기 때문이다. 
이러한 경우에 NAT 를 호스트에서 등록해주면 된다.

# iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -j MASQUERADE

이렇게 등록해주면 다른 네트워크 네임스페이스에서 패킷을 보내도 해당 호스트가 통신을 시도한 것으로 외부 네트워크가 인식한다.
구글 같은 인터넷과도 통신하려면 네임스페이스가 인터넷에도 도달해야 한다.
지금은 네임스페이스 내부의 라우팅 테이블에 인터넷으로 가는 길이 없다. 해당 부분도 등록해줘야 한다.

# ip -n red ip route add default via 192.168.15.5

기본 routing 은 v-net-0 를 통해서 통신해라 라고 따로 등록해줬기 때문에 네임스페이스 내부에서 통신을 시도하면 호스트의 네트워크에서 통신을 시도하게 된다. 호스트는 인터넷과 연결되어 있어서 정상적으로 통신이 가능함.

 

외부 네트워크에서 가상스위치 내부 네트워크와 통신하는 방법

하지만 반대로 외부 호스트에서 red 네트워크 네임스페이스 내부의 장비로 통신을 시도하려면 어떻게 해야할까?
외부 (192.168.1.3) 에서는 내부 인터넷 네임스페이스 (192.168.15.1) 에 통신할 수 없기 때문에 호스트의 위치를 찾을 수가 없다.

이러한 경우엔 외부에서 오는 통신을 호스트가 내부 네트워크 네임스페이스로 갈 수 있도록 iptables 를 설정해주는 것이다.

# iptables -t nat -A PREROUTING --dport 80 --to-destination 192.168.15.1:80 -j DNAT

호스트 장비의 80 포트로 통신 시도가 오면 192.168.15.1 의 80 포트로 전달해주도록 설정하였다.
호스트에서는 해당 네트워크 네임스페이스로 통신이 가능하기 때문에 외부에서도 해당 주소로 통신이 가능해지게 된다.

 

반응형
저작자표시 (새창열림)

'DevOps > ✏️ Cloud' 카테고리의 다른 글

CNI (Container Network Interface)  (0) 2025.05.19
Docker Networking  (1) 2025.05.16
drain, cordon, uncordon 명령  (0) 2025.03.27
Multi-Container (init Container)  (0) 2025.03.26
K8S Controller (ReplicaSet, Deployment)  (0) 2024.12.11
'DevOps/✏️ Cloud' 카테고리의 다른 글
  • CNI (Container Network Interface)
  • Docker Networking
  • drain, cordon, uncordon 명령
  • Multi-Container (init Container)
자동화를 꿈꿉니다.
자동화를 꿈꿉니다.
DevOps 개발자
  • 자동화를 꿈꿉니다.
    데봅스 성장기
    자동화를 꿈꿉니다.
  • 전체
    오늘
    어제
    • 분류 전체보기 (29)
      • DevOps (29)
        • ✏️ Cloud (12)
        • ✏️ CICD (11)
        • ✏️ Mac (6)
      • 경제 (0)
      • 운동 (0)
  • 블로그 메뉴

    • 홈
  • hELLO· Designed By정상우.v4.10.3
자동화를 꿈꿉니다.
Network Namespace
상단으로

티스토리툴바