컨테이너 내부원리

hyuckhoon.ko·2024년 2월 16일
0

네임스페이스

프로세스끼리 시스템 자원 충돌을 막는 것은 중요하다.
웹서버에서, 컨테이너 하나만 실행시키는 건 토이프로젝트에서나 가능하다.
운영환경에서는 여러 웹서버 컨테이너들이 실행된다.

웹서버의 기본 포트 번호는 80.
컨테이너를 이용하게 되면 여러 컨테이너가 동시에 80포트를 사용할 수있다.

반면, 일반적인 프로세스에서는 포트 번호는 중복될 수 없다.

네트워크적, UID, Mount, UTS, IPC, PID 등 여러 네임스페이스들이 있다.
(그 중 PID, 네트워크, 마운트가 특히 중요하다.)

PID namespace

프로세스에 할당되는 고유한 ID

  • 새롭게 pid 1번부터 진행

Network namespace

네트워크 디바이스, 포트번호, IP 주소 등

UID namespace

UID와 GID를 독립적으로 가질 수 있게 한다.

Mount namespace

mount(장치와 폴더의 연결)에 대하여 독립된 파일시스템 트리를 관리

UTS namespace

호스트명, 도메인명을 독자적으로 가져간다.

IPC namespace

프로세스간 통신(IPC)에 대해서 namespace별 독립화

실습

프로세스와 컨테이너가 어떤 차이가 있을까?
namespace 실습을 통해 하나하나 확인해보자.

방법 1. lsns 명령어 활용

1) 도커 컨테이너 실행

reallinux@ubuntu:~$ docker run -it -d ubuntu:16.04
b7456d853038a716ef3ef95c82af2358f380c8aceef88dda74b3a7bcdcf64d56
reallinux@ubuntu:~$ docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS         PORTS     NAMES
b7456d853038   ubuntu:16.04   "/bin/bash"   16 seconds ago   Up 3 seconds             nostalgic_murdock

2) 사용 중인 bash의 프로세스 ID를 확인하기

호스트 서버에서 아래 명령어를 입력하여 bash 프로그램의 PID 확인

reallinux@ubuntu:~$ echo $$
1937
reallinux@ubuntu:~$ ps -ef | grep 1937
reallin+  1937  1936  0 11:43 pts/0    00:00:00 -bash
reallin+  2089  1937  0 11:52 pts/0    00:00:00 ps -ef
reallin+  2090  1937  0 11:52 pts/0    00:00:00 grep --color=auto 1937

3) 컨테이너의 PID 정보 확인하기

reallinux@ubuntu:~$ docker inspect b7456d853038 | grep Pid
            "Pid": 2040,
            "PidMode": "",
            "PidsLimit": null,

컨테이너의 PID는 2040이다.

우리는 컨테이너도 프로세스라고 배웠다.
호스트 서버에서 해당 프로세스를 찾아보자.

reallinux@ubuntu:~$ ps -ef | grep 2040
root      2040  2019  0 11:51 pts/0    00:00:00 /bin/bash
reallin+  2107  1937  0 11:54 pts/0    00:00:00 grep --color=auto 2040

하지만 ps -ef 명령어만으론
PID 2040의 프로세스가 컨테이너인지 아닌지 알 수없다.

lsns 명령어로 프로세스의 namespace를 들여다 본다면 구분이 가능하다.
: lists information about the accessible namespaces or a specific namespace

# 도커 컨테이너 프로세스의 namespace
reallinux@ubuntu:~$ sudo lsns -p 2040
[sudo] password for reallinux: 
        NS TYPE   NPROCS   PID USER COMMAND
4026531835 cgroup    126     1 root /sbin/init maybe-ubiquity
4026531837 user      126     1 root /sbin/init maybe-ubiquity
4026532191 mnt         1  2040 root /bin/bash
4026532192 uts         1  2040 root /bin/bash
4026532193 ipc         1  2040 root /bin/bash
4026532194 pid         1  2040 root /bin/bash
4026532196 net         1  2040 root /bin/bash

(+ Q. 근데 sudo 없이 하면 왜 다른 결과가 나오지?!)

주목할 점은 프로세스1번의 좌측 네임스페이스 ID와 bash 프로세스의 그것이 일치한다는 것이다.

# bash 프로세스의 namespace
reallinux@ubuntu:~$ sudo lsns -p 1937
        NS TYPE   NPROCS PID USER COMMAND
4026531835 cgroup    128   1 root /sbin/init maybe-ubiquity
4026531836 pid       127   1 root /sbin/init maybe-ubiquity
4026531837 user      128   1 root /sbin/init maybe-ubiquity
4026531838 uts       127   1 root /sbin/init maybe-ubiquity
4026531839 ipc       127   1 root /sbin/init maybe-ubiquity
4026531840 mnt       122   1 root /sbin/init maybe-ubiquity
4026531992 net       127   1 root /sbin/init maybe-ubiquity

