⚠️ 記事内に広告を含みます。

コンテナの基盤技術であるカーネルのpid namespaceについて知る

コンテナ技術が利用しているカーネル機能の一つpid namespaceを知ることでコンテナ技術についての知識を深める

namespaceとは?

名前空間(namespace)は任意の識別子を使ってユニークな値を複数のグループに分離するために使われます。

例としては住所で、同じ中央区1-1でも北海道札幌市中央区と福岡県福岡市中央区では別の地図の場所を指し示すように、北海道と福岡とで別々の名前空間に属しているので別のユニークな値を示します。

pid namespace

lsns -t pidでプロセスのネームスペースを表示することができます。

コンテナを起動していない状態のネームスペースを確認

# lsns -t pid
        NS TYPE NPROCS PID USER COMMAND
4026531836 pid     155   1 root /sbin/init fixrtc splash

名前空間は4026531836の一つだけ

コンテナ起動後に確認

postgresのコンテナを立ち上げてから確認すると2つのnamespaceが確認できる

##---docker psコマンドでコンテナの起動を確認---
# docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED        STATUS        PORTS      NAMES
c39561a2af03   postgres:13-alpine   "docker-entrypoint.s…"   5 months ago   Up 1 second   5432/tcp   docker-postgres-1

###---lsnsでネームスペースを確認
# lsns -t pid
        NS TYPE NPROCS     PID USER COMMAND
4026531836 pid     157       1 root /sbin/init fixrtc splash
4026532369 pid       7 2923124 70   postgres

ネームスペースの親子関係

プロセスと同じようにプロセスのネームスペースにも親子関係がある。
lsnsで確認した時に上のPIDネームスペース4026531836はPIDが1になっている。これが親です。
一方でpostgres(コンテナ)のNSのPIDは304612で子の関係にあります。

# lsns -t pid
        NS TYPE NPROCS     PID USER COMMAND
4026531836 pid     167       1 root /sbin/init fixrtc splash
4026532369 pid       7 3034612 70   postgres

新しい世代のLinuxはsystemdを採用しているので、PID1のinitプロセスはsystemdになっているはずです。
上の例のOSはubuntuですが、なぜか/sbin/initとなっています。この詳細をlsで確認すると/lib/systemd/systemdへのシンボリックリンクになっていることが確認できるので実質これはsystemdということがわかります。

# cat /etc/os-release  | grep PRETTY
PRETTY_NAME="Ubuntu 22.04.1 LTS"

# ls -al /sbin/init
lrwxrwxrwx 1 root root 20 Sep 10 03:47 /sbin/init -> /lib/systemd/systemd

https://bugs.launchpad.net/ubuntu/+source/init-system-helpers/+bug/1457886

systemdでは全てのプロセスはsystemdの子プロセスとして起動します。

systemdとは?systemdとは?systemctlコマンドとは

親側であるホストOSからは子側(コンテナ)のプロセスを確認することができる。

# ps -e -o pid,ipcns,args | sort -nk2 | tail -10
2941085 4026531839 ps -e -o pid,ipcns,args
2941086 4026531839 sort -nk2
2941087 4026531839 tail -10
2923124 4026532368 postgres
2923195 4026532368 postgres: checkpointer 
2923196 4026532368 postgres: background writer 
2923197 4026532368 postgres: walwriter 
2923198 4026532368 postgres: autovacuum launcher 
2923199 4026532368 postgres: stats collector 
2923200 4026532368 postgres: logical replication launcher 

ホスト側でプロセスを確認するとdockerで立ち上げているpostgresのプロセスがホストとは別のnamespaceで上がっている。

docker側から確認しようとしてもホスト側のプロセスは確認できない

# ps aux
PID   USER     TIME  COMMAND
    1 postgres  0:00 postgres
   23 postgres  0:00 postgres: checkpointer 
   24 postgres  0:00 postgres: background writer 
   25 postgres  0:00 postgres: walwriter 
   26 postgres  0:00 postgres: autovacuum launcher 
   27 postgres  0:00 postgres: stats collector 
   28 postgres  0:00 postgres: logical replication launcher 
  153 root      0:00 /bin/bash
  162 root      0:00 ps aux

コンテナ内ではPID1はpostgresになっている。
ホストのsystemdのPID1と被ってしまうように感じるが、ホストとコンテナでは別々のnamespaceに属しているので同じPID1でも別物である。

ネームスペースを分離することでプロセスをホストとは別のグループに分離できる。

このカーネルの機能がdockerなどのコンテナ技術で利用されている。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です