#概要
kubernetesのpodには自動的にpauseコンテナというコンテナが起動する。
こいつは何者なのか?という話
kubernetes を運用している中で、podがteminatingのまま消えない現象の時、pause コンテナがout of memory で kill されている現象が起きていたことが多かったのでついでに調査。
#実装
非常に短い。C言語 が読めるならすぐ。
なんでgo じゃないんだろう??
https://github.com/kubernetes/kubernetes/tree/master/build/pause
#コンテナとはノードのリソースを割り当てられたプロセス
題名の通り、「コンテナ」とは Linuxのプロセスに対し、名前空間とcgroup でいろんなリソースを隔離して与えられたプロセス。
ここら辺を参考に
http://gihyo.jp/admin/serial/01/linux_containers/0002
#pauseコンテナはネットワーク名前空間とPID名前空間に関係する
このあたりを
https://www.ianlewis.org/en/almighty-pause-container
##PID名前空間
隔離されたPID名前空間(つまり、コンテナとして起動されたプロセスが存在するPID名前空間のこと)では新たなプロセスIDが1から振られる。
ここで通常のプロセスの関係を思い出すと、子プロセスが死ぬと親プロセスがwaitするまではカーネルのプロセステーブルに残り続ける。いわゆるゾンビプロセス。
先に親プロセスが死んだ場合は、子プロセスの親はプロセスID 1、つまりinitプロセスになる。
この関係を覚えたままPID名前空間に戻ります。プロセスID 1 には子プロセスを看取る役割がある。
ということはコンテナとして起動されたプロセスにもその役割が期待される。それを担当するのがpauseコンテナ。
実装を見ても waitpid に引数 -1 を渡して実行(任意のプロセスを待つ)しているのが見て取れます。
static void sigreap(int signo) {
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
ただこういうpauseコンテナがなくても、コンテナとして起動されたプロセスはカーネルから見たらただの一つのプロセスにすぎないため、最終的には親プロセスが死んだとしても結局はinit プロセスの子プロセスになるのだと思われる。
podにゾンビプロセスを溜めないための仕組みといった感じを受ける.
##ネットワーク名前空間
docker を例に説明します。
docker では通常コンテナを起動するときに新たにネットワーク名前空間が付与される。
https://tech.uzabase.com/entry/2017/08/07/172411
ただ、オプションですでに起動しているコンテナのネットワーク名前空間を使用することもできる。
上で紹介したサイト内の一部を抜粋。
docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost
つまり、最初にネットワーク名前空間を規定しているコンテナが存在すれば、後から起動するコンテナ達(まとめてpod となる単位)はそのネットワーク名前空間を共有できる。
おそらく、ネットワーク名前空間上で実行しているプロセスが死ぬとその名前空間が消滅するので用意しているのかな~と思ってます。
参考
https://tenforward.hatenablog.com/entry/20160726/1469533536
#結局terminating との関係は?
調査中