# PID 1번의 namespace
reallinux@ubuntu:~$ sudo lsns -p 1
        NS TYPE   NPROCS PID USER COMMAND
4026531835 cgroup    128   1 root /sbin/init maybe-ubiquity
4026531836 pid       127   1 root /sbin/init maybe-ubiquity
4026531837 user      128   1 root /sbin/init maybe-ubiquity
4026531838 uts       127   1 root /sbin/init maybe-ubiquity
4026531839 ipc       127   1 root /sbin/init maybe-ubiquity
4026531840 mnt       122   1 root /sbin/init maybe-ubiquity
4026531992 net       127   1 root /sbin/init maybe-ubiquity

기본적으로 모든 프로세스들은 PID 1인 /sbin/init 프로세스의 namespace를 상속받는다.
그래서 1번 프로세스와 bash 프로그램의 namespace는 일치하는 것이다.

하지만 (격리된, 독립된 환경의) 컨테이너는 namespace가 다름을 확인할 수있다.

이상 lsns 명령어로 프로세스와 컨테이너를 구별하는 방법을 살펴봤다.

방법 2. ll /proc/{PID}ns

reallinux@ubuntu:~$ sudo su
root@ubuntu:/home/reallinux# ll /proc/1/ns

# PID 1
total 0
dr-x--x--x 2 root root 0 Feb 16 11:57 ./
dr-xr-xr-x 9 root root 0 Feb 16 11:41 ../
lrwxrwxrwx 1 root root 0 Feb 16 11:57 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 12:21 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 uts -> 'uts:[4026531838]'

# 컨테이너
root@ubuntu:/home/reallinux# ll /proc/2040/ns
total 0
dr-x--x--x 2 root root 0 Feb 16 11:51 ./
dr-xr-xr-x 9 root root 0 Feb 16 11:51 ../
lrwxrwxrwx 1 root root 0 Feb 16 11:57 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 ipc -> 'ipc:[4026532193]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 mnt -> 'mnt:[4026532191]'
lrwxrwxrwx 1 root root 0 Feb 16 11:51 net -> 'net:[4026532196]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 pid -> 'pid:[4026532194]'
lrwxrwxrwx 1 root root 0 Feb 16 12:21 pid_for_children -> 'pid:[4026532194]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Feb 16 11:57 uts -> 'uts:[4026532192]'

# 현재 실행중인 bash
root@ubuntu:/home/reallinux# echo $$
2276
root@ubuntu:/home/reallinux# ll /proc/2276/ns
total 0
dr-x--x--x 2 root root 0 Feb 16 12:22 ./
dr-xr-xr-x 9 root root 0 Feb 16 12:22 ../
lrwxrwxrwx 1 root root 0 Feb 16 12:22 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Feb 16 12:22 uts -> 'uts:[4026531838]'
root@ubuntu:/home/reallinux# 

ll /proc/{PID}/ns 명령어를 통해서도 프로세스와 컨테이너는 서로 다른 namespace를 갖고 있음을 확인할 수 있다.

이번엔 도커를 사용하지 말고 다른 방식으로 접근해보자.
직접 격리된 환경을 구축한 프로세스에서도 위의 결과와 동일할까?

방법 3. (도커를 사용하지 않고) unshare 명령어로 생성한 프로세스에서도 여전히 namespace는 다를까?

1) unshare 명령어로 독립된 프로세스 직접 생성

# 지난 시간 다운로드했던 rootfs 활용
reallinux@ubuntu:~$ unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash
root@ubuntu:/# 
root@ubuntu:/# mount -t proc proc /proc
root@ubuntu:/# ps -ef 
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 12:38 ?        00:00:00 /bin/bash
root         5     1  0 12:40 ?        00:00:00 ps -ef

수동으로 만든 컨테이너 내부 프로세스 ID는 역시나 1이다.

root@ubuntu:/# echo $$
1

(Q. 이 부분 다시 수정 필요)

root         5     1  0 12:40 ?        00:00:00 ps -ef
root@ubuntu:/# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

2) lsns 명령어로 namespace 비교

이제 새로운 터미널 창에서 아래 명령어를 실행한다.

reallinux@ubuntu:~$ pidof unshare
2498

reallinux@ubuntu:~$ sudo lsns -p 2498
[sudo] password for reallinux: 
        NS TYPE   NPROCS   PID USER      COMMAND
4026531835 cgroup    134     1 root      /sbin/init maybe-ubiquity
4026531836 pid       132     1 root      /sbin/init maybe-ubiquity
4026532250 user        2  2498 reallinux unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash
4026532251 mnt         2  2498 reallinux unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash
4026532252 uts         2  2498 reallinux unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash
4026532253 ipc         2  2498 reallinux unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash
4026532256 net         2  2498 reallinux unshare --mount --uts --ipc --net --pid --fork --user --map-root-user chroot rootfs /bin/bash

