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.8k
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
モダンインフラの基礎を学ぼう!実践コンテナ入門
bells17
2
180
Kubernetes Code Contribution入門
bells17
5
950
Dev ContainersとTestcontainers
bells17
3
370
アーキテクチャから学ぶKubernetesの全体像
bells17
19
13k
Controllerを作ってみよう ~ Kubernetes Controllerハンズオン ~
bells17
7
960
Kubernetesに対する理解を高めてKubernetesの「わからない」を減らそう
bells17
19
4.6k
KubernetesとCoreDNSについて理解する
bells17
3
2.2k
KEP-3063: Dynamic resource allocation
bells17
0
300
kube-proxy入門
bells17
9
2.1k
Other Decks in Programming
See All in Programming
推しの夫に恋のGPS「ときメーター」#M5Stack #IoT #M5JPTour2024
riyu
0
220
Pythonで改めて考える「クラス(class)」の使いどころ
os1ma
13
3.4k
CSC509 Lecture 03
javiergs
PRO
0
120
ビット演算の話 / Let's play with bit operations
kaityo256
PRO
3
140
AWS Lambda Web Adapterを活用する新しいサーバーレスの実装パターン
tmokmss
6
5.2k
Modernisation Progressive d’Applications PHP
hhamon
0
160
Kubernetes上でOracle_Databaseの運用を楽にするOraOperatorの紹介
nnaka2992
0
130
"noncopyable types" の使いどころについて考えてみた
andpad
0
110
CSC509 Lecture 01
javiergs
PRO
1
190
"型"のあるRailsアプリケーション開発 / Typed Rails application development
sinsoku
8
2.1k
Removing Corepack
yosuke_furukawa
PRO
9
960
Micro Frontends Unmasked: Opportunities, Challenges, Alternatives
manfredsteyer
PRO
0
250
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
32k
StorybookのUI Testing Handbookを読んだ
zakiyama
26
5.1k
How to name files
jennybc
76
98k
The Invisible Customer
myddelton
119
13k
Automating Front-end Workflow
addyosmani
1365
200k
A Philosophy of Restraint
colly
202
16k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
23
1.7k
Bash Introduction
62gerente
608
210k
GitHub's CSS Performance
jonrohan
1030
450k
Art, The Web, and Tiny UX
lynnandtonic
294
20k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
41
6.5k
Code Reviewing Like a Champion
maltzj
518
39k
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_