본문 바로가기

docker

container가 생성되는 과정 (1) - computing resource

Host와 (논리적으로) 분리된 환경에서 동작하는 container는 복잡한 과정을 거쳐서 생성된다. 
어떻게 가능한 것일까? 실제로 물리적인 서버에서 동작하는 process이면서, 별도의 resource를 가지고 network 환경까지도 분리하여 동작이 가능한 것인가..!? (마치 다른 서버에서 동작하는 것 처럼!?)

나와 비슷한 궁금증을 갖고 있는 분들에게 이번 게시물이 도움이 되길 바란다.

linux namespace?

linux에서 namespace는 프로세스를 실행할 때, 시스템의 resource를 분리해서 사용할 수 있도록 도와주는 기능이다.
일반적으로 linux에서 process를 실행할 때, 부모 process인 pid 1가 속해있는 namespace와 같은 namespace에서 동작을 하는데, 이를 분리하여 독립된 resource를 제공하도록 하는데 도움을 준다.

# ls -al /proc/1/ns/
total 0
dr-x--x--x 2 root root 0 Nov 22 06:44 .
dr-xr-xr-x 9 root root 0 Nov 22 06:29 ..
lrwxrwxrwx 1 root root 0 Nov 22 06:44 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 net -> net:[4026532088]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 pid_for_children -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 time -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 time_for_children -> time:[4026531834]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Nov 22 06:44 uts -> uts:[4026531838]

 위 내용은 pid 1의 namespace를 조회한 결과인데, cgroup, ipc, mnt, net, ...과 같이 resource별 namespace가 별도로 구성되어 있는것을 확인할 수 있다.
(이번 게시물에서는 cgroup의 namespace를 활용한다 )

docker container 생성 및 cgroup 확인

우선 간단한 container를 동작시켜보자.

# docker run -it -d --cpu-shares=512 --memory=512 ubuntu:16.04 -- /bin/bash

위 명령어는 cpu-share 512m, memory 512MB를 할당받은 ubuntu container를 생성하고 init process로 /bin/bash를 실행한다.

container가 동작하고 있는 host server위에서 아래와 같이 해당 process를 조회하면 pid를 확인할 수 있는데, 해당 정보를 이용하여 실제 container에 cpu/memory가 얼만큼 할당되었는지 확인할 수 있다.

# ps -ef | grep bin/bash
root      4796  4774  0 06:42 pts/0    00:00:00 /bin/bash

### pid 1(host)의 cgroup 결과
# cat /proc/1/cgroup 
11:hugetlb:/
10:blkio:/
9:net_cls,net_prio:/
8:cpuset:/
7:freezer:/
6:pids:/
5:memory:/
4:devices:/
3:cpu,cpuacct:/
2:perf_event:/
1:name=systemd:/

### pid 4796(container)의 cgroup 조회 결과
# cat /proc/4796/cgroup 
11:hugetlb:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
10:blkio:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
9:net_cls,net_prio:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c
6eb108
8:cpuset:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
7:freezer:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
6:pids:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
5:memory:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
4:devices:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
3:cpu,cpuacct:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb10
8
2:perf_event:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb108
1:name=systemd:/docker/4be72c590c2a7c604136255add642364b97d2a4c0ddb09ed2f809fb88c6eb1
08

host와 container의 cgroup 조회 결과가 차이가 있음을 한 눈에 알 수 있다. 실제 값이 매핑된 경로가 나와있으며 4be...는 container id이다.

cgroups?
(control groups의 약자)는 프로세스들의 자원의 사용(CPU, 메모리, 디스크 입출력, 네트워크 등)을 제한하고 격리시키는 리눅스 커널 기능이다.

위 경로에 실제로 해당 cgroup에 docker run 명령어 입력당시 할당했던 resource가 정의되어 있음을 확인할 수 있다.

### cpu 확인
# cat /sys/fs/cgroup/cpu/docker/4be72c590c2a7c604136255add642
364b97d2a4c0ddb09ed2f809fb88c6eb108/cpu.shares 
512

### memory 확인
# cat /sys/fs/cgroup/memory/docker/4be72c590c2a7c604136255add
642364b97d2a4c0ddb09ed2f809fb88c6eb108/memory.limit_in_bytes 
536870912

 

위와 같은 설정으로 인해 kernel에서 분리된 resource 운영을 할 수 있게된다.

반응형

'docker' 카테고리의 다른 글

container가 생성되는 과정 (3) - network  (0) 2021.11.25
container가 생성되는 과정 (2) - file system  (0) 2021.11.24
set -e 와 exec "$@"  (0) 2021.07.19