Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CRIの仕様とdockershimの実装について調べてみた/CRI spec & docke...
Search
bells17
January 28, 2021
Programming
0
1.9k
CRIの仕様とdockershimの実装について調べてみた/CRI spec & dockershim implementation
Container Runtime Meetup #3
https://runtime.connpass.com/event/198071/
で発表したスライドです
bells17
January 28, 2021
Tweet
Share
More Decks by bells17
See All by bells17
コードを読んで理解するko build
bells17
1
75
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
230
スリーシェイクにおけるOSSの取り組み
bells17
4
330
コミュニティ紹介: Kubernetes Meetup Novice
bells17
1
140
社内活動の取り組み紹介 ~ スリーシェイクでこんな取り組みしてます ~
bells17
1
540
モダンインフラの基礎を学ぼう!実践コンテナ入門
bells17
2
290
Kubernetes Code Contribution入門
bells17
5
1.1k
Dev ContainersとTestcontainers
bells17
3
570
アーキテクチャから学ぶKubernetesの全体像
bells17
20
14k
Other Decks in Programming
See All in Programming
Software Architecture
hschwentner
6
2.1k
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
260
sappoRo.R #12 初心者セッション
kosugitti
0
250
2024年のWebフロントエンドのふりかえりと2025年
sakito
2
250
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
110
Writing documentation can be fun with plugin system
okuramasafumi
0
120
バックエンドのためのアプリ内課金入門 (サブスク編)
qnighy
8
1.8k
法律の脱レガシーに学ぶフロントエンド刷新
oguemon
5
740
Rails アプリ地図考 Flush Cut
makicamel
1
120
Immutable ActiveRecord
megane42
0
140
GAEログのコスト削減
mot_techtalk
0
120
昭和の職場からアジャイルの世界へ
kumagoro95
1
380
Featured
See All Featured
YesSQL, Process and Tooling at Scale
rocio
172
14k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.1k
It's Worth the Effort
3n
184
28k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
960
Embracing the Ebb and Flow
colly
84
4.6k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
100
18k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
A Tale of Four Properties
chriscoyier
158
23k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
Transcript
CRIの仕様とdockershimの実装に ついて調べてみた Container Runtime Meetup #3(2021/01/28) @bells17
▶ @bells17 ▶ Software Engineer ▶ 普段やってること: + Kubernetes 関連コンポーネントの開発
+ Kubernetes as a Service開発の調査・研究 ▶ Kubernetes SIG-Docs Japanese localization reviewer ▶ Kubernetes Internal Organizer ▶ #kubenews ▶ @bells17_
今⽇話すこと ▶ CRIについて ▶ dockershimについて
このセッションの⽬標 ▶ CRIの仕様の構成と内容について、”ふわっと”知ってもらう ▶ dockershimとは何か?を”ざっくりと”理解してもらう ▶ dockershimがどんなふうにDockerと通信してコンテナを起動している のか、”なんとな〜く”雰囲気を感じてもらう
注意点 ▶ コンテナランタイム超絶初⼼者枠です ▶ ついでに以下も初⼼者です + Linuxコンテナ + コンテナ周りのネットワーク ▶
ガチでただの調べてみた系のLTです ▶ ⾼度な内容は期待しないでください!!! ▶ ⼀応dockershimのコードベースは Kubernetes v1.19ベースでのお話になります
アジェンダ 1. CRIとは? 2. dockershimとは? 3. dockershimの挙動 4. まとめ
CRIとは?
CRIとは? ▶ CRI = Container Runtime Interface ▶ Kubernetesが定義しているコンテナランタイムと連携するための仕様が CRI
▶ CRIの定義はDesign Proposal(的なもの)が機能種別ごとに別れており、ま たあまり情報がまとまっていないので、結局現⾏の正しい?CRI全体の仕 様を定義をまとめたドキュメントが無くて分かりづらい ▶ ドキュメントではCRI実装のことをRuntime ShimやCRI Shimと呼んでる ▶ ちなみにまだv1ではないらしい(今はbetaっぽい)
CRI定義の種別 ▶ Protocol Buffer/gRPC Server ▶ Networking Specifications ▶ Container
Metrics ▶ Exec/Attach/PortForward Streaming Requests ▶ Container stdout/stderr logs
Protocol Buffer/gRPC Server ▶ 以下の2種類のServiceに分割されている + Runtime Service: コンテナの操作に関するもの +
Image Service: コンテナイメージの取得などに関するもの ▶ Kubeletの設定値/実装を⾒る限りRuntime ServiceとImage Serviceは 別々のランタイムを使い分けることが可能なように⾒える(詳細不明) ▶ PodSandboxというPodのベースとなるコンテナを作り、Podで定義され たその他のコンテナがSandboxコンテナが作成したネットワーク空間など をシェアしてもらうようなモデル ▶ ⼀応CRIの定義の中にLinuxコンテナだけでなく(micro)VMを使うことを想 定しているようなことも書かれている(でも詳細はほぼ書いてない) https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/container-runtime-interface-v1.md
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/runtime-client-server.md Pod作成時のフロー
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/runtime-client-server.md Pod削除時のフロー
Networking Specifications ▶ CRIのネットワーク周りに関する定義 ▶ “RunPodSandbox” RPC でPodネットワークを設定する必要がある ▶ “StopPodSandbox”
RPC でPodネットワークを停⽌?する必要がある ▶ といったPod操作とその時のネットワークの操作に関する定義がざっくり とされている感じ ▶ CRI networking requirements/k8s networking requirementsが満たされ ている限りは、CNI/CNM/その他の実装でも何でも動くようにという感じ らしい + CRI networking requirementsは“RunPodSandbox” RPC ~といった 部分だと思われる https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/kubelet-cri-networking.md
k8s networking requirements ▶ ノード上のPodが、NATなしですべてのノード上のすべてのPodと通信で きること ▶ systemdやkubeletなどノード上にあるエージェントが、そのノード上の すべてのPodと通信できること ▶
ノードのホストネットワーク内のPodは、NATなしですべてのノード上の すべてのPodと通信できること + 注: ホストネットワークで実⾏されるPodをサポートする プラットフォームの場合(Linuxなど)は https://kubernetes.io/docs/concepts/cluster-administration/networking/
Container Metrics ▶ コンテナランタイムから取得できるメトリクス情報を抽象化したもの ▶ 取得できるメトリクス情報がProtocol Bufferによって定義されている ▶ メトリクスの取得⾃体はRuntime ServiceからRPCコールで取得できる
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md
Exec/Attach/PortForward Streaming Requests ▶ Exec/Attach/PortForwardそれぞれのストリーミングリクエストの⽅法につ いて定義されている ▶ Exec/Attach/PortForward⾃体はRuntime Serviceに対してRPCコールで呼び 出せる
▶ Exec/Attach/PortForwardリクエストをShimが受け付けるとリクエストを受 け付けるサーバーを起動し、起動したサーバーのポート情報を返し、Kubelet がAPI Serverからのリクエストを返されたポートにリダイレクトする ▶ API ServerではリダイレクトされたShimの起動されたサーバーに接続を⾏い Exec/Attach/PortForwardの処理を⾏う ▶ API Server - Shim間の認証/認可はKubeletと同様に証明書などを利⽤する ▶ のような感じで書いてはあるが、Kubeletの実装は書いてる事と結構違う https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/edit#heading=h.4yfjiw58o8d3
Execなどでコンテナに接続するまでのフロー https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/edit#heading=h.4yfjiw58o8d3
Execなどでコンテナに接続するまでのフロー(実際) https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/edit#heading=h.4yfjiw58o8d3
Container stdout/stderr logs ▶ Kubernetesがコンテナのストリーミングstdout/stderrログを扱うための 仕様 ▶ KubeletがPodSandboxコンテナ起動時に /var/log/pods/<podUID>/ ディ
レクトリを作成する ▶ CRI Shimは(Sandboxコンテナ以外の)各種コンテナを起動する際にコンテ ナのログが /var/log/pods/<podUID>/<containerName>_<instance#>.log に出⼒されるように設定を⾏う ▶ ログフォーマットは以下のようになっている必要がある + プレフィックスにRFC 3339Nano timestamp + ストリームタイプが付き + 改⾏で終わる https://github.com/kubernetes/kubernetes/blob/release-1.5/docs/proposals/kubelet-cri-logging.md
dockershimとは?
dockershimとは? ▶ コンテナランタイムにDockerを使⽤する際に、Kubeletが内部で起動する Docker⽤のCRI Shim実装 ▶ Kubelet内部でgoroutineとして起動される ▶ 内部は以下の3区分のアプリケーションとなっている +
Streaming Server: kubectl execやkubectl port-forwardなどをプロキシする tcpサーバー + gRPC Server: CRIのServiceを実装したgRPC Server + Container Manager: コンテナプロセスのoom_score_adjの設定などを⾏う ▶ Kubernetes v1.22 で削除される予定となっている ▶ 主にContainer Manager周りが独⽴しておらず、その他のKubeletの処理で Container Managerなどの操作を⾏っていたりする ▶ ここらへんの保守コストが原因で削除されることになったのでは?と予想
None
dockershimの特徴 ▶ RunPodSandbox/StartContainerなどのRPCコールの裏側でDockerのライ ブラリを使って普通にDockerのAPI呼び出しを⾏っている ▶ なので普通にdocker create/docker startのようなdockerコマンドに変換 して読んでいくことが可能 +
ただし、dockerコマンドで渡せる様々なオプションがどういったことを しているのかの理解は必要(誰か教えて…) ▶ そのためdockerコマンドを使ってどのようにdockershimがコンテナを作 成~起動などをしているかの勉強になる(気がしている)
dockershimの挙動
RunPodSandbox ▶ もし⼿元にSandboxコンテナ⽤のイメージがなければ、イメージのPullを⾏う ▶ Sandboxコンテナ⽤のdocker createのコンフィグを⽣成 ▶ docker create相当のAPIを呼び出し⽣成したコンフィグに沿ったSandboxコン テナを作成
▶ 作成したコンテナのPortMapping情報など(Checkpoint)をファイルに保存 ▶ docker start相当のAPIを呼び出しSandboxコンテナを起動 ▶ resolv.confを⽣成し、Sandboxコンテナに保存 ▶ ネットワークプラグインを使⽤してPod間ネットワーク?を設定 + CNIを利⽤している場合にはCNIのAddNetworkListというRPCが呼び出され るよう
CreateContainer ▶ 作成するコンテナ⽤のdocker createのコンフィグを⽣成 ▶ Sandboxコンテナの情報を元にコンフィグをアップデート ▶ docker create相当のAPIを呼び出し⽣成したコンフィグに沿ってコンテナ を作成
StartContainer ▶ docker start相当のAPIを呼び出し対象となるコンテナを起動 ▶ /var/log/pods/<podUID>/<containerName>_<instance#>.log パスに起動 したコンテナのログファイルのシンボリックリンクを作成
Exec(Attach/PortForwardも同じ) ▶ API ServerからKubeletに /exec/{podNamespace}/{podID}/{containerName} といったWebSocketエンドポイントにGET or POSTリクエストが送られる ▶ リクエストを受けるとKubeletは以下のような処理を⾏う
+ 認証のためのトークンを発⾏ + 実際にコンテナにexecを⾏うための /exec/{token} エンドポイントを⽣成 + このエンドポイントにプロキシを⾏うプロキシサーバーを起動 + プロキシされて /exec/{token} にリクエストが送られると、内部で dockershimのExec RPCをリクエストする + dockershimのExecでは内部でdocker exec相当の処理を⾏い、コンテナ にexecを⾏う
まとめ
まとめ ▶ Kubernetesにはコンテナランタイムとやり取りをする仕様であるContainer Runtime Interface(CRI)がある ▶ CRIではKubernetesのPodを起動したり、コンテナにexecするためのRPCコールの定義が されている ▶ dockershimはDocker向けのCRI実装(CRI(Runtime)
Shim) ▶ dockershimはStreaming(tcp) Server/gRPC Server/Container Managerの3つのアプリケー ションによって構成されている ▶ dockershimの中⾝はdocker cliに変換して考えられるような実装の組み合わせになっている
感想 ▶ CRIの仕様はCSIに⽐べると結構ざっくりしてるなーという印象だったのですが、CRIの様々 な仕様についてスライドにまとめていく過程でなんとなくCRIの仕様の全体像がイメージで きる感じになってきてよかったです ▶ また、dockershim側の実装についても調べることで、CRIのイメージがより具体化された なという感じでした ▶ とはいえdocker
createで実際に指定しているオプション(コンフィグ)の具体的な設定値に ついてはまだ調べきれてないので、次はそこらへんについてまとめてみたいなと思いました
参考資料 ▶ Kubernetes v1.19: https://github.com/kubernetes/kubernetes/tree/release-1.19 ▶ CRI: the Container Runtime
Interface: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md ▶ Container Runtime Interface (CRI) Networking Specifications: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/kubelet-cri- networking.md ▶ Container Runtime Interface: Container Metrics: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md ▶ CRI Streaming Requests (exec/attach/port-forward): https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/ edit#heading=h.4yfjiw58o8d3 ▶ CRI: Log management for container stdout/stderr streams: https://github.com/kubernetes/kubernetes/blob/release-1.5/docs/proposals/kubelet-cri-logging.md ▶ Client/Server container runtime: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/runtime-client-server.md ▶ Redefine Container Runtime Interface: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/container-runtime- interface-v1.md ▶ Add a new container runtime interface: https://github.com/kubernetes/kubernetes/pull/25899 ▶ Kubelet CRI support: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2040-kubelet-cri ▶ libnetwork design: https://github.com/moby/libnetwork/blob/master/docs/design.md ▶ Kubelet network plugin for client/server container runtimes: https://github.com/kubernetes/kubernetes/issues/28667 ▶ Cluster Networking: https://kubernetes.io/docs/concepts/cluster-administration/networking/ ▶ containernetworking/cni: https://github.com/containernetworking/cni ▶ Core Metrics in kubelet: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/core-metrics-pipeline.md ▶ Kubernetes monitoring architecture: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/ monitoring_architecture.md
唐突ですがKubeletについてはこの 本にまとめています書いてます ▶ 技術書典: http://bit.ly/tbf-kubelet ▶ Booth: http://bit.ly/booth-kubelet Kubeletの詳細が気になる⽅は 良ければ買ってください!
また ▶ Kubeletの概要についてはJFT 2021 Winter ▶ Kubeletのコードがどんなふうになっているかは Kubernetes Internal #4 でそれぞれ説明してますので興味があればどうぞ!
Thanks / Question? ▶ @bells17 ▶ Slide: https://speakerdeck.com/bells17 ▶ @bells17_