Network Namespace 개념은 리눅스 컨테이너에서 네트워크 분리를 위해 사용되는 기술이다.
컨테이너는 Process Namespace로 격리되어 있어서, 컨테이너 위에서 돌아가는 프로세스만 볼 수 있다. 컨테이너 위에서 ps aux를 찍어 보면 CMD로 구동되는 프로세스의 PID가 1임을 볼 수 있다.
하지만 호스트에서 ps aux를 찍어 보면, 해당 프로세스의 PID가 전혀 다른 값으로 들어가 있는 것을 볼 수 있다.
즉 같은 프로세스가 컨테이너 내부와 외부에서 전혀 다른 PID를 가지고 있는 것이다.
네트워크 네임스페이스도 비슷하다. 호스트에는 Routing 및 ARP Table이 존재한다.
하지만 컨테이너 생성 시에는 네트워크 네임스페이스가 생성되며, 컨테이너 내부에서는 호스트의 네트워크 관련 정보를 전혀 볼 수 없다.
또한, 컨테이너는 네트워크 네임스페이스 내부에서 자신의 가상 인터페이스 (veth0), 라우팅 테이블, ARP 테이블을 가지고 있다.
네트워크 네임스페이스의 생성
ip netns add name으로 네트워크 네임스페이스를 수동으로 생성할 수 있다.ip netns로 네트워크 네임스페이스를 볼 수 있다.
호스트에서는, ip link로 인터페이스 목록을 볼 수 있다. 네트워크 네임스페이스 내부의 인터페이스 목록은 어떻게 볼 수 있을까?
ip netns exec name ip link를 실행하면 된다.- 혹은,
ip -n name link를 할 수도 있겠다.
ARP Table이나 Routing Table 역시 비슷하게 볼 수 있다.
ip netns exec name arpip netns exec name route
두 네트워크 네임스페이스를 연결하기
가상 이더넷 쌍을 이용하여 두 네트워크 네임스페이스 red와 blue를 연결해 보자. ("Virtual Cable" 또는 "Pipe")
veth-red와 veth-blue 인터페이스를 생성한다.
ip link add veth-red type veth peer name veth-blue
각각의 인터페이스를 네트워크 네임스페이스에 할당한다.
ip link set veth-red netns redip link set veth-blue netns blue
ip addr명령어로 각 네임스페이스의 인터페이스에 IP를 할당한다.ip -n red addr add 192.168.15.1 dev veth-redip -n blue addr add 192.168.15.2 dev veth-blue
ip link set up명령어로 인터페이스를 올린다.ip -n red link set veth-red upip -n blue link set veth-blue up
이제 통신이 작동한다.
ip netns exec red ping 192.168.15.2- red 네트워크 네임스페이스의 ARP 테이블에는 veth-blue의 MAC주소와 IP가 기록된다.
ip netns exec red arp
- blue 네트워크 네임스페이스의 ARP 테이블에는 veth-red의 MAC주소와 IP가 기록된다.
- 호스트에서
arp를 실행해보면, 이 네트워크 네임스페이스 내부의 ARP 정보는 전혀 확인할 수 없다.
여러 네트워크 네임스페이스를 브리지로 연결하기
현실에서 여러 호스트를 이더넷으로 연결하려면 스위치를 사용한다.
마찬가지로 가상세계에서 여러 네트워크 네임스페이스를 가상 이더넷으로 연결하려면 가상 스위치를 사용하면 된다.
리눅스의 브리지(Bridge)를 이용하여 이를 구현할 수 있다.
호스트에서
ip link add vnet0 type bridge를 하여 브리지를 생성한다.- 호스트의 입장에서는 이것은 하나의 인터페이스이다.
ip link를 찍어 보면 목록에 lo, eth0과 함께 나온다.- 하지만 네트워크 네임스페이스에 있어서는 스위치처럼 기능한다.
- 일단
ip link set dev vnet0 up으로 링크를 올려준다.
- 호스트의 입장에서는 이것은 하나의 인터페이스이다.
기존 단계에서 사용했던 link들은 삭제해준다. (
ip -n red link del veth-red)이제 veth-red와
veth-red-br간의 peer를 만들어주고, veth-red 인터페이스를 네트워크 인터페이스에 할당한다.ip link add veth-red type veth peer name veth-red-brip link set veth-red netns red
이제 veth-red-br을 브리지에 연결시켜주어야 한다. 이를 위해,
ip link set veth-red-br master vnet0처럼, master를 vnet0으로 지정한다.
나머지 과정은 위와 동일하다.
ip addr명령어로 각 네임스페이스의 인터페이스에 IP를 할당한다.ip -n red addr add 192.168.15.1 dev veth-redip -n blue addr add 192.168.15.2 dev veth-blue
ip link set up명령어로 인터페이스를 올린다.ip -n red link set veth-red upip -n blue link set veth-blue up
호스트와 브리지 간 통신
이 브리지라는 것은 호스트 입장에서는 네트워크 인터페이스이다. 그렇기에 호스트에서 vnet0에 IP를 할당해주기만 하면 호스트에서 브리지 네트워크 간에 서로 통신이 가능하다.ip addr add 192.168.15.254/24 dev vnet0
브리지에서 바깥 네트워크로 나가기
호스트의 eth0이 192.168.1.2/24라고 해 보자. pink 네임스페이스(192.168.15.1/24)에서 eth0과 연결된 LAN의 192.168.1.3에 접속하려면 어떻게 해야 할까?
pink 네임스페이스에서 192.168.1.0/24에 대한 라우팅 정보, 이를테면 게이트웨이를 알아야 한다.ip netns exec blue ip route add 192.168.1.0/24 via 192.168.15.254를 해 주면, 이제 192.168.15.1에서 192.168.1.0/24로 패킷이 나갈 수 있다.
하지만, 패킷이 다시 돌아올 수는 없다. 외부 네트워크는 192.168.15.0/24를 모르기 때문이다.
따라서 NAT를 설정해주어야 한다.
iptables를 이용하여 NAT 기능을 추가할 수 있다.iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -j MASQUERADE
인터넷에 연결하기
지금 pink의 라우팅 테이블에는 목적지 192.168.15.0/24, 192.168.1.0/24에 대한 정보밖에 없기 때문에, ping 8.8.8.8을 하면 Network is unreachable이 나올 것이다.
ip netns exec pink ip route add default via 192.168.15.5로, 기본 라우트를 192.168.15.254로 잡아주면, 패킷이 외부로 나갈 수 있다.
외부 네트워크에서 브리지에 물린 네임스페이스로 inbound
192.168.15.0/24의 라우팅 정보를 외부 네트워크의 라우팅 테이블에 올리는 방법이 있긴 한데 이것은 별로 효율적인 방식은 아니다.
이것보다는 포트포워딩을 해 주는 것이 현실적이다.iptables -t nat -A PREROUTING --dport 80 --to-destination 192.168.15.2:80 -j DNAT
'콤퓨우터 > 필기: KodeKloud CKA 강의' 카테고리의 다른 글
| 215. CNI Weave (0) | 2024.05.17 |
|---|---|
| 206. Docker Networking (0) | 2024.05.17 |
| 189-191. Persistent Volumes, Persistent Volume Claims and Using PVCs in Pods (0) | 2024.05.17 |
| 184-185. Storage in Docker and Volume Driver Plugins (0) | 2024.05.17 |
| 177-178. Kubernetes Network Policy (0) | 2024.05.17 |