私はDockerもDocker Composeもcontainerdも素人で、今回の問題がよく知られた問題なのか、そうでないのかもよく知りません。ちなみにDocker Composeは今日まで使ったことがなかったし、Rancher Desktopも今日はじめてインストールしました(^^)。
この辺りのコンテナランタイムの知識もないので、用語の使い方も間違ってたりするかもしれませんがご容赦を。
このエントリは単に「ちょっと時間使って調べた」ので「オレ頑張ったよ」と誰かに言わないと気がすまないし、最近技術ブログ書いてないよなと思ったので書いてみるだけです。
問題
「Sensu Goをコンテナで起動してるけど、コンテナを再起動するたびに初期化されるので、Sensuに詳しいだろうからちょっと見て」という相談を受けたのが始まりです。(ちなみにSensu Go詳しくないです。Sensu Goを使ったシステムをちょっと作ったことがありますが)結局は Sensu の知識は全く不要でした。
Rancher Desktop環境で、Sensu Goの公式ドキュメントにあるDocker Composeを使ってsensu-backend(sensuサーバー)を起動すると、再起動するたびにetcdのデータが初期化されているのか、毎回クライアント側も初期設定する必要があるということでした。
ちなみに yaml はこんな。
version: "3"
services:
sensu-backend:
ports:
- 3000:3000
- 8080:8080
- 8081:8081
volumes:
- "sensu-backend-data:/var/lib/sensu/sensu-backend/etcd"
command: "sensu-backend start --state-dir /var/lib/sensu/sensu-backend --log-level debug"
environment:
- SENSU_BACKEND_CLUSTER_ADMIN_USERNAME=admin
- SENSU_BACKEND_CLUSTER_ADMIN_PASSWORD=admin
image: sensu/sensu:latest
volumes:
sensu-backend-data:
driver: local
解決
問題自体はすぐに解決しました。手元に Rancher Desktop がなかったので、Linux 上の Docker 環境で docker-compose.yaml を書いて起動してみました。
しかしどのようにやっても、ちょっとコンテナを強制終了しても、特に再起動後は問題なく使えます。で、このことを相談を受けた人に伝えると、すぐに
- Linux(のDocker)でやったらたしかに問題は起こらない
- 試しに Rancher Desktop のコンテナランタイムを "containerd" にしていたのを "dockerd(moby)" に切り替えたら問題が起こらなくなった
というわけで、これで解決です。
問題を再燃させる
でも、気になりますよね、これ!ということであえて Rancher Desktop のコンテナランタイムを "containerd" に切り替えて調査!
ここで引き下がるのはなんか悔しいってことで色々調べてみました。調べたといってもほとんど Docker Compose の YAML の書き方とか、そもそも「ボリュームってなんやねん」とか、皆無だった基礎知識のあたりを調べてた時間がほとんどですが。
まず、最初に気づいたのは起動時に Warning が出ていること。
% nerdctl compose up -d
INFO[0000] Creating network sensu_default
WARN[0000] Ignoring: volume sensu-backend-data: [Driver] <-(コレ)
INFO[0000] Ensuring image sensu/sensu:latest
INFO[0000] Creating container sensu_sensu-backend_1
もしかして、ボリュームがうまくできてないの?とか思ったけど、これは文字通りWarningで関係ないことが後で判明します。多分ですが、
ココに
Unimplemented docker volume create flags: --driver, --opt
と書かれてるので、これが原因でしょう。
色々調べてると、どうやら再起動するたびにボリュームが新たに作られていってることに気づきます。これだったら、毎回新たに etcd のデータが作られるので、毎回初期設定が必要になるのもわかります。こんな感じ。再起動のたびに新たにボリュームが作られています。
% nerdctl volume list
VOLUME NAME DIRECTORY
% nerdctl compose up -d
INFO[0000] Creating network sensu_default
WARN[0000] Ignoring: volume sensu-backend-data: [Driver]
INFO[0000] Creating volume sensu_sensu-backend-data
INFO[0000] Ensuring image sensu/sensu:latest
INFO[0000] Creating container sensu_sensu-backend_1
% nerdctl volume list
VOLUME NAME DIRECTORY
9a3721923ba55334655208752d48846585c9072f11bce8f1e7fa9f2a4a5074a0 /var/lib/nerdctl/dbb19c5e/volumes/default/9a3721923ba55334655208752d48846585c9072f11bce8f1e7fa9f2a4a5074a0/_data
sensu_sensu-backend-data /var/lib/nerdctl/dbb19c5e/volumes/default/sensu_sensu-backend-data/_data
% nerdctl compose down
INFO[0000] Removing container sensu_sensu-backend_1
INFO[0000] Removing network sensu_default
karma@warbird sensu % nerdctl compose up -d
INFO[0000] Creating network sensu_default
WARN[0000] Ignoring: volume sensu-backend-data: [Driver]
INFO[0000] Ensuring image sensu/sensu:latest
INFO[0000] Creating container sensu_sensu-backend_1
% nerdctl volume list
VOLUME NAME DIRECTORY
sensu_sensu-backend-data /var/lib/nerdctl/dbb19c5e/volumes/default/sensu_sensu-backend-data/_data
0b65bbacb252e1ac8953c2b2903aa7ae94b0f213952776ce568d08bdb8b794d2 /var/lib/nerdctl/dbb19c5e/volumes/default/0b65bbacb252e1ac8953c2b2903aa7ae94b0f213952776ce568d08bdb8b794d2/_data
9a3721923ba55334655208752d48846585c9072f11bce8f1e7fa9f2a4a5074a0 /var/lib/nerdctl/dbb19c5e/volumes/default/9a3721923ba55334655208752d48846585c9072f11bce8f1e7fa9f2a4a5074a0/_data
たぶん、ここは sensu-backend-data
という名前のボリュームがひとつだけ作られるのが正解っぽいけど、なぜか謎のボリュームが増殖していくという…
これは何が起こっているのかコンテナ内(コンテナのMount Namespace内)を確認しないとダメだね、ってことで、やってみました。
% nerdctl ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0eeffa3553b5 docker.io/sensu/sensu:latest "sensu-backend start…" 2 minutes ago Up 0.0.0.0:3000->3000/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:8081->8081/tcp sensu_sensu-backend_1
% nerdctl exec -ti sensu_sensu-backend_1 -- /bin/sh
/
146 125 253:1 /var/lib/nerdctl/dbb19c5e/volumes/default/sensu_sensu-backend-data/_data /var/lib/sensu/sensu-backend/etcd rw,relatime master:4 - ext4 /dev/disk/by-label/data-volume rw
147 125 253:1 /var/lib/nerdctl/dbb19c5e/volumes/default/0b65bbacb252e1ac8953c2b2903aa7ae94b0f213952776ce568d08bdb8b794d2/_data /var/lib/sensu rw,relatime master:4 - ext4 /dev/disk/by-label/data-volume rw
これでもうわかりましたね。ちゃんと指定のボリュームは作られているものの、別のマウントもされているので、おそらくはそっち側が上にマウントされてる感じかな?
ちなみに名前付きで作ってるボリュームについては、コンテナ内の別のディレクトリにマウントしてみると空でした。こっちが指定どおり sensu-backend-data
という名前で作られてないのも気になりますね。("name" 属性を指定したらちゃんとその名前で作られたけど)
匿名のボリュームは /var/lib/sensu
にマウントされていることから、コンテナ内に /var/lib/sensu
は存在しなくても作ってくれるものの、さらにその子ディレクトリが /var/lib/sensu/sensu-backend/etcd
のように指定されていると、コンテナ上にはそのようなディレクトリがないので、まずは /var/lib/sensu
を作りに行って、それに新たにボリュームが作成されてマウントされてしまう感じでしょうか。名前付きのボリュームもマウントはされているので、そちらがどのような状態になっているのかが謎…
存在しないディレクトリにはマウントできないし、でも作成された後であとでマウントされたらそっちが見えるはずだし、でもどうやら匿名で作られた /var/lib/sensu
にマウントされている方が上で見えているようだし…
というわけで、docker-compose.yaml には、存在しないディレクトリは /var/lib/sensu
のように一段だけ指定して無事解決でした。
version: "3"
services:
sensu-backend:
ports:
- 3000:3000
- 8080:8080
- 8081:8081
volumes:
- sensu-backend-data:/var/lib/sensu
command: "sensu-backend start --state-dir /var/lib/sensu/sensu-backend --log-level debug"
environment:
- SENSU_BACKEND_CLUSTER_ADMIN_USERNAME=admin
- SENSU_BACKEND_CLUSTER_ADMIN_PASSWORD=admin
image: sensu/sensu:latest
volumes:
sensu-backend-data:
まとめると、
- containerd をランタイムとして使うと、volumesで指定したパスのうち、コンテナ内に存在するディレクトリ(ここでは
/var/lib
)の下に存在しないディレクトリ(マウントポイント)は、直下のディレクトリ(ここでは /var/lib/sensu
まで)は作成してくれる
- それ以上深いディレクトリを指定しても作ってくれなくて、とりあえず新しいボリュームを作成し、存在するディレクトリの一層下までのディレクトリまで作成し、そこにマウントしてしまう(ここでは
/var/lib/sensu
)
- 存在しない深いディレクトリ(ここでは
/var/lib/sensu/sensu-backend/etcd
)を指定すると、それもマウントはしてくれるようだが、その上にさらに上記のマウントを重ねてしまうようなので見えないので結局は使えない(マウント情報を見ての想像です)
- Rancher Desktop でランタイムとして "dockerd" 指定すると、最初に示した YAML で問題なく動く
- ここの
volumes
の指定をどのように行うのが正解なのかはよく知らない(わからない)<ドキュメントとか読んでません
という感じです。雑なまとめ。
うーん、Mac 上から VM 層が隠蔽されていると、VM 内を覗けないのでトラブルシューティングしにくいなあ…(やる方法あるのかもしれんけどしらん)
ま、これ以上は特に興味がない個別のプロダクトのお話になるのでこの辺りで終わり!