$30 off During Our Annual Pro Sale. View Details »
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
2.1k
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
TFLintカスタムプラグインで始める Terraformコード品質管理
bells17
2
650
Amazon VPC CNIに学ぶCNI-LT版
bells17
2
200
コードを読んで理解するko build
bells17
1
460
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
480
スリーシェイクにおけるOSSの取り組み
bells17
4
580
コミュニティ紹介: Kubernetes Meetup Novice
bells17
1
300
社内活動の取り組み紹介 ~ スリーシェイクでこんな取り組みしてます ~
bells17
1
710
モダンインフラの基礎を学ぼう!実践コンテナ入門
bells17
2
440
Kubernetes Code Contribution入門
bells17
5
1.4k
Other Decks in Programming
See All in Programming
Tinkerbellから学ぶ、Podで DHCPをリッスンする手法
tomokon
0
120
ID管理機能開発の裏側 高速にSaaS連携を実現したチームのAI活用編
atzzcokek
0
220
なあ兄弟、 余白の意味を考えてから UI実装してくれ!
ktcryomm
11
11k
AtCoder Conference 2025「LLM時代のAHC」
imjk
2
390
STYLE
koic
0
160
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
6
1.3k
エディターってAIで操作できるんだぜ
kis9a
0
710
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
140
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
270
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
370
ゲームの物理 剛体編
fadis
0
330
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
8
20k
Featured
See All Featured
It's Worth the Effort
3n
187
29k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Six Lessons from altMBA
skipperchong
29
4.1k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3k
A Tale of Four Properties
chriscoyier
162
23k
Balancing Empowerment & Direction
lara
5
790
Embracing the Ebb and Flow
colly
88
4.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Thoughts on Productivity
jonyablonski
73
5k
GitHub's CSS Performance
jonrohan
1032
470k
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_