본문 바로가기
Kubernetes/Management

k8s - Kubernetes container 이해 및 Kubernetes unknown container 조치

by 여행을 떠나자! 2021. 11. 7.

1. 개요

- Docker engine의 역할을 이해한다.

- Kubernetes 컨테이너 구조와 pause 컨테이너의 역할을 이해한다.

- Kubernetes에서 관리하고 있지 않는 unknown 컨테이너의 존재를 인지하고 사라지게(kill) 한다. 

 

 

2. Docker 이해

a. Docker engine (간략)

- dockerd

   containerd를 활용하여 컨테이너를 생성하고 관리하는 서비스

- containerd

   image와 컨테이너 lifecycle을 관리하는 서비스, dockerd로부터 컨테이너 생성 요청을 받고, runc를 이용하여 컨테이너를 생성함. 

- containerd-shim

   shim은 containerd와 컨텐이너 runtime 사이에서 소통을 담당

   runc가 컨테이너를 생성 후 컨테이너 runtime의 부모가 됨

   containerd가 관리상의 이유로 재기동되어도 컨테이너 runtime이 독립적으로 실행될 수 있도록 함

- runc

   runc은 namespace와 cgroup을 만들고 값을 설정 하고, 컨테이너(프로세스)를 실행 후 종료

   docker는 runtime으로 runc를 사용

https://betterprogramming.pub/docker-for-front-end-developers-c758a44e622f

 

b. Docker engine (상세)

 

https://iximiuz.com/implementing-container-runtime-shim/docker-containerd-runc-2000-opt.png

 

c. docker engine 19.x, 18.x 살펴보기

- docker engine 19.03.13

   dockerd, containerd 그리고 containerd-shim 프로세스의 계층 구조는 아래와 같다.

/usr/bin/dockerd 
/usr/bin/containerd
          \_ containerd-shim
              \_ container runtime
          \_ containerd-shim
              \_ container runtime

   아래 프로세스 중 6531, 7009등이 컨테이너 runtime이다. 

$ ps auxf
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       3255 43.1  0.6 11711168 400184 ?     Ssl  Aug09 4624:3 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=repo.chelsea.kt.co.kr:5002 --insecure-registry=nexus.kt.co.kr:10000 --insecure-registry=nexus.kt.co.kr:10001
root       2951 20.9  0.1 16945612 95760 ?      Ssl  Aug09 2268:3 /usr/bin/containerd
root       6452  0.0  0.0 110120  4676 ?        Sl   Aug09   6:42  \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/9d39436aceaf3296b39a042c51291bf2865f63b3b39a122f9c3b068327f8e58b -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       6531  0.0  0.0   1012     4 ?        Ss   Aug09   0:00  |   \_ /pause
root       6940  0.0  0.0 110120  4428 ?        Sl   Aug09   7:09  \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/0ee05e4e102052529c03cb088ed162240220c7f087f9bcfce757d9c63ec6b3fc -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root       7009  0.0  0.0  11688   204 ?        Ss   Aug09   0:00  |   \_ /bin/sh -c ln -s /lib/modules/3.10.0-1160.6.1.el7.x86_64 /lib/modules/3.10.0-1127.el7.x86_64 && nvidia-driver init
root       7152  0.0  0.0  11824   348 ?        S    Aug09   0:00  |   |   \_ /bin/bash /usr/local/bin/nvidia-driver init
root      12143  0.0  0.0   4364    76 ?        S    Aug09   0:00  |   |       \_ sleep infinity
root      12066  0.0  0.0  19220   376 ?        Ss   Aug09  29:55  |   \_ nvidia-persistenced --persistence-mode

 

- docker engine 18.06.2

   docker engine 19.x와 비교해서 일부 프로세스 명이 다르고, docker-containerd는 daemon 형태가 아닌 dockerd의 자식 프로세스이다. 

/usr/bin/dockerd 
 \_ docker-containerd 
    \_ docker-containerd-shim
    \_ docker-containerd-shim
