『イラストでわかるDockerとKubernetes Software Design plus』を読んだ
この本を読んだメモ。
Docker/Kubernetesは仕事で使っているものの、きちんと勉強したことがないなと思ったので、まわりで評判の良かったこの本を丁寧に読むことにした。
本の感想
- Docker使ってると「レイヤ」って言葉を見るけど、そのイメージがついた。イラスト付きでしっかり解説してくれるのはありがたい。
CRIランタイム
/OCIランタイム
って言葉をよく見かける。こないだも見た。これの意味を理解した。CRIランタイム
: 高レベルランタイム。kubeletからの命令を受け付ける部分。コンテナ・イメージ・ネットワーク等全般の管理。OCIランタイム
: 低レベルランタイム。CRIランタイム
からの命令を受け付ける。ホストから隔離された実行環境をコンテナとして作り出し、操作可能にする。
- コンテナを使う際に何が起きてるのか、ざっとだが理解できたと思う。書いてあるけど理解が追いつかない部分はあるのでまた読み返そう・・
- 正直、最後の方はついていくのが大変だった。というかついていけなかった気がする。コンピュータの基礎についてちゃんと勉強したほうがいいな。
読んでてハマったこと
コマンドが書いてあるので一つ一つ模写しながら確認していった。
その中でいくつかハマったのでメモとして残しておく。
前提:検証時の環境
- PC: MacBook Pro (13-inch, 2020)
- OS: MacOS Catalina(10.15.7)
- Docker Desktop(3.1.0)
overlay2のディレクトリが見つからない
2-2-4レイヤ構造のイメージからのルートファイルシステム作成に用いられる要素技術
Docker内のレイヤの重ね合わせの説明で、storage driver
「overlay2
」の説明がある。
Docker Imageの中で実際にレイヤがどう保存されているかを確認してみよう、というところがある。
/var/lib/docker/overlay2/
しかしこのパスがMacだと見つからない。
% ls /var/lib/docker/overlay2/ ls: /var/lib/docker/overlay2/: No such file or directory
なんでやねん、ということで調べてみると、MacのDocker DesktopはVM上で動いているため、ここで出てくるパスはローカルMacではなくてVM上のパスであるとのこと。たしかにそんなことを聞いたことがある気がする。
じゃあそのVMにはどうアクセスしたらええねん、と続けて調べてみると、以下のコマンドでアクセスできるとのことで試す。
% screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
が、できない。何も表示されない。
記事によってはtty
を入れてないので、そこか?と試す。
% screen ~/Library/Containers/com.docker.docker/Data/vms/0/ [screen is terminating]
ダメ。なんか即切りされる。
screenコマンドに慣れていないので、何かが違うのか?といろいろ調べてみるが、すぐに表示されるはず、らしい。
https://qiita.com/kawanet/items/263acbb870e3d2a842cd
何がおかしいんやと追加でググる。すると以下のissueを見つけた。
https://github.com/docker/for-mac/issues/4822
StackOverFlowにも同じような悩みが。
https://stackoverflow.com/questions/63445657/why-i-am-getting-screen-is-terminating-error-in-macos/63595817#63595817
ということでworkaround1を試す
https://stackoverflow.com/questions/63445657/why-i-am-getting-screen-is-termination-error-in-macos/63595817#63595817
% docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh / # ls /var/lib/docker/overlay2/ 04220f51e5fa4946d9ccc91265931d1ac12a9da8b8ac268eaf4d07d67b890ae2 0da11ec70bdaaecc4f570fc28082ab7ea6a268cf610d842054ff1ef5b30c7e5d 0f9284d24e5a01b131f58917b7177b96dfd9ddc519fdc8952bfd86fc99fca4ed (後略)
いけた!
このコマンドが何をやっているのかよくわからんので分解してみる。
docker run \ -it \ --privileged \ --pid=host \ debian \ nsenter \ -t 1 \ -m \ -u \ -n \ -i \ sh
基本は Docker-docs-jaから引用。筆者による追記あり。
docker run
- 新しいコンテナを実行する命令
-it
-i
(--interactive
): コンテナの STDIN にアタッチ- Dockerを起動しているコンソールの標準出力とコンテナの標準入力が繋がる
-t
(--tty
): 疑似ターミナル (pseudo-TTY) を割り当て- Dockerを起動しているコンソールの標準出力とコンテナの標準出力が繋がる
--privileged
: このコンテナに対して拡張権限を与える--pid=host
debian
- pullするイメージ
nsenter
debian
イメージに入ってるツール。Dockerで作った名前空間(ネームペース:namespace)に入るためのコマンドライン・ツール。debian
イメージでコンテナを起動して、このツールを起動している。- https://github.com/jpetazzo/nsenter
-t 1
nsenter
のオプション-t, --target <pid>
: 名前空間を取得するターゲットプロセス- ここでは
1
を指定している。1
ってなんやと調べてみると、起動プロセス。まあそうか。
root@3b877f756d3f:/# cat /proc/1/cmdline /sbin/init
-m
nsenter
のオプション-m, --mount[=<file>]
: マウント名前空間
-u
nsenter
のオプション-u, --uts[=<file>]
: UTS名前空間
-n
nsenter
のオプション-n, --net[=<file>]
: ネットワーク名前空間
-i
nsenter
のオプション-i, --ipc[=<file>]
: システムV IPC名前空間
sh
nsenter
で上記で指定した名前空間内でshellを起動する。
・・・調べてみたが結局よくわからん。特にnsenter
のオプションのところがわからない。
なんとなくわかったような気がするところだけ書くと、
- ホスト(Mac)とnamespaceを共有したdebianイメージを特権モードで起動する
- 起動したコンテナ内で
nsenter
で別PIDに入り込もうとする。このときPIDに1を指定すると自分自身を指定したことになる(?)ので、ホスト側から見るとDockerコンテナを起動している場所=DockerDesktopのVMへ入ることになる(?)
なのかな、たぶん。-m -u -n -i
のところが全然わからないのだけど。
あまり深追いしてもしょうがないと自分に言い聞かせることにした。だれか詳しい人教えてほしい。
とりあえず、上記コマンドでMac上で起動しているDockerDesktopのVMに入ることができる。