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. ▶ @bells17 ▶ Software Engineer ▶ 普段やってること: + Kubernetes 関連コンポーネントの開発

    + Kubernetes as a Service開発の調査・研究 ▶ Kubernetes SIG-Docs Japanese localization reviewer ▶ Kubernetes Internal Organizer ▶ #kubenews ▶ @bells17_
  2. 注意点 ▶ コンテナランタイム超絶初⼼者枠です ▶ ついでに以下も初⼼者です + Linuxコンテナ + コンテナ周りのネットワーク ▶

    ガチでただの調べてみた系のLTです ▶ ⾼度な内容は期待しないでください!!! ▶ ⼀応dockershimのコードベースは Kubernetes v1.19ベースでのお話になります
  3. CRIとは? ▶ CRI = Container Runtime Interface ▶ Kubernetesが定義しているコンテナランタイムと連携するための仕様が CRI

    ▶ CRIの定義はDesign Proposal(的なもの)が機能種別ごとに別れており、ま たあまり情報がまとまっていないので、結局現⾏の正しい?CRI全体の仕 様を定義をまとめたドキュメントが無くて分かりづらい ▶ ドキュメントではCRI実装のことをRuntime ShimやCRI Shimと呼んでる ▶ ちなみにまだv1ではないらしい(今はbetaっぽい)
  4. CRI定義の種別 ▶ Protocol Buffer/gRPC Server ▶ Networking Specifications ▶ Container

    Metrics ▶ Exec/Attach/PortForward Streaming Requests ▶ Container stdout/stderr logs
  5. 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
  6. 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
  7. k8s networking requirements ▶ ノード上のPodが、NATなしですべてのノード上のすべてのPodと通信で きること ▶ systemdやkubeletなどノード上にあるエージェントが、そのノード上の すべてのPodと通信できること ▶

    ノードのホストネットワーク内のPodは、NATなしですべてのノード上の すべてのPodと通信できること + 注: ホストネットワークで実⾏されるPodをサポートする プラットフォームの場合(Linuxなど)は https://kubernetes.io/docs/concepts/cluster-administration/networking/
  8. 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
  9. 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
  10. 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などの操作を⾏っていたりする ▶ ここらへんの保守コストが原因で削除されることになったのでは?と予想
  11. dockershimの特徴 ▶ RunPodSandbox/StartContainerなどのRPCコールの裏側でDockerのライ ブラリを使って普通にDockerのAPI呼び出しを⾏っている ▶ なので普通にdocker create/docker startのようなdockerコマンドに変換 して読んでいくことが可能 +

    ただし、dockerコマンドで渡せる様々なオプションがどういったことを しているのかの理解は必要(誰か教えて…) ▶ そのためdockerコマンドを使ってどのようにdockershimがコンテナを作 成~起動などをしているかの勉強になる(気がしている)
  12. RunPodSandbox ▶ もし⼿元にSandboxコンテナ⽤のイメージがなければ、イメージのPullを⾏う ▶ Sandboxコンテナ⽤のdocker createのコンフィグを⽣成 ▶ docker create相当のAPIを呼び出し⽣成したコンフィグに沿ったSandboxコン テナを作成

    ▶ 作成したコンテナのPortMapping情報など(Checkpoint)をファイルに保存 ▶ docker start相当のAPIを呼び出しSandboxコンテナを起動 ▶ resolv.confを⽣成し、Sandboxコンテナに保存 ▶ ネットワークプラグインを使⽤してPod間ネットワーク?を設定 + CNIを利⽤している場合にはCNIのAddNetworkListというRPCが呼び出され るよう
  13. 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を⾏う
  14. まとめ ▶ 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に変換して考えられるような実装の組み合わせになっている
  15. 参考資料 ▶ 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
  16. 唐突ですがKubeletについてはこの 本にまとめています書いてます ▶ 技術書典: http://bit.ly/tbf-kubelet ▶ Booth: http://bit.ly/booth-kubelet Kubeletの詳細が気になる⽅は 良ければ買ってください!

    また ▶ Kubeletの概要についてはJFT 2021 Winter ▶ Kubeletのコードがどんなふうになっているかは Kubernetes Internal #4 でそれぞれ説明してますので興味があればどうぞ!