$ ps auxf
USER     PID %CPU %MEM    VSZ   RSS TTY    STAT START   TIME COMMAND
...
root    2923 28.4  0.2 8861212 290164 ?    Ssl  15:11 109:33 /usr/bin/dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:30030 --max-concurrent-downloads 10 --insecure-registry=nexus.kt.co.kr:10000 --insecure-registry=nexus.kt.co.kr:10001
root    3181  8.7  0.0 11798356 99548 ?    Ssl  15:11  33:43  \_ docker-containerd --config /var/run/docker/containerd/containerd.toml
root    4521  0.0  0.0   8800  3932 ?      Sl   15:12   0:01      \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/61f07076e6a799ecaa39226c4ba9cb4c0d31710608ae9949aa1a28163289ed00 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root    4539  0.0  0.0   1012     4 ?      Ss   15:12   0:00      |   \_ /pause
root   34899  0.1  0.0   9952  4924 ?      Sl   15:13   0:25      \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/8cd8b569140bb69f210f140a4ee3c84c3eaf5261b6df53d9de16f58fb59d8e7b -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
1001   36319  0.0  0.0   2384   740 ?      Ss   15:13   0:00      |   \_ /bin/sh /opt/bitnami/rabbitmq/sbin/rabbitmq-server
1001   37643  3.6  0.1 12868332 198592 ?   Sl   15:13  13:48      |       \_ /opt/bitnami/erlang/lib/erlang/erts-12.1/bin/beam.smp -W w -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zdbbl 128000 -sbwt none -sbwtdcpu none -sbwtdio none -B i -- -root /opt/bitnami/erlang/lib/erlang -progname erl -- -home /opt/bitnami/rabbitmq/.rabbitmq -- -pa  -noshell -noinput -s rabbit boot -boot start_sasl -syslog logger [] -syslog syslog_error_logger false
1001   37774  0.0  0.0   2276   596 ?      Ss   15:13   0:00      |       |   \_ erl_child_setup 1048576
1001   39142  0.0  0.0   5968  2544 ?      S    15:13   0:01      |       \_ /opt/bitnami/erlang/lib/erlang/erts-12.1/bin/epmd -daemon
...

 

 

3. Kubernetes Pod와 Container 

- Pod란?

   Pod는 Kubernetes에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 단위로, 하나 이상의 컨테이너의 그룹이다.

 

- ysjeon-mariadb-0 Pod 조회

   분석에 사용될 ysjeon-mariadb-0 Pod는 iap12 노드에서 실행중이다.

   ysjeon-mariadb-0 Pod는 mariadb 컨테이너 하나를 포함하고 있다.

   mariadb 컨테이너 ID는 24505fc6375cc42c30d0c8441f2c14aac19f9f1891ef4f126ea98e10c4a68655이다.

$ k describe pod ysjeon-mariadb-0 -n yoosung-jeon
Name:         ysjeon-mariadb-0
Namespace:    yoosung-jeon
Priority:     0
Node:         iap12/14.52.244.216
...
Controlled By:  StatefulSet/ysjeon-mariadb
Containers:
  mariadb:
    Container ID:   docker://24505fc6375cc42c30d0c8441f2c14aac19f9f1891ef4f126ea98e10c4a68655
    Image:          docker.io/bitnami/mariadb:10.5.12-debian-10-r32
    Image ID:       docker-pullable://bitnami/mariadb@sha256:7f8d968150f6f1503291e4a2629335903fd3488485e5798c13f7c94710b27c12
...
$

 

- ysjeon-mariadb-0 Pod의 도커 컨테이너 찾기

   iap12 노드에서 실행 중인 ysjeon-maridb-0 Pod의 도커 컨테이너는 총 2개이다.

   첫 번째는 mariadb 컨테이너이다. Kubernetes에서 조회하였던 mariadb 컨테이너 ID의 첫 12 문자가 도커 컨테이너 ID(24505fc6375c)이다.

   두 번째는 pause 컨테이너이다. pause 컨테이너는 Pod마다 하나씩 자동으로 생성되며, Pod내의 컨테이너들이 공유하는 Network과 IPC namespace를 생성하고 유지하는 역할을 한다.