reallinux@ubuntu:~$ sudo lsns -p 1
        NS TYPE   NPROCS PID USER COMMAND
4026531835 cgroup    134   1 root /sbin/init maybe-ubiquity
4026531836 pid       132   1 root /sbin/init maybe-ubiquity
4026531837 user      132   1 root /sbin/init maybe-ubiquity
4026531838 uts       131   1 root /sbin/init maybe-ubiquity
4026531839 ipc       131   1 root /sbin/init maybe-ubiquity
4026531840 mnt       126   1 root /sbin/init maybe-ubiquity
4026531992 net       131   1 root /sbin/init maybe-ubiquity

pidof unshare 명령어로 수동으로 생성한 프로세스의 PID를 얻었다.
도커에서의 비교 결과와 동일하다.

직접 격리시킨 프로세스의 namespace와 프로세스 1번의 namespace는 분명 다르다.

마찬가지로 ll /proc/{PID}/ns 명령어도 적용해보자.

reallinux@ubuntu:~$ sudo su
root@ubuntu:/home/reallinux# ll /proc/2498/ns
total 0
dr-x--x--x 2 reallinux reallinux 0 Feb 16 12:46 ./
dr-xr-xr-x 9 reallinux reallinux 0 Feb 16 12:45 ../
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 ipc -> 'ipc:[4026532253]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 mnt -> 'mnt:[4026532251]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 net -> 'net:[4026532256]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:48 pid_for_children -> 'pid:[4026532254]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 user -> 'user:[4026532250]'
lrwxrwxrwx 1 reallinux reallinux 0 Feb 16 12:46 uts -> 'uts:[4026532252]'
root@ubuntu:/home/reallinux# ll /proc/1/ns
total 0
dr-x--x--x 2 root root 0 Feb 16 12:46 ./
dr-xr-xr-x 9 root root 0 Feb 16 11:41 ../
lrwxrwxrwx 1 root root 0 Feb 16 12:46 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 12:48 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Feb 16 12:46 uts -> 'uts:[4026531838]'

마찬가지로 unshare명령어로 만든 프로세스 역시 일반적인 프로세스와는 다른 namespace를 갖는다.

방법 3. nsenter 명령어

reallinux@ubuntu:~$ whatis nsenter
nsenter (1)          - run program with namespaces of other processes
# unshare로 만든 프로세스의 ip 주소
reallinux@ubuntu:~$ pidof unshare
2498

# 일반 프로세스의 ip 주소
reallinux@ubuntu:~$ sudo nsenter -t 2498 -n ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
reallinux@ubuntu:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:6c:2f:72 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 82272sec preferred_lft 82272sec
    inet6 fe80::a00:27ff:fe6c:2f72/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:53:2e:49:5a brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:53ff:fe2e:495a/64 scope link 
       valid_lft forever preferred_lft forever
5: vethd7c91c8@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 36:a7:02:4f:0f:cb brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::34a7:2ff:fe4f:fcb/64 scope link 
       valid_lft forever preferred_lft forever
reallinux@ubuntu:~$ 
# 도커 컨테이너의 ip 주소
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

nsenter 명령어

nsenter 명령어로 임의의 프로세스의 namespace가 그대로 적용된 프로세스를 만들고 명령어를 실행시켜 보려고 한다.

도커로도 exec 명령어로 충분히 할 수 있다.
하지만 여기에 비밀이 숨겨져 있다.
내부적으로는 이러한 방식과 명령어를 통해 프로세스를 운용하는 것이다.
즉, 도커는 컨테이너 생성/관리/운영을 편리하게 해주는 단순한 도구에 불과하다.

도커 프로세스 ID인 2040의 namespace를 그대로 상속받는 프로세스를 생성하고 임의의 명령어를 실행시켜보자.

1) ps -ef 명령어 실행시키기

reallinux@ubuntu:~$ sudo nsenter -t 2040 -p -r ps -ef 
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 11:51 pts/0    00:00:00 /bin/bash
root        11     0 28 12:55 ?        00:00:00 ps -ef

2) top 명령어 실행시키기

# 2040 namespace 활용하여 top 명령어 실행
reallinux@ubuntu:~$ sudo nsenter -t 2040 -p -r top

top - 12:56:23 up  1:14,  0 users,  load average: 1.18, 1.08, 1.19
Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  1.4 sy, 15.3 ni, 83.1 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2034848 total,    86264 free,   166092 used,  1782492 buff/cache
KiB Swap:  2094076 total,  2093552 free,      524 used.  1626348 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                           
    1 root      20   0   18228   3144   2728 S   0.0  0.2   0:00.90 bash                                                              
   12 root      20   0   36652   3124   2680 R   0.0  0.2   0:00.05 top  
   
