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 arp
ip 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 red
ip link set veth-blue netns blue
ip addr
명령어로 각 네임스페이스의 인터페이스에 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 link set up
명령어로 인터페이스를 올린다.ip -n red link set veth-red up
ip -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-br
ip 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-red
ip -n blue addr add 192.168.15.2 dev veth-blue
ip link set up
명령어로 인터페이스를 올린다.ip -n red link set veth-red up
ip -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 |