[root@iap12 ~]# docker ps | egrep 'CONTAINER|ysjeon-mariadb-0'
CONTAINER ID   IMAGE                  COMMAND                  CREATED       STATUS       PORTS   NAMES
24505fc6375c   649c8e2d84b1           "/opt/bitnami/script…"   2 weeks ago   Up 2 weeks           k8s_mariadb_ysjeon-mariadb-0_yoosung-jeon_33dbfd5f-3c6f-48b5-8eba-d79b0f1c7fbe_56
6f4ef9734c5c   k8s.gcr.io/pause:3.1   "/pause"                 2 weeks ago   Up 2 weeks           k8s_POD_ysjeon-mariadb-0_yoosung-jeon_33dbfd5f-3c6f-48b5-8eba-d79b0f1c7fbe_4
[root@iap12 ~]#

 

- ysjeon-mariadb-0 Pod의 containerd-shim, 컨테이너 runtime 프로세스 찾기

   ✓ 도커 컨테이너 ID로 containerd-shim 컨테이너 프로세스와 컨테이너 runtime 프로세스(mysqld, pause)를 조회할 수 있다.

   ✓ mysqld 프로세스의 namespace를 조회하면 pause 프로세스와 ipc, network namespace를 공유하고 있음을 알 수 있다. 즉 Pod내의 사용자 컨테이너들은 pause 컨테이너를 통해 ipc와 network를 공유하게 된다.

   ✓ Namespace 종류

       ▷ user: user와 group ID를 분할 격리

       ▷ ipc: Inter-process communication. 프로세스간 통신 격리

       ▷ net: Network interface, iptables 등 network 리소스와 관련된 정보를 분할

       ▷ mnt: file system의 mount 지점을 분할하여 격리
       ▷ uts: hostname을 변경하고 분할
       ▷ pid: PID (Process ID)를 분할 관리

$ ps -ef | egrep 'PID|24505fc6375c|6f4ef9734c5c' | grep -v grep
UID    PID     PPID  C STIME TTY       TIME   CMD
root   38848   3181  0 Oct22 ?     01:11:53   docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/24505fc6375cc42c30d0c8441f2c14aac19f9f1891ef4f126ea98e10c4a68655 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root   30388   3181  0 Oct22 ?     00:01:24   docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6f4ef9734c5c7d02c023178e37e8fc785c0f60ff1a3218aa58ba768703cd5e78 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
$ ps -ef | egrep 'PID|38848' | grep -v grep
UID      PID   PPID  C STIME TTY       TIME   CMD
root   38848   3181  0 Oct22 ?     01:11:56   docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/24505fc6375cc42c30d0c8441f2c14aac19f9f1891ef4f126ea98e10c4a68655 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
1001   40285  38848  0 Oct22 ?     00:05:57   /opt/bitnami/mariadb/sbin/mysqld --defaults-file=/opt/bitnami/mariadb/conf/my.cnf --basedir=/opt/bitnami/mariadb --datadir=/bitnami/mariadb/data --socket=/opt/bitnami/mariadb/tmp/mysql.sock --pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid
[root@iap12 ~]# ps -ef | egrep 'PID|30388' | grep -v grep
UID      PID   PPID  C STIME TTY       TIME   CMD
root   30388   3181  0 Oct22 ?     00:01:24   docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6f4ef9734c5c7d02c023178e37e8fc785c0f60ff1a3218aa58ba768703cd5e78 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root   31861  30388  0 Oct22 ?     00:00:00   /pause
$
$ lsns -p 40285
        NS TYPE  NPROCS   PID USER COMMAND
