Cloud Native 読書会第3回 containerd
Cloud Native 読書会
前回
毎月第3水曜日に少人数で集まり一緒に Cloud Native 技術のコードを読む会です。
Connpass と Wantedly で募集しています。
Role
- @potsbo 司会 -> 全体進行
- @south37 裏方 -> 参加できてない人のケアなど
Timetable
- Introduction 5 min
- 自己紹介 15 min
- 読書 60 min
- 反省会/次回予告 10 min
概要
コードを読むことがなんだかんだ一番コスパの良い技術の学習方法だと @potsbo 考えています。もともとは Kubernetes 読書会として Kubernetes のコードを読む会をしていた事がありましたが、今回はそれの復活版で更に Kubernetes 以外のコードも読んでいいじゃないか、という会です。
かなりカジュアルに行っていた会で進め方も固まっているわけではありません。
皆さんのいろんな意見を聞きながら良い会にしていければなと思ってます。
(ちゃんとやるのが面倒になって中止してしまっていましたが結構評判が良かったので「続けること」を目標に再開しています。)
うまくいったら下の発表のような知見が得られることを期待しています。
前提
ハードルは低く行きます。「少人数だからこそ何でも聞いて良い」を前提にします。どんなに馬鹿に思える質問でもコードを追うことで理解するという解決策を取れば必ず良い学びになると思っています。
多分人の顔と名前も覚えてられないと思うので、「名前は覚えられていない」という前提を共有して進みましょう。
進め方
誰か一人の PC の画面共有をしながら議論をしながら何らかのテーマを解決していきます。全員が非公開 Podcast の出演者のような気持ちで積極的に発言してくれることを期待しています。
テーマはまだ決めていないので「そういえばここの挙動が気になる」というようなものがあると嬉しいです。
@potsbo
Wantedly で技術基盤チームで Istio や Ambassador をいじっています。
containerd は一ヶ月前まで概要すら知りませんでしたし今も殆ど知りません。
@bgpat
Wantedly のインフラチームで Kubernetes を触るお仕事をしています
containerd は Docker 経由でしか触ったことがないです
@south37
「Wantedly で Kubernetes を管理しているチーム(= Infrastructure Team)」に所属しています。少し前まで仕事では「gRPC の利用を社内に広げるプロジェクト」をやっていました。
@Goryudyuma
とある会社でSREとして仕事してます。
containerdは詳しくないので、皆さんと一緒に勉強していけたら良いなと思います、よろしくお願いします!
_tsuzu_
, GitHub: cs3238-tsuzu)
@tsuzu(Twitter: 内定者インターンをしている学生です。
コンテナランタイムは1 dayインターンで作成する、みたいなことをやって楽しかったのですが、containerdはほとんど知りません。
@y_taka_23 (チェシャ猫)
チェシャ猫です。containerd は CRI から shim を呼び出す流れを一度追ってみたことがあるんですが、今日は改めて理解を深められればと思います。よろしくお願いします。
@tetsu
とある会社に20卒で入社した山本です
Kubernetesは最近触り始め感じで、containerdは概要を知っているレベルです
containerd を3行で
kubelet が CRI という interface (gRPC) で containerd
に container がほしいよと言ったら containerd
が runc を起動してくれるという立ち位置のやつ
git checkout v1.3.9
で読む
最初に見るコード: https://github.com/containerd/containerd/blob/v1.3.9/client.go
これは「containerd を利用する際の、client 側のコード」。
% git show
commit 1230bd63031ba4b65709103b5cb8f5be78a43b75 (HEAD -> v1.3.9, origin/master, origin/HEAD, master)
Merge: 9c3f17139 a73103923
Author: Phil Estes <estesp@gmail.com>
Date: Tue Jan 19 16:21:35 2021 -0500
Merge pull request #4952 from crosbymichael/label-etc-files
[cri] label etc files for selinux containers
とりあえずこんなふうに使われている
containerd.New("/run/containerd/containerd.sock")
daemon のコードが読みたい => 探す
(直接今回の会と関係ない話)moby/moby で containerd.New を読んでる箇所を見つけたので、これが「docker から containerd を利用してる箇所」かも。
ここもそれっぽい。
containerd
の client は CRI なのか?
@potsbo はそうなのではないかと思ったけど雰囲気的には違いそう?
CRI から読むのがイメージしやすそう
StartContainer がその中でも一番簡単そうなのでここから行く
CRI の protofile はおそらくこれ。
ociRuntime というのが出てきて気になる
containerd → shim (containerd のリポジトリ内にある) → runc
kubernetesのpodには自動的にpauseコンテナというコンテナが起動する
Pauseはネットワークのインターフェースを担当する
shim の仕様はここで、自作も可能。
pause container について説明してそうな blog post を見つけました(ちゃんと読んではないです)。
ここまで読んだ
今のところ設定のロードとかインタフェースの変換くらいしかしていない
Kubernetes から実際に使う RuntimeClass を Pod ごとに変えるには。
OCI の spec の struct に落とし込むところ
AppArmor
apparmor,seccompは同じようなセキュリティのやつ、不審なプロセス起動しないとか
「containerdにおけるcontainerはメタデータにすぎない」
実際のコンテナ作成処理は container.NewTask を読むといいらしい
containerdにおけるcontainerはメタデータにすぎないので、実際に作るところはcontainer.Newtaskを読んでください
今このへん?
FYI
AppArmorはDebian系で動くSELinuxみたいなやつ
Kubernetes → Dockershim → Docker → containerd
- dockershim -> ブリッジ
- 消される CRI を docker interface に変換する
- docker 自体は CRI を持っていない
- docker が containerd を叩くときは containerd の API を叩く
- 多分 getting started のアレ
- containerd に CRI のために wrapper が存在する
CRI は Plugin として実装されてる。
CRI の proto file はおそらくこれ
https://github.com/containerd/containerd/blob/v1.3.9/vendor/github.com/containerd/cri/pkg/server/container_start.go#L107 の NewTask が一番我々が想像する「コンテナを作るところ」に近いところ
CreateConatiner で containerid が帰ってくるのでこれを StartContainer にわたすようになっている。
exitChはexit codeを待っている
Waitはexit codeが帰ってくるchanを返す
##結論
getting started の下の部分に相当するところとして CreateContainer, StartContainer の2つの method を読んだ。
結果、CRI の実装はcontainerd の wrapper として作られていて、dockershim がやっていたようなことをやっているレイヤがこんなところにみたいな感じだった。
// create a container
container, err := client.NewContainer(
ctx,
"redis-server",
containerd.WithImage(image),
containerd.WithNewSnapshot("redis-server-snapshot", image),
containerd.WithNewSpec(oci.WithImageConfig(image)),
)
if err != nil {
return err
}
defer container.Delete(ctx, containerd.WithSnapshotCleanup)
// create a task from the container
task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
if err != nil {
return err
}
defer task.Delete(ctx)
https://github.com/containerd/containerd/blob/v1.3.9/container.go#L286 から読んでいくと runtime の起動までたどり着けるらしい
反省会
反省: 遅刻しない
反省
- 手元のVSCodeがGo ModulesでないためJump to definitionができずつらかった
- 積極的に発言できるようにしたい
- リロードは必要だったがそこまで問題はなかった気がする?
Keep
- Zenn だからか、コメントは積極的に行われた気がする
- Zenn はコードハイライトなどが効くのが良い
Problem
- Zenn は reload しないとコメントに気づけないのがデメリット(interactive なコミュニケーションが微妙にやりづらかった)
反省会
- 最初にバージョンを揃えておいたのはよかった
- criの方は微妙にズレてるものを読んでたせいで、変換しながら読んでました笑
- 同時編集・リアルタイム反映欲しい (@zenn)
- もっとzennに書き込めばよかった
- Visual Studio Live Shareとかも相性良さそう?って思った
- 人のカーソルに飛ぶことができたり
cri は vendor/github.com/containerd/cri を見てた
Live Shareいいですね!
感想 by @potsbo
- 知見がある人がいて割とサクサク進めた
- その代わり割と多くの割合の人を放置してしまった気がする
- zenn を使うという新しいアプローチがうまく言ったのか気になる
感想 by @tetsu
- 途中質問タイムがあって、わからないことを聞くと教えてもらえるのがよかった
- 関係ありそうなところと関係なさそうなところを的確に判断して進めてくれているので早かった
- ファイルパスがどこかわからなかったので手元で探すのが大変だった
- 個人的には人数はそこまでに気にならなかった
反省/感想
- 一番読みたかったところまで辿り着かなかったけどなんかいろいろ wrap されてることは分かった
- コードを読んでも gRPC の client にしかたどり着けない…
- component 間の図がほしい
- zenn.dev は更新されないのが使いにくかった
- vim-go のコードジャンプが使いやすかった
- sourcegraph も併用していたけど飛んでくれないことがあった
- たまに読んでる場所を貼ったりしてたけど使ってくれた人いたんだろうか?
反省 / 感想
- なんか出しゃばりすぎた感ある。
- Zenn はちょっとリロードが面倒だった。
- 共有された画面と自分のターミナルを同時に見るのは厳しい。
実はいつでも質問して止めていいとは明示的に書いてなかった
hackmd だと複数人で同時 md 編集ができるらしい
thread 機能に今気づいたけど自己紹介 thread とか感想 thread とか作ればよかったのか
予習がしやすいと嬉しさがある -> そのとおりだと思った
次読むもの
- Istio
- containerd 再挑戦
- runc
- コードベース小さい
- kubelet ←これを読む
- buildkit
次回 2/17 Wed!!! kubelet !!!!
特に container 作成周り
@inductor がちょっとだけ予習資料を用意してくれる
ありがとうございました!