今日覚えて帰ること
PID名前空間
一群のプロセスが他の名前空間のPIDとは別に独自の一意のPIDセットを持つことができる名前空間のこと。
各コンテナは通常独自のPID名前空間を持つ。
コンテナを立ち上げる際、–pid=<resistory:tag> というオプションをつけると、指定したコンテナと同じ名前空間にコンテナを立ち上げることが出来る。
Container Namespaces Docker
Create two Docker containers sharing the same PID namespace
Run two Docker containers
app1
andapp2
with the following attributes:
- they should run image
nginx:alpine
- they should share the same PID kernel namespace
- they should run command
sleep infinity
- they should run in the background (detached)
Then check which container sees which processes and make sense of why.
2つのコンテナを指定した条件で立ち上げろ、と言っています。
ここでそもそもコンテナの立ち上げ方を正しく認識していなかったのでメモしておきます。
このブログでは今まで
docker run <containerID>
で立ち上げていました。
これでも問題はないのですが、このような立ち上げ方以外にも以下のようにレポジトリとタグを指定することでコンテナを立ち上げることが出来ます。
docker run <repositoryName>:<tag>
例えばローカルに以下のようなイメージがあるとします。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx alpine 21f5eb7b4eec 2 weeks ago 22.9MB
nginx latest 5578ee0b9347 2 weeks ago 133MB
この場合、
docker run nginx:alpine
で一つ目に記載されているコンテナを立ち上げることが出来ます。
デフォルトのタグは「latest」なので、
docker run nginx
というコマンドを打てば2つ目のコンテナが立ち上がります。
また、コマンドで指定したイメージがローカルに存在しない場合、docker hubからコンテナイメージを取得してコンテナを立ち上げます。
閑話休題。(脱線でもなかったけどね。)
まずはapp1を立ち上げます。
controlplane $ docker run --name app1 -d nginx:alpine sleep infinity
Unable to find image 'nginx:alpine' locally
alpine: Pulling from library/nginx
46b060cc2620: Pull complete
21af147d2ad5: Pull complete
b3ee43e51ca6: Pull complete
b17a9d410da1: Pull complete
542e3e75411d: Pull complete
2b2faad386df: Pull complete
a5e22afba545: Pull complete
fb923a41dc10: Pull complete
Digest: sha256:208b70eefac13ee9be00e486f79c695b15cef861c680527171a27d253d834be9
Status: Downloaded newer image for nginx:alpine
e8db81b6bfc13b0ccba497dee35d642bd62bd6b49246aac95c1ebf77c04b34ca
docker run --name <container name> -d(optioin) <repository>:<tag> <command>
という形で立ち上げています。
今回はローカルにイメージがなかったのでpullしてきているみたいですね。
Unable to find image 'nginx:alpine' locally
どのユーザーがプロセスを立ち上げているか確認します。
controlplane $ docker exec app1 ps aux
PID USER TIME COMMAND
1 root 0:00 sleep infinity
6 root 0:00 ps aux
rootでした。
次に app1 が存在するPID名前空間に 同じ中身のコンテナ app2 を立てます。
が、PID名前空間が良くわからないので調べてみます。
PID(プロセス識別子)名前空間は、Linuxカーネルの機能であり、プロセスの隔離を提供します。これにより、一群のプロセスが他の名前空間のPIDとは別に独自の一意のPIDセットを持つことができます。これは、プロセスの隔離がセキュリティとリソース管理に不可欠なコンテナ化に特に役立ちます。
必要な情報を箇条書きにすると、
- Linuxカーネルの機能
- プロセスの隔離を提供(別の名前空間のプロセスを参照できない)
- プロセスが他の名前空間のPIDとは別に独自の一意のPIDセットを持てるようになる
- コンテナ化に必要
ってなところでしょうか。
コンテナって言っちゃえば隔離されたプロセスの塊で、PID名前空間の分離はコンテナを構成する技術の一つですね。
今回は2つのコンテナでそのPID名前空間を共有しよう、ということです。
疎通できるコンテナってなんとなく聞き覚えがありませんか?
そうです!今回はpodのようなものを作ろうとしているのです。
詳しく知りたい方は以下の記事が参考になります
では進めていきます。
controlplane $ docker run --name app2 --pid=container:app1 -d nginx:alpine sleep infinity
015766188c859aa80f64ddc5fd1cd9dcef0ff4aa04d7cc9e1e50e6c26273517d
イメージが既にローカルに存在するため各レイヤーをpullする必要がなくなっています。
そして –pid=<resistory:tag> オプションで既存のコンテナとPID名前空間を共有することが出来ます。
docker exec でコンテナに入って参照できるpsを確認します。
controlplane $ docker exec app1 ps aux
PID USER TIME COMMAND
1 root 0:00 sleep infinity
11 root 0:00 sleep infinity
16 root 0:00 ps aux
controlplane $ docker exec app2 ps aux
PID USER TIME COMMAND
1 root 0:00 sleep infinity
11 root 0:00 sleep infinity
21 root 0:00 ps aux
どちらのコンテナでも sleep infinity は一度しか実行していないにもかかわらず、2つのプロセスが表示されています。
これは app1, app2がPID名前空間を共有しており、各コンテナ内に存在するプロセスを相互に確認できるからです。
次のシナリオである Container Namespaces Podman は、今回のシナリオのコマンドを docker から podman に変更しただけで全く同じなので、省略します。