4026531837 user    1846     1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026535420 ipc        2 31861 root /pause
4026535483 net        2 31861 root /pause
4026535715 mnt        1 40285 1001 /opt/bitnami/mariadb/sbin/mysqld --defaults-file=/opt/bitnami/mariadb/conf/my.cnf --base
4026535717 uts        1 40285 1001 /opt/bitnami/mariadb/sbin/mysqld --defaults-file=/opt/bitnami/mariadb/conf/my.cnf --base
4026535718 pid        1 40285 1001 /opt/bitnami/mariadb/sbin/mysqld --defaults-file=/opt/bitnami/mariadb/conf/my.cnf --base
$

 

 

4. Kubernetes unknown container 조치

- Kubernetes unknown container?

   Kubernetes에 의해 생성된 Docker 컨테이너이지만 어떤 이유로 Kubernetes에서 관리하지 않는 컨테이너를 의미한다.

   'unknown container'가 공식적으로 사용되는 용어는 아니다.

 

- unknown container 찾기

   ✓ (docker-)conatiner-shim의 부모 프로세스가 (docker-)containerd가 아니고 systemd(PID: 1)인 경우를 찾는다. 

$ ps -ef | egrep 'containerd-shim|PPID' | awk '$3 ~ /^1$|PPID/'
UID      PID  PPID  C STIME TTY       TIME CMD
root    9650     1  0 Oct21 ?     00:00:03 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/6b225ee63cae0642bf09f07f76a35c47fcc97c428baf3af578e484f307de54d3 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root   24080     1  0 Oct21 ?     00:00:02 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/91203830e792799445d9b7cc32fc26344a7fc29b276077ffa4f40ac7fd4a4450 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
root   24909     1  0 08:53 ?     00:00:00 docker-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/d7dce1b9d4bf1028ebff223f0e3d53b6a1199fc5140aeaa30f2c79aa9c70626e -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup
…

 

- Kubernetes, Docker engine 조회

   ✓ Kubernetes에서 관리하고 있는 컨테이너 리스트에는 unknwon container가 없다.  

       docker-containerd-shim의 workdir 인자 값 중 moby 디렉터리 다음이 Kubernetes container id값이다.

       "-workdir /var/.../moby/6b225ee63cae0642bf09f07f76a35c47fcc97c428baf3af578e484f307de54d3"

 

$ k describe pod -A | egrep '6b225ee63cae0642bf09f07f76a35c47fcc97c428baf3af578e484f307de54d3|91203830e792799445d9b7cc32fc26344a7fc29b276077ffa4f40ac7fd4a4450|d7dce1b9d4bf1028ebff223f0e3d53b6a1199fc5140aeaa30f2c79aa9c70626e'
$

 

   ✓ docker engine에서 관리하고 있는 컨테이너 리스트에는 unknwon container가 없다.  

$ docker ps | grep 6b225ee63cae
$

 

- unknown container 조치

a. kubelet / docker 재기동

   재 기동 후에도 일부 남아 있는 unknown container들이 존재했다.

# systemctl stop kubelet && systemctl stop docker
...
# systemctl start docker && systemctl start kubelet
...
#

 

b. unknown container 종료

   남아있는 컨테이너들은 kill 명령어(SIGTERM)로 종료시킨다. 

# ps -ef | egrep 'containerd-shim' | awk '$3 ~ /^1$/' | awk '{print $2}' | xargs kill
...
#

 

Docker engine 로그를 보면 unknown container가 종료된 경우 아래와 같이 메시지를 출력되다.

# journalctl -u docker.service -f | grep ac489b23311f4e841607810f2569f7a50b77882252ee24d07caeb57cb57b7454
Oct 22 10:48:01 iap12 dockerd[216498]: time="2021-10-22T10:48:01.677468710+09:00" level=warning msg="unknown container" container=ac489b23311f4e841607810f2569f7a50b77882252ee24d07caeb57cb57b7454 module=libcontainerd namespace=moby

 

 

참조.

   https://betterprogramming.pub/docker-for-front-end-developers-c758a44e622f

   https://iximiuz.com/en/posts/implementing-container-runtime-shim/

   https://brunch.co.kr/@jehovah/35

댓글