일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- namespace
- built-in
- 실사용
- S3
- 리뷰
- 도커
- 커피머니불리기
- 후기
- docker network
- 리워드앱
- docker
- Container
- 토스카드
- network
- mininet
- 재테크
- DocumentDB
- Python
- python3
- clone
- MongoEngine
- aws codecommit
- 하나머니
- MongoDB
- AWS
- VPC
- Linux
- 앱테크
- codecommit
- 포인트앱
- Today
- Total
ㅍㅍㅋㄷ
Linux namespace - NET 본문
NET namespace
최근 lightweight 한 가상화 플랫폼인 Docker나 Linux container LXC 가 주목을 받고 있는데, 여기에 사용된 기반 기술 중 하나로 namespace 라는 것이 있다. namespace 에 대한 설명은 이전 포스팅 참고 ( Linux namespace )
namespace 는 크게 6가지로 분류되는데, 이번 포스팅에는 NET namespace에 대해 알아볼 예정이다.
1. UTS namespace : hostname 을 변경하고 분할
2. IPC namespace : Inter-process communication. 프로세스간 통신 격리
3. PID namespace : PID (Process ID)를 분할 관리
4. NS namepsace : file system 의 mount 지점을 분할하여 격리
5. NET namespace : Network interface, iptables 등 network 리소스와 관련된 정보를 분할
6. USER namespace : user와 group ID를 분할 격리
NET namespace 는 격리화된 network interface를 제공하는 기술이다. 이것 또한 기존 namespace 와 같은 방식으로 clone system call 에서 CLONE_NEWNET flag를 추가해서 구현이 가능하다.
int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWNET | SIGCHLD, NULL);
한가지 반가운 점은, NET namespace의 경우 iproute2 의 ip netns 라는 명령어를 이용하여 손쉽게 구현할 수 있도록 제공하고 있다.
먼저 ip 명령어를 통해 현재 서버의 interface 정보를 확인해 보자.
root@~~# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:8e:40:2d brd ff:ff:ff:ff:ff:ff
현재 interface는 loopback 과 eth0 두개가 있는것을 볼 수 있다.
iproute2 를 이용한 network namespace 생성
이제 ip netns로 새로운 namespace를 생성해 보자. song_ns 라는 이름으로 만들어 보자.
root@~~# ip netns add song_ns
생성된 namespace는 아래와 같이 확인이 가능하다.
root@~~# ip netns
song_ns
이제 방금 생성한 namespace인 song_ns 내부에 interface 정보를 보자.
ip netns exec 라는 명령어를 이용하면 지정한 namespace 내부에 명령어를 입력할 수 있다.
root@~~# ip netns exec song_ns ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
위 결과는 song_ns namespace 내부에서 ip link list 라는 명령어를 출력한 것이다.
song_ns 내부에는 위와 같이 loopback interface 하나만 있는걸 확인할 수 있다. state 또한 DOWN 상태이다.
loopback interface를 up 해보자.
root@~~# ip netns exec song_ns ip link set lo up
interface를 다시 확인해 보면 아래와같이 DOWN 상태에서 UNKNOWN 상태로 변경된걸 볼 수 있다.
root@~~# ip netns exec song_ns ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
그렇다면, 이렇게 생성한 network namespace 는 어떻게 외부와 통신할 수 있을까?
가장 간단한 방법은 veth interface를 이용하는 방법이다. veth interface의 가장 큰 특징은 두개의 interface가 pair로 동작한다는 점이다.
한쪽 interface 에 packet이 들어오면 pair로 맺어진 다른쪽 interface로 나가도록 동작한다.
이것을 이용하여 veth pair 의 한쪽 interface는 namespace 내부에, 한쪽은 외부에 생성하게 되면 namespace 내/외부로 통신이 가능하다.
아래와 같이 veth0 와 veth1 interface를 생성하고 두 interface를 pair로 설정하자.
root@~~# ip link add veth0 type veth peer name veth1
ip link list 로 살펴보면 아래와 같이 veth0과 veth1 interface 가 생성된 것을 볼 수 있다.
root@~~# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:8e:40:2d brd ff:ff:ff:ff:ff:ff
3: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 02:86:c2:3c:82:0c brd ff:ff:ff:ff:ff:ff
4: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 6e:a4:7a:5b:25:d4 brd ff:ff:ff:ff:ff:ff
두 interface가 pair로 맺어져 있다는 것은 ethtool을 이용하여 확인할 수 있다.
root@~~# ethtool -S veth0
NIC statistics:
peer_ifindex: 3
veth0 interface가 peer_ifindex 가 3으로 설정되어 있다. 이는 ip link list 로 확인했을때 veth1의 index임을 알 수 있다.
즉, 두 interface가 pair로 설정되어 있다는 의미이다.
3: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 02:86:c2:3c:82:0c brd ff:ff:ff:ff:ff:ff
이제 veth1 interface를 아까 생성한 song_ns namespace에 할당해 보자.
root@~~# ip link set veth1 netns song_ns
이제 ip link list를 확인해 보면?
root@~~# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:8e:40:2d brd ff:ff:ff:ff:ff:ff
4: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 6e:a4:7a:5b:25:d4 brd ff:ff:ff:ff:ff:ff
veth1이 보이지 않을 것이다. song_ns 내부에 할당되어 격리되었기 때문이다.
ip netns exec 를 이용하여 song_ns 내부의 interface 정보를 보자.
root@~~# ip netns exec song_ns ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 02:86:c2:3c:82:0c brd ff:ff:ff:ff:ff:ff
veth1이 song_ns 내부에 할당된 것을 확인할 수 있다.
이제 실제 통신 되는것을 확인해 보기 위해 veth0과 veth1 모두 interface 를 up 하고, IP도 할당해 보자.
IP는 veth0은 172.21.0.1/24 veth1은 172.21.0.2/24 로 설정하였다.
root@~~# ip link set veth0 up
root@~~# ip link add 172.21.0.1/24 dev veth0
root@~~#
root@~~# ip netns exec song_ns ip link set veth1 up
root@~~# ip netns exec song_ns ip link add 172.21.0.1/24 dev veth1
두 interface모두 ip가 잘 설정되었는지 확인해 보자.
확인은 ip address show 로 해보자. 물론 ifconfig로 해도 된다.
root@~~# ip address show veth0
4: veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 6e:a4:7a:5b:25:d4 brd ff:ff:ff:ff:ff:ff
inet 172.21.0.1/24 scope global veth0
valid_lft forever preferred_lft forever
root@~~# ip netns exec song_ns ip address show veth1
3: veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:86:c2:3c:82:0c brd ff:ff:ff:ff:ff:ff
inet 172.21.0.2/24 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::86:c2ff:fe3c:820c/64 scope link
valid_lft forever preferred_lft forever
위와같이 잘 설정되어 있는것을 볼 수 있다.
ping 명령어를 이용하여 namespace 내부로 통신이 되는지 확인해 보자.
song_ns에 할당한 veth1의 IP가 172.21.0.2 이므로 여기로 ping을 쏴보자.
root@~~# ping 172.21.0.2
PING 172.21.0.2 (172.21.0.2) 56(84) bytes of data.
64 bytes from 172.21.0.2: icmp_seq=1 ttl=64 time=0.025 ms
64 bytes from 172.21.0.2: icmp_seq=2 ttl=64 time=0.025 ms
64 bytes from 172.21.0.2: icmp_seq=3 ttl=64 time=0.021 ms
반대로 namespace 내부에서 외부 host로 ping 을 확인해 봐도 결과는 동일하다.
root@~~# ip netns exec song_ns ping 172.21.0.1
PING 172.21.0.1 (172.21.0.1) 56(84) bytes of data.
64 bytes from 172.21.0.1: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 172.21.0.1: icmp_seq=2 ttl=64 time=0.021 ms
64 bytes from 172.21.0.1: icmp_seq=3 ttl=64 time=0.020 ms
64 bytes from 172.21.0.1: icmp_seq=4 ttl=64 time=0.021 ms
64 bytes from 172.21.0.1: icmp_seq=5 ttl=64 time=0.024 ms
위에서 확인한 namespace 와 veth pair 방식은 docker container에서 사용하는 방식과 동일하다.
아래는 docker container의 network 구조에 대한 내용이니 참고
Docker Network 구조(1) - docker0와 container network 구조
- 참고 : https://blog.yadutaf.fr/2014/01/19/introduction-to-linux-namespaces-part-5-net/
'IT > Linux' 카테고리의 다른 글
Linux namespace - NS (File System) (0) | 2016.05.04 |
---|---|
Linux namespace - PID (1) | 2015.07.14 |
Linux namespace - IPC (0) | 2015.07.13 |
Linux namespace - UTS (2) | 2015.07.03 |
Linux namespace (0) | 2015.07.02 |