OS
[ DEVOCEAN OpenLab ] 리눅스 네임스페이스 (Network Namespace)
jogaknabi_1023
2024. 5. 9. 23:30
리눅스 네임스페이스에는 다양한 유형의 네임스페이스가 있다.
- 마운트 네임스페이스 (Mount Namespace): 파일 시스템 마운트 포인트를 격리하는 데 사용된다. 각각의 네임스페이스는 독립적으로 파일 시스템을 마운트하고 사용할 수 있다.
- PID 네임스페이스 (PID Namespace): 프로세스 식별 번호를 격리하는 데 사용된다. 각각의 네임스페이스는 독립적으로 프로세스 ID를 할당받아 프로세스의 식별이 겹치지 않는다.
- UTS 네임스페이스 (UTS Namespace): 호스트 시스템의 호스트 이름(UTS 이름)과 도메인 이름을 격리하는 데 사용된다.
- IPC 네임스페이스 (IPC Namespace): Inter-Process Communication (IPC) 자원을 격리하는 데 사용된다. 프로세스 간 통신(IPC) 자원(예: 메시지 큐, 세마포어 등)이 격리되어 독립적인 IPC 공간을 가진다.
- 유저 네임스페이스 (User Namespace): 사용자 ID(UID), 그룹 ID(GID)를 격리하는 데 사용된다. 각각의 네임스페이스는 독립적으로 사용자와 그룹을 정의하고 할당할 수 있다.
- 네트워크 네임스페이스(Network Namespace): 라우팅 테이블, 방화벽 규칙 등 네트워크 관련 구성 요소를 격리하는 데 사용된다. 각 네트워크 네임스페이스는 자체적인 네트워크 인터페이스와 IP 주소를 가지며, 네트워크 연결이 격리된다.
그 중에서도 이번 게시글에서 다뤄볼 네임스페이스는 Network Namespace이다.
[ 실습 1 ] 하나의 가상 네임스페이스 생성
new 네임스페이스 생성 및 라우팅 설정
# 모든 네트워크 인터페이스 확인 (기본)
ubuntu@ip-172-31-32-227:~$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 0a:af:ed:98:43:71 brd ff:ff:ff:ff:ff:ff
# 새로운 네임스페이스 생성
ubuntu@ip-172-31-32-227:~$ sudo ip netns add new
ubuntu@ip-172-31-32-227:~$ ip netns list
new
# veth 가상 이더넷 페어 생성
ubuntu@ip-172-31-32-227:~$ sudo ip link add veth1 type veth peer name veth2
# 생성된 네트워크 인터페이스 확인
ubuntu@ip-172-31-32-227:~$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 0a:af:ed:98:43:71 brd ff:ff:ff:ff:ff:ff
3: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 9a:8e:01:11:6c:5d brd ff:ff:ff:ff:ff:ff
4: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether a6:c8:21:7a:95:15 brd ff:ff:ff:ff:ff:ff
# veth2 인터페이스를 new 네임스페이스로 이동
ubuntu@ip-172-31-32-227:~$ sudo ip link set veth2 netns new
# new 네트워크 네임스페이스 내에서 veth2 인터페이스에 IP 주소를 추가
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ip address add 192.168.0.1 dev veth2
# new 네트워크 네임스페이스 내에서 veth2 인터페이스를 활성화
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ip link set dev veth2 up
# 현재 시스템의 기본 네트워크 네임스페이스에서 veth1 인터페이스를 활성화
ubuntu@ip-172-31-32-227:~$ sudo ip link set dev veth1 up
# new 네트워크 네임스페이스 내에서 lo(로컬 루프백) 인터페이스를 활성화
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ip link set lo up
# 현재 기본 라우팅 테이블 확인
ubuntu@ip-172-31-32-227:~$ sudo route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.31.32.1 0.0.0.0 UG 0 0 0 enX0
172.31.0.2 172.31.32.1 255.255.255.255 UGH 0 0 0 enX0
172.31.32.0 0.0.0.0 255.255.240.0 U 0 0 0 enX0
172.31.32.1 0.0.0.0 255.255.255.255 UH 0 0 0 enX0
# 192.168.0.1/32로 가는 패킷이 veth1 인터페이스를 통해 전달되게끔 라우팅 설정
ubuntu@ip-172-31-32-227:~$ sudo ip route add 192.168.0.1/32 dev veth1
# 라우팅 테이블 설정 확인
ubuntu@ip-172-31-32-227:~$ route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.31.32.1 0.0.0.0 UG 0 0 0 enX0
172.31.0.2 172.31.32.1 255.255.255.255 UGH 0 0 0 enX0
172.31.32.0 0.0.0.0 255.255.240.0 U 0 0 0 enX0
172.31.32.1 0.0.0.0 255.255.255.255 UH 0 0 0 enX0
192.168.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 veth1
# ping으로 통신 확인 -> 통신 안됨.
ubuntu@ip-172-31-32-227:~$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
From 172.31.32.227 icmp_seq=1 Destination Host Unreachable
From 172.31.32.227 icmp_seq=2 Destination Host Unreachable
# 네임스페이스 new에서 설정된 라우팅 테이블 확인
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
# new 네임스페이스의 내부 트래픽을 veth2 인터페이스(dev)를 통해 지정된 게이트웨이로 보내도록 라우팅 테이블 설정
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ip route add default via 192.168.0.1 dev veth2
# new 네임스페이스의 라우팅 테이블 확인
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 veth2
# ping 확인 -> 통신 가능.
ubuntu@ip-172-31-32-227:~$ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.058 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=0.034 ms
[ 실습 2 ] 두 개의 가상 네임스페이스 생성
실습1에서 만들었던 네임스페이스 new 설정은 그대로하고 old 라는 새로운 네임스페이스를 만든다. 이후 브릿지 네트워크를 생성하여 두 네임스페이스가 통신 가능하도록 하는 것이 목표이다. old 네임스페이스 설정은 new 네임스페이스 및 라우팅 설정과 동일한 방법이다.
old 네임스페이스 생성 및 라우팅 설정
ubuntu@ip-172-31-32-227:~$ sudo ip link set veth4 netns old
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old ip address add 192.168.0.2 dev veth4
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old ip link set dev veth4 up
ubuntu@ip-172-31-32-227:~$ sudo ip link set dev veth3 up
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old ip link set lo up
ubuntu@ip-172-31-32-227:~$ sudo ip route add 192.168.0.2/32 dev veth3
ubuntu@ip-172-31-32-227:~$ route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 172.31.32.1 0.0.0.0 UG 0 0 0 enX0
172.31.0.2 172.31.32.1 255.255.255.255 UGH 0 0 0 enX0
172.31.32.0 0.0.0.0 255.255.240.0 U 0 0 0 enX0
172.31.32.1 0.0.0.0 255.255.255.255 UH 0 0 0 enX0
192.168.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 veth1
192.168.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 veth3
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old ip route add default via 192.168.0.2 dev veth4
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old route -en
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.0.2 0.0.0.0 UG 0 0 0 veth4
# 최종적으로 로컬에서 old 네임스페이스 veth4와 통신 가능한 것을 확인
ubuntu@ip-172-31-32-227:~$ ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.064 ms
Bridge Network 설정
Before) new <-> old 네임스페이스 통신 불가능
# 브릿지 네트워크 생성 전 (new -> veth4(192.168.0.2)) => 통신 불가능
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
From 192.168.0.1 icmp_seq=1 Destination Host Unreachable
From 192.168.0.1 icmp_seq=2 Destination Host Unreachable
After) new <-> old 네임스페이스 서로 통신 가능
# bridge 인터페이스 생성
ubuntu@ip-172-31-32-227:~$ sudo ip link add br0 type bridge
# bridge 인터페이스에 ip 주소 할당
ubuntu@ip-172-31-32-227:~$ sudo ip addr add 192.168.0.10/24 dev br0
# 인터페이스 활성화
ubuntu@ip-172-31-32-227:~$ sudo ip link set dev br0 up
# veth1 인터페이스 br0 브릿지에 연결
ubuntu@ip-172-31-32-227:~$ sudo ip link set veth1 master br0
# veth3 인터페이스 br0 브릿지에 연결
ubuntu@ip-172-31-32-227:~$ sudo ip link set veth3 master br0
# new 네임스페이스에서 veth4으로 통신 가능
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec new ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.041 ms
# old 네임스페이스에서 veth2으로 통신 가능
ubuntu@ip-172-31-32-227:~$ sudo ip netns exec old ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=0.045 ms