일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- AWS
- 후기
- 재테크
- clone
- 토스카드
- 커피머니불리기
- VPC
- 앱테크
- MongoDB
- 리뷰
- built-in
- Container
- namespace
- 하나머니
- Linux
- S3
- MongoEngine
- DocumentDB
- codecommit
- docker network
- mininet
- docker
- 도커
- aws codecommit
- python3
- 리워드앱
- network
- 포인트앱
- 실사용
- Python
- Today
- Total
ㅍㅍㅋㄷ
Linux namespace - NS (File System) 본문
NS (File system) namespace
[Contents]
5. Linux namespace - NS(File System)
최근 lightweight 한 가상화 플랫폼인 Docker나 Linux container LXC 가 주목을 받고 있는데, 여기에 사용된 기반 기술 중 하나로 namespace 라는 것이 있다. namespace 에 대한 설명은 이전 포스팅 참고 ( Linux namespace )
namespace 는 크게 6가지로 분류되는데, 이번 포스팅에는 NS 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를 분할 격리
지난 포스팅에서 PID namespace를 이용하여 Process Tree의 최상단인 PID 1을 새롭게 생성하여 분기 시켜보았다. ( 지난 포스팅 참고 : Linux namespace - PID )
하지만, ps 명령어로 프로세스를 확인해 보면, 자신의 관리 영역 외에도 존재하는 모든 process 리스트가 보였다. 이것은 Process를 기록하고 관리하는 filesystem 영역인 /proc 은 아직 공유하고 있었기 때문이다. filesystem 격리는 NS namespace 를 통해 구현해 보자
Clone을 이용한 NS namespace 구성 방법
NS namespace를 생성하는 방법도 지금까지 했던 방식과 동일하다. clone() 생성시 flag로 CLONE_NEWNS 만 추가해 주면 된다.
int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWNS | SIGCHLD, NULL);
지난 포스팅에서 했던 소스 코드에서 CLONE_NEWNS flag만 추가해 보자.
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];
char* const child_args[] = {
"/bin/bash",
NULL
};
int child_main(void* arg)
{
printf(" - [%4d] Current namspace, Parent PID : %d\n", getpid(), getppid() );
sethostname("namespace", 12);
execv(child_args[0], child_args);
return 1;
}
int main()
{
printf(" - [%4d] New namespace, Parent PID : %d\n", getpid(), getppid() );
int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
waitpid(child_pid, NULL, 0);
return 0;
}
실행해 보면 결과는 이전과 다르지 않다.
root@~~# ./newns
- [1225] Current namespace, Parent PID : 1228
- [ 1] New namespace, Parent PID : 0
root@namespace:~#
눈에 보이진 않지만, 현재 새롭게 생성된 namespace는 file system 또한 격리화 되어 관리되고 있는 상태이다.
이제 process 리스트가 관리 되는 proc file system 을 새롭게 mount 해보자.
일단, proc file system을 새롭게 mount 할 디렉토리를 생성한다.
root@namespace:~# mkdir -p /tmp/proc
proc file system을 새롭게 mount 한다.
root@namespace:~# mount -t proc /tmp/proc /proc
mount 명령어로 확인해 보면, 아래와 같이 proc type의 file system이 새롭게 mount 되어 있는것을 볼 수 있다.
root@namespace:~# mount
/dev/vda2 on / type ext4 (rw,nodev,noatime)
... (중략)
/root/proc on /proc type proc (rw)
이제 ps 명령어로 process 리스트를 확인해 보자.
root@namespace:~# ps -aef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 18:34 pts/0 00:00:00 /bin/bash
root 16 1 0 18:41 pts/0 00:00:00 ps -aef
root@namespace:~# pstree -p
bash(1)───pstree(17)
위와 같이 현재 자신이 속한 namespace의 process 만 확인이 가능하다. 마치 docker를 사용할때와 같은 느낌적인 느낌.
새롭게 터미널을 열어 namespace 가 아닌 기존 환경으로 접속하여 ps 명령어를 치면, 기존 process 리스트를 확인할 수 있다.
만약, 예제를 실행시키자 마자 바로 proc 을 mount 하려면 아래와 같이 추가하면 된다.
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mount.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];
char* const child_args[] = {
"/bin/bash",
NULL
};
int child_main(void* arg)
{
printf(" - [%4d] Current namspace, Parent PID : %d\n", getpid(), getppid() );
sethostname("namespace", 12);
mount("/root/proc", "/proc", "proc", 0, NULL);
execv(child_args[0], child_args);
return 1;
}
int main()
{
printf(" - [%4d] New namespace, Parent PID : %d\n", getpid(), getppid() );
int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
waitpid(child_pid, NULL, 0);
return 0;
}
mount 함수에 대한 설명은 여길 참고 : http://man7.org/linux/man-pages/man2/mount.2.html
[참고]
- https://blog.yadutaf.fr/2014/01/12/introduction-to-linux-namespaces-part-4-ns-fs/
'IT > Linux' 카테고리의 다른 글
Linux namespace - NET (4) | 2016.05.10 |
---|---|
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 |