Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CRIの仕様とdockershimの実装について調べてみた/CRI spec & dockershim implementation

bells17
January 28, 2021

CRIの仕様とdockershimの実装について調べてみた/CRI spec & dockershim implementation

Container Runtime Meetup #3
https://runtime.connpass.com/event/198071/
で発表したスライドです

bells17

January 28, 2021
Tweet

More Decks by bells17

Other Decks in Programming

Transcript

  1. CRIの仕様とdockershimの実装に
    ついて調べてみた
    Container Runtime Meetup #3(2021/01/28)
    @bells17

    View full-size slide

  2. ▶ @bells17
    ▶ Software Engineer
    ▶ 普段やってること:
    + Kubernetes 関連コンポーネントの開発
    + Kubernetes as a Service開発の調査・研究
    ▶ Kubernetes SIG-Docs Japanese localization reviewer
    ▶ Kubernetes Internal Organizer
    ▶ #kubenews
    ▶ @bells17_

    View full-size slide

  3. 今⽇話すこと
    ▶ CRIについて
    ▶ dockershimについて

    View full-size slide

  4. このセッションの⽬標
    ▶ CRIの仕様の構成と内容について、”ふわっと”知ってもらう
    ▶ dockershimとは何か?を”ざっくりと”理解してもらう
    ▶ dockershimがどんなふうにDockerと通信してコンテナを起動している
    のか、”なんとな〜く”雰囲気を感じてもらう

    View full-size slide

  5. 注意点
    ▶ コンテナランタイム超絶初⼼者枠です
    ▶ ついでに以下も初⼼者です
    + Linuxコンテナ
    + コンテナ周りのネットワーク
    ▶ ガチでただの調べてみた系のLTです
    ▶ ⾼度な内容は期待しないでください!!!
    ▶ ⼀応dockershimのコードベースは
    Kubernetes v1.19ベースでのお話になります

    View full-size slide

  6. アジェンダ
    1. CRIとは?
    2. dockershimとは?
    3. dockershimの挙動
    4. まとめ

    View full-size slide

  7. CRIとは?

    View full-size slide

  8. CRIとは?
    ▶ CRI = Container Runtime Interface
    ▶ Kubernetesが定義しているコンテナランタイムと連携するための仕様が
    CRI
    ▶ CRIの定義はDesign Proposal(的なもの)が機能種別ごとに別れており、ま
    たあまり情報がまとまっていないので、結局現⾏の正しい?CRI全体の仕
    様を定義をまとめたドキュメントが無くて分かりづらい
    ▶ ドキュメントではCRI実装のことをRuntime ShimやCRI Shimと呼んでる
    ▶ ちなみにまだv1ではないらしい(今はbetaっぽい)

    View full-size slide

  9. CRI定義の種別
    ▶ Protocol Buffer/gRPC Server
    ▶ Networking Specifications
    ▶ Container Metrics
    ▶ Exec/Attach/PortForward Streaming Requests
    ▶ Container stdout/stderr logs

    View full-size slide

  10. 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

    View full-size slide

  11. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/runtime-client-server.md
    Pod作成時のフロー

    View full-size slide

  12. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/runtime-client-server.md
    Pod削除時のフロー

    View full-size slide

  13. 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

    View full-size slide

  14. k8s networking requirements
    ▶ ノード上のPodが、NATなしですべてのノード上のすべてのPodと通信で
    きること
    ▶ systemdやkubeletなどノード上にあるエージェントが、そのノード上の
    すべてのPodと通信できること
    ▶ ノードのホストネットワーク内のPodは、NATなしですべてのノード上の
    すべてのPodと通信できること
    + 注: ホストネットワークで実⾏されるPodをサポートする
    プラットフォームの場合(Linuxなど)は
    https://kubernetes.io/docs/concepts/cluster-administration/networking/

    View full-size slide

  15. Container Metrics
    ▶ コンテナランタイムから取得できるメトリクス情報を抽象化したもの
    ▶ 取得できるメトリクス情報がProtocol Bufferによって定義されている
    ▶ メトリクスの取得⾃体はRuntime ServiceからRPCコールで取得できる
    https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md

    View full-size slide

  16. 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

    View full-size slide

  17. Execなどでコンテナに接続するまでのフロー
    https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/edit#heading=h.4yfjiw58o8d3

    View full-size slide

  18. Execなどでコンテナに接続するまでのフロー(実際)
    https://docs.google.com/document/d/1OE_QoInPlVCK9rMAx9aybRmgFiVjHpJCHI9LrfdNM_s/edit#heading=h.4yfjiw58o8d3

    View full-size slide

  19. Container stdout/stderr logs
    ▶ Kubernetesがコンテナのストリーミングstdout/stderrログを扱うための
    仕様
    ▶ KubeletがPodSandboxコンテナ起動時に /var/log/pods// ディ
    レクトリを作成する
    ▶ CRI Shimは(Sandboxコンテナ以外の)各種コンテナを起動する際にコンテ
    ナのログが /var/log/pods//_.log
    に出⼒されるように設定を⾏う
    ▶ ログフォーマットは以下のようになっている必要がある
    + プレフィックスにRFC 3339Nano timestamp + ストリームタイプが付き
    + 改⾏で終わる
    https://github.com/kubernetes/kubernetes/blob/release-1.5/docs/proposals/kubelet-cri-logging.md

    View full-size slide

  20. dockershimとは?

    View full-size slide

  21. 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などの操作を⾏っていたりする
    ▶ ここらへんの保守コストが原因で削除されることになったのでは?と予想

    View full-size slide

  22. dockershimの特徴
    ▶ RunPodSandbox/StartContainerなどのRPCコールの裏側でDockerのライ
    ブラリを使って普通にDockerのAPI呼び出しを⾏っている
    ▶ なので普通にdocker create/docker startのようなdockerコマンドに変換
    して読んでいくことが可能
    + ただし、dockerコマンドで渡せる様々なオプションがどういったことを
    しているのかの理解は必要(誰か教えて…)
    ▶ そのためdockerコマンドを使ってどのようにdockershimがコンテナを作
    成~起動などをしているかの勉強になる(気がしている)

    View full-size slide

  23. dockershimの挙動

    View full-size slide

  24. RunPodSandbox
    ▶ もし⼿元にSandboxコンテナ⽤のイメージがなければ、イメージのPullを⾏う
    ▶ Sandboxコンテナ⽤のdocker createのコンフィグを⽣成
    ▶ docker create相当のAPIを呼び出し⽣成したコンフィグに沿ったSandboxコン
    テナを作成
    ▶ 作成したコンテナのPortMapping情報など(Checkpoint)をファイルに保存
    ▶ docker start相当のAPIを呼び出しSandboxコンテナを起動
    ▶ resolv.confを⽣成し、Sandboxコンテナに保存
    ▶ ネットワークプラグインを使⽤してPod間ネットワーク?を設定
    + CNIを利⽤している場合にはCNIのAddNetworkListというRPCが呼び出され
    るよう

    View full-size slide

  25. CreateContainer
    ▶ 作成するコンテナ⽤のdocker createのコンフィグを⽣成
    ▶ Sandboxコンテナの情報を元にコンフィグをアップデート
    ▶ docker create相当のAPIを呼び出し⽣成したコンフィグに沿ってコンテナ
    を作成

    View full-size slide

  26. StartContainer
    ▶ docker start相当のAPIを呼び出し対象となるコンテナを起動
    ▶ /var/log/pods//_.log パスに起動
    したコンテナのログファイルのシンボリックリンクを作成

    View full-size slide

  27. 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を⾏う

    View full-size slide

  28. まとめ
    ▶ 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に変換して考えられるような実装の組み合わせになっている

    View full-size slide

  29. 感想
    ▶ CRIの仕様はCSIに⽐べると結構ざっくりしてるなーという印象だったのですが、CRIの様々
    な仕様についてスライドにまとめていく過程でなんとなくCRIの仕様の全体像がイメージで
    きる感じになってきてよかったです
    ▶ また、dockershim側の実装についても調べることで、CRIのイメージがより具体化された
    なという感じでした
    ▶ とはいえdocker createで実際に指定しているオプション(コンフィグ)の具体的な設定値に
    ついてはまだ調べきれてないので、次はそこらへんについてまとめてみたいなと思いました

    View full-size slide

  30. 参考資料
    ▶ 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

    View full-size slide

  31. 唐突ですがKubeletについてはこの
    本にまとめています書いてます
    ▶ 技術書典: http://bit.ly/tbf-kubelet
    ▶ Booth: http://bit.ly/booth-kubelet
    Kubeletの詳細が気になる⽅は
    良ければ買ってください!
    また
    ▶ Kubeletの概要についてはJFT 2021 Winter
    ▶ Kubeletのコードがどんなふうになっているかは
    Kubernetes Internal #4
    でそれぞれ説明してますので興味があればどうぞ!

    View full-size slide

  32. Thanks / Question?
    ▶ @bells17
    ▶ Slide: https://speakerdeck.com/bells17
    ▶ @bells17_

    View full-size slide