ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Docker] Docker Container 와 PID Namespace 알아보기
    Docker 2024. 6. 21. 07:24
    반응형

    - 목차

     

    들어가며.

    Docker Container 는 내부적으로 Linux Namespace 를 통한 Isolation 이 적용됩니다.

    그래서 Docker Container 는 Host 관점에서 볼 때에 하나의 Linux Process 에 지나지 않습니다.

    예를 들어, 아래와 같이 3개의 Docker Container 들이 존재하는 상황에서 ps 명령어를 통해 실행 중인 Process 를 확인해봅니다.

     

    docker ps
    CONTAINER ID   IMAGE     COMMAND            CREATED       STATUS       PORTS     NAMES
    fb9170705bfa   busybox   "sleep 10000000"   3 hours ago   Up 3 hours             strange_bhaskara
    6e25e21b0f7f   busybox   "sleep 100000"     4 hours ago   Up 4 hours             quizzical_austin
    5e40782136df   busybox   "sleep 100000"     4 hours ago   Up 4 hours             agitated_cannon
    ps aux
    PID   USER     TIME  COMMAND
        1 root      0:01 docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376
       56 root      0:06 dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --
       68 root      0:20 containerd --config /var/run/docker/containerd/containerd.toml
      424 root      0:01 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 5e40782136dfcb23bdc8ee9c
      445 root      0:00 sleep 100000
      496 root      0:01 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 6e25e21b0f7ff1306bd2d7d4
      515 root      0:00 sleep 100000
      573 root      0:00 sh
      630 root      0:00 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id fb9170705bfad18512aff16b
      649 root      0:00 sleep 10000000
      845 root      0:00 ps aux

     

    위 출력 결과는 docker ps 와 ps aux 의 출력 결과입니다.

    docker ps 는 3개의 Running Container 들을 출력합니다.

    그리고 ps aux 또한 실행 중인 Linux Process 들을 출력합니다.

    실행 중인 Linux Process 들은 dockerd, containerd, containerd-shim 등이 Docker 와 관련된 기본 Process 들이 존재하구요.

    Docker Container 의 Command 로 사용된 sleep 프로세스들 또한 확인됩니다.

    즉, Host 의 관점에서 Docker Container 는 하나의 Linux process 에 지나지 않습니다.

     

    다만 중요한 점은 Docker Container 로 인해서 실행되는 프로세스들은 리눅스 네임스페이스에 의해서 격리됩니다.

    그 중에서 PID Namespace 에 대한 격리와 여러가지 개념들을 이번 글에서 확인하려고 합니다.

     

    PID Namespace 란 ?

    아래의 링크는 unshare 명령어를 활용해서 PID Namespace 를 설정하는 방법에 대해서 설명합니다.

    https://westlife0615.tistory.com/910

     

    [Linux] unshare 과 PID Namespace 격리 알아보기

    - 목차 들어가며.이번 글에서는 Docker 와 같은 Container 가상화 기술의 근간이 되는 PID Namespace 에 대해서 알아봅니다.PID Namespace 격리는 unshare 명령어를 통해서 구현할 수 있습니다.기본적으로 Root L

    westlife0615.tistory.com

     

    아래의 도커 컨테이너 명령어를 통해서 3개의 도커 컨테이너를 실행합니다.

    docker run -d busybox sleep 100000

     

    그리고 ps aux 명령어를 통해 실행 중인 리눅스 프로세스를 확인할 수 있습니다.

    저의 경우에는 445, 515, 649 PID 를 가지는 리눅스 프로세스가 도커 컨테이너의 Command 를 실행하고 있습니다.

    ps aux
    PID   USER     TIME  COMMAND
        1 root      0:01 docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376
       56 root      0:07 dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --
       68 root      0:21 containerd --config /var/run/docker/containerd/containerd.toml
      424 root      0:01 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 5e40782136dfcb23bdc8ee9c
      445 root      0:00 sleep 100000
      496 root      0:01 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id 6e25e21b0f7ff1306bd2d7d4
      515 root      0:00 sleep 100000
      573 root      0:00 sh
      630 root      0:00 /usr/local/bin/containerd-shim-runc-v2 -namespace moby -id fb9170705bfad18512aff16b
      649 root      0:00 sleep 10000000
      846 root      0:00 ps aux

     

    그럼 각각의 PID Namespace 를 확인해볼까요 ?

    PID Namespace 는 /proc/*/ns/pid 파일에서 확인할 수 있습니다.

    /proc 디렉토리는 Process 와 관련된 파일시스템이 마운트된 특별한 디렉토리입니다.

    이는 커널에서 관리되며, /proc 디렉토리 하위에서 실행 중인 프로세스의 상세한 정보를 확인할 수 있습니다.

     

    그 중에서 각 Process 의 PID Namespace 를 확인하는 방법은 아래와 같습니다.

    각 프로세스의 PID Namespace 의 정보가 출력됩니다.

    주목할 점은 445, 515, 649 PID 를 제외한 나머지 프로세스들은 4026532563 에 해당하는 동일한 PID Namespace 를 사용합니다.

    반면, 445, 515, 649 프로세스는 별도의 PID Namespace 를 사용합니다.

     

    ls -l /proc/*/ns/pid
    /proc/1/ns/pid -> pid:[4026532563]
    /proc/424/ns/pid -> pid:[4026532563]
    /proc/445/ns/pid -> pid:[4026532701]
    /proc/496/ns/pid -> pid:[4026532563]
    /proc/515/ns/pid -> pid:[4026532836]
    /proc/56/ns/pid -> pid:[4026532563]
    /proc/573/ns/pid -> pid:[4026532563]
    /proc/630/ns/pid -> pid:[4026532563]
    /proc/649/ns/pid -> pid:[4026532969]
    /proc/68/ns/pid -> pid:[4026532563]
    /proc/self/ns/pid -> pid:[4026532563]
    /proc/thread-self/ns/pid -> pid:[4026532563]

     

    Host 와 Container 의 PID Namespace 의 관계.

    Host 와 Container 는 서로 다른 PID Namespace 를 사용하지만,

    Host 입장에서는 Container 와 관련된 리눅스 프로세스는 모드 노출됩니다.

    그 이유는 PID Namespace 는 부모-자식의 수직적인 계층 구조를 가지기 때문입니다.

    하지만 Container 의 입장에서는 부모 PID Namespace 의 리눅스 프로세스들을 확인할 수 없습니다.

     

    아래의 nsenter 명령어는 특정 Process 의 Isolation 공간으로 진입할 수 있는 명령어입니다.

    즉, 아래의 명령어는 445 PID 의 Process 가 사용하는 PID Namespace 에 진입할 수 있는 명령어입니다.

    그리고 그 출력 결과는 아래와 같이 자기 자신의 Process 만이 출력되게 됩니다.

     

    nsenter -t 445 --pid --mount ps aux
    nsenter -t 445 --pid --mount ps aux
    PID   USER     TIME  COMMAND
        1 root      0:00 sleep 100000
       10 root      0:00 ps aux

     

     

    또 주목할 점은 sleep 프로세스가 1번인 Root Process 로 실행됩니다.

    따라서 1번 프로세스인 sleep 프로세스가 종료되면 관련된 PID Namespace 또한 종료됩니다.

     

     

    반응형
Designed by Tistory.