# 일반 프로세스 top 명령어 실행
reallinux@ubuntu:~$ top

top - 12:57:05 up  1:15,  2 users,  load average: 1.13, 1.08, 1.18
Tasks: 129 total,   4 running,  71 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.5 us,  1.3 sy,  4.8 ni, 92.8 id,  0.2 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem :  2034848 total,    85696 free,   221496 used,  1727656 buff/cache
KiB Swap:  2094076 total,  2093552 free,      524 used.  1625956 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                           
 1789 root      39  19  204428 100684  60760 R  99.1  4.9  74:11.51 unattended-upgr                                                   
 2658 reallin+  20   0   42792   4084   3468 R   2.9  0.2   0:00.38 top                                                               
 2627 root      20   0       0      0      0 I   1.7  0.0   0:00.94 kworker/u8:2-ev                                                   
 2467 root      20   0       0      0      0 I   0.9  0.0   0:06.71 kworker/u8:5-ev                                                   
   99 root      20   0       0      0      0 I   0.7  0.0   0:14.61 kworker/u8:1-ev                                                   
  918 root      20   0  110408   2088   1868 S   0.7  0.1   0:01.72 irqbalance                                                        
  926 root      20   0 1437148  44464  32436 S   0.6  2.2   0:12.51 containerd                                                        
 2492 root      20   0       0      0      0 I   0.2  0.0   0:02.31 kworker/2:0-mm_                                                   
    1 root      20   0  159496   8836   6652 S   0.0  0.4   0:11.00 systemd                                                           
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.02 kthreadd                                                          
    3 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 rcu_gp                                                            
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 rcu_par_gp                                                        
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H                                                      
    7 root      20   0       0      0      0 I   0.0  0.0   0:01.15 kworker/0:1-cgr                                                   
    9 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq                                                      
   10 root      20   0       0      0      0 S   0.0  0.0   0:00.37 ksoftirqd/0                                                       
   11 root      20   0       0      0      0 R   0.0  0.0   0:02.84 rcu_sched                                                         
   12 root      rt   0       0      0      0 S   0.0  0.0   0:00.25 migration/0                                                       
   13 root     -51   0       0      0      0 S   0.0  0.0   0:00.00 idle_inject/0                                                     
   14 root      20   0       0      0      0 S   0.0  0.0   0:00.00 cpuhp/0                                                           
   15 root      20   0       0      0      0 S   0.0  0.0   0:00.00 cpuhp/1                                                           
   16 root     -51   0       0      0      0 S   0.0  0.0   0:00.00 idle_inject/1                                                     
   17 root      rt   0       0      0      0 S   0.0  0.0   0:00.49 migration/1                                                       
   18 root      20   0       0      0      0 S   0.0  0.0   0:00.59 ksoftirqd/1                                                       
   20 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/1:0H                                                      
   21 root      20   0       0      0      0 S   0.0  0.0   0:00.00 cpuhp/2    

프로세스와 컨테이너는 서로 다른 프로세스다.
따라서, 상태를 보여주는 top 명령어 실행 결과도 다를 수밖에 없다.

3) hostname 명령어 실행시키기

# 2040 namespace 활용하여 top 명령어 실행
reallinux@ubuntu:~$ sudo nsenter -t 2040 -p -u hostname
b7456d853038

# 호스트에서 실행
reallinux@ubuntu:~$ hostname
ubuntu

reallinux@ubuntu:~$ docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED             STATUS             PORTS     NAMES
b7456d853038   ubuntu:16.04   "/bin/bash"   About an hour ago   Up About an hour             nostalgic_murdock

2040은 도커 컨테이너의 프로세스 ID였다.
2040 프로세스의 namespace를 그대로 적용하여 hostname 명령어를 새롭게 실행시켰고, 도커 컨테이너 ID와 일치하고 있다.

도커 컨테이너의 hostname은 도커 컨테이너의 ID임을 알 수 있다.

4) docker exec -it /bin/bash 구현하기

reallinux@ubuntu:~$ sudo nsenter -t 2040 -p -a
[sudo] password for reallinux: 
root@b7456d853038:/# 

호스트 이름 root@b7456d853038이 보인다.
도커 컨테이너 ID와 동일한 값이다.
즉, 같은 namespace를 갖는 프로세스를 하나 생성하여 /bin/bash를 실행시킨 것이다.

이 사실은 ps -ef 명령어로 확인이 가능하다.

root@b7456d853038:/# ps -ef 
UID        PID  PPID  C STIME TTY 
root         1     0  0 11:51 pts/0    00:00:00 /bin/bash
root        14     0  0 13:00 ?        00:00:00 -bash
root        17    14  0 13:02 ?        00:00:00 ps -ef

1번이 도커 컨테이너이고
14번이 동일한 namespace를 적용한 프로세스다.

0개의 댓글