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

Kubernetesをとりまくコンテナランタイムの栄枯盛衰 / The rise and fall of the container runtimes surrounding Kubernetes

Kubernetesをとりまくコンテナランタイムの栄枯盛衰 / The rise and fall of the container runtimes surrounding Kubernetes

A talk at Kubernetes Novice Tokyo #10

Kohei Ota

May 12, 2021
Tweet

More Decks by Kohei Ota

Other Decks in Technology

Transcript

  1. Kubernetesをとりまく
    コンテナランタイムの栄枯盛衰
    Presented by @inductor

    View full-size slide

  2. 今日の目標
    ● コンテナランタイムがどうしてDockerだけじゃないのかを知る
    ● コンテナランタイムの歴史を知ることで、Kubernetesで動かす
    アプリケーションの裏側について少しだけ詳しくなる
    ● ランタイムの選択肢にはどんなものがあって、どんな特徴があるのかを
    知ることで、Docker非推奨の話の裏側を少し理解できる

    View full-size slide

  3. 2019年の夏...
    ↓こんな話をしました

    View full-size slide

  4. Kubernetesの特徴(リリース時)
    ● Google Borgの10年以上に渡る運用知見を集約した基盤のOSS
    ○ リリース当初はGoogleがメインで開発
    ● Docker、etcdを中心とした分散型コンテナ実行基盤
    ● APIを起点に、etcdに書かれたステートを正とし
    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム
    ● 管理用のマスター、実行用のミニオンと呼ばれるマシンからなる

    View full-size slide

  5. Kubernetesの特徴(現在)
    ● Google Borgの10年以上に渡る運用知見を集約した基盤のOSS
    ○ CNCFがホスティング、コミュニティを主体とした開発体制
    ● コンテナランタイム、etcdを中心とした分散型コンテナ実行基盤
    ● APIを起点に、etcdに書かれたステートを正とし
    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム
    ● 管理用のコントロールプレーン、実行用のワーカーからなる

    View full-size slide

  6. Kubernetesの特徴(現在)
    ● Google Borgの10年以上に渡る運用知見を集約した基盤のOSS
    ○ CNCFがホスティング、コミュニティを主体とした開発体制
    ● コンテナランタイム、etcdを中心とした分散型コンテナ実行基盤
    ● APIを起点に、etcdに書かれたステートを正とし
    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム
    ● 管理用のコントロールプレーン、実行用のワーカーからなる
    Dockerが非推奨になったの!?
    で話題になった1.20.0リリース時のアレ

    View full-size slide

  7. ランタイムのこれまでについて
    お話していきます

    View full-size slide

  8. Kubernetes初期のランタイムとの関係
    ● Google Borgの10年以上に渡る運用知見を集約した基盤のOSS
    ○ リリース当初はGoogleがメインで開発
    ● Docker、etcdを中心とした分散型コンテナ実行基盤
    ● APIを起点に、etcdに書かれたステートを正とし
    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム
    ● 管理用のマスター、実行用のミニオンと呼ばれるマシンからなる

    View full-size slide

  9. Kubernetes 1.0 当時の実装
    https://github.com/kubernetes/kubernetes/blob/release-1.0/pkg/kubelet/dock
    ertools/manager.go
    kubeletのdockertools配下にDockerのための実装があった
    → 完全にDockerで動くことだけを想定

    View full-size slide

  10. Kubernetes 1.0 当時の実装
    https://github.com/kubernetes/kubernetes/blob/release-1.0/pkg/kubelet/dock
    ertools/manager.go
    kubeletのdockertools配下にDockerのための実装があった
    → 完全にDockerで動くことだけを想定
    ちょっとだけソースの中身を覗い
    てみましょう

    View full-size slide

  11. Kubernetes 1.0 当時の実装
    https://github.com/kubernetes/kubernetes/blob/release-1.0/pkg/kubelet/dock
    ertools/manager.go
    kubeletのdockertools配下にDockerのための実装があった
    → 完全にDockerで動くことだけを想定
    docker周りの実装
    rkt周りの実装(!)

    View full-size slide

  12. rktとはなんだったのか
    ● CoreOS社(Red Hatが2018年に買収)が作ったコンテナランタイム
    ○ CoreOS社は他にもetcdやコンテナホスト用LinuxディストロCoreOSを開発するなど、
    Kubernetesのエコシステムに貢献してきた
    ○ CoreOS Meetup Tokyo #1 の資料を見ると当時の状況がよくわかって面白い
    ● Docker社が事実上独占していたコンテナのエコシステムを打破する
    きっかけになった
    ○ Dockerはデーモンを配置してノード上に常駐させるモデルなのに対し、 rktはsystemdによる隔
    離を応用した”デーモンレス”なコンテナ技術
    ○ Dockerとは違いPodのネイティブサポートをするなど、 Kubernetesの仕組みを意識

    View full-size slide

  13. rktとはなんだったのか
    ● CoreOS社(Red Hatが2018年に買収)が作ったコンテナランタイム
    ○ CoreOS社は他にもetcdやコンテナホスト用LinuxディストロCoreOSを開発するなど、
    Kubernetesのエコシステムに貢献してきた
    ○ CoreOS Meetup Tokyo #1 の資料を見ると当時の状況がよくわかって面白い
    ● Docker社が事実上独占していたコンテナのエコシステムを打破するきっかけに
    なった
    ○ Dockerはデーモンを配置してノード上に常駐させるモデルなのに対し、 rktはsystemdによる隔
    離を応用した”デーモンレス”なコンテナ技術
    ○ Dockerとは違いPodのネイティブサポートをするなど、 Kubernetesの仕組みを意識
    https://kubernetes.io/blog/2016/07/rktnetes-brings-rkt-container-engine-to-kubernetes/

    View full-size slide

  14. rktとはなんだったのか
    ● CoreOS社(Red Hatが2018年に買収)が作ったコンテナランタイム
    ○ CoreOS社は他にもetcdやコンテナホスト用LinuxディストロCoreOSを開発するなど、
    Kubernetesのエコシステムに貢献してきた
    ○ CoreOS Meetup Tokyo #1 の資料を見ると当時の状況がよくわかって面白い
    ● Docker社が事実上独占していたコンテナのエコシステムを打破するきっかけに
    なった
    ○ Dockerはデーモンを配置してノード上に常駐させるモデルなのに対し、 rktはsystemdによる隔
    離を応用した”デーモンレス”なコンテナ技術
    ○ Dockerとは違いPodのネイティブサポートをするなど、 Kubernetesの仕組みを意識
    https://kubernetes.io/blog/2016/07/rktnetes-brings-rkt-container-engine-to-kubernetes/
    https://speakerdeck.com/ytaka23/mao-demowakaru-rkt-plus-kubernetes-number-ichigayageek

    View full-size slide

  15. Kubernetes 1.3: rktをランタイムとして採用
    ● これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを
    外部注入可能な形に置き換えるきっかけに
    ● コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した
    「secure by default」な実装
    ● UNIX哲学に基づいたシンプルなプロセスモデル
    ○ Dockerdがないのでrkt process = pod process
    ● 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽
    量VMへの対応など夢がてんこ盛り

    View full-size slide

  16. Kubernetes 1.3: rktをランタイムとして採用
    ● これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを
    外部注入可能な形に置き換えるきっかけに
    ● コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した
    「secure by default」な実装
    ● UNIX哲学に基づいたシンプルなプロセスモデル
    ○ Dockerdがないのでrkt process = pod process
    ● 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽
    量VMへの対応など夢がてんこ盛り systemdによるisolation
    (その他kvm等も選べる)

    View full-size slide

  17. Kubernetes 1.3: rktをランタイムとして採用
    ● これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを
    外部注入可能な形に置き換えるきっかけに
    ● コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した
    「secure by default」な実装
    ● UNIX哲学に基づいたシンプルなプロセスモデル
    ○ Dockerdがないのでrkt process = pod process
    ● 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽
    量VMへの対応など夢がてんこ盛り
    flyと呼ばれる分離とオーバー
    ヘッドが少ないシンプルなモー
    ドもあった

    View full-size slide

  18. Kubernetes 1.3: rktをランタイムとして採用
    ● これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを
    外部注入可能な形に置き換えるきっかけに
    ● コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した
    「secure by default」な実装
    ● UNIX哲学に基づいたシンプルなプロセスモデル
    ○ Dockerdがないのでrkt process = pod process
    ● 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽
    量VMへの対応など夢がてんこ盛り
    flyと呼ばれる分離とオーバー
    ヘッドが少ないシンプルなモー
    ドもあった
    systemdでプロセスを管理
    (Podの初期化など)
    APIサービス経由で任意の
    コマンド実行したり
    https://speakerdeck.com/surbaniak/meetup-london-2016-rkt-plus-kubernetes

    View full-size slide

  19. Kubernetes 1.3: rktをランタイムとして採用
    ● これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを
    外部注入可能な形に置き換えるきっかけに
    ● コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した
    「secure by default」な実装
    ● UNIX哲学に基づいたシンプルなプロセスモデル
    ○ Dockerdがないのでrkt process = pod process
    ● 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽
    量VMへの対応など夢がてんこ盛り
    flyと呼ばれる分離とオーバー
    ヘッドが少ないシンプルなモー
    ドもあった
    systemdでプロセスを管理
    (Podの初期化など)
    APIサービス経由で任意の
    コマンド実行したり
    https://speakerdeck.com/surbaniak/meetup-london-2016-rkt-plus-kubernetes
    よさそうでは?

    View full-size slide

  20. Kubernetes 1.5: CRIの登場
    ● これまでDockerに依存していた部分を、(Kubernetesにとって)コンテナを動かす
    ための仕組み、すなわち「CRI(Container Runtime Interface)」として仕様を定

    ○ ノード上にDaemonを配置
    ○ イメージとコンテナを操作するための gRPCサービス(サーバーの存在が前提 )
    ○ ランタイムを外部ソケット通信にすることで Kubernetes側とライフサイクルを切り離し

    View full-size slide

  21. なぜCRI?
    ● ランタイムに依存するコードがKubernetes内部に多かった
    ○ rktにしてもDockerにしても、それぞれが持つ APIを呼び出すためのコード
    ○ 各ランタイムのバージョンに依存する修正が発生すると、 Kubernetesに変更が発生
    ○ 各ランタイム自体(特にDocker)はKubernetesだけを対象にしてないので、容赦なしに変更を加
    えてバージョンアップしてくる
    ● 外部コンポーネント化することで関心を分離しないとメンテナンスが大変
    ○ Kubeletは各ノードにいるので、 gRPC over UNIX Socketな構成が都合よかった
    ○ 結局DockerもMoby projectを発表し、containerdがのちにCRIランタイムとして台頭

    View full-size slide

  22. こまったrktくん
    ● デーモンレスなプロセスモデル
    ○ KubernetesがCRIを発表したので、なくなく CRIに対応せざるを得ない状況に
    ● ランタイムでの再実装が不要なgRPCによる命令型のAPIモデル
    ○ rktはsystemdでPod(プロセス)を立ち上げてハイ終わりなモデルなので厳しい
    ● rktletとか作っていろいろ頑張るも、2019年にはプロジェクトの凍結が発表され

    ○ CNCFプロジェクトとしては (自分が知る限りは)いまだ唯一の”Archived”プロジェクト
    https://www.cncf.io/blog/2019/08/16/cncf-archives-the-rkt-project/

    View full-size slide

  23. こまったrktくん
    ● デーモンレスなプロセスモデル
    ○ KubernetesがCRIを発表したので、なくなく CRIに対応せざるを得ない状況に
    ● ランタイムでの再実装が不要なgRPCによる命令型のAPIモデル
    ○ rktはsystemdでPod(プロセス)を立ち上げてハイ終わりなモデルなので厳しい
    ● rktletとか作っていろいろ頑張るも、2019年にはプロジェクトの凍結が発表され

    ○ CNCFプロジェクトとしては (自分が知る限りは)いまだ唯一の”Archived”プロジェクト
    https://www.cncf.io/blog/2019/08/16/cncf-archives-the-rkt-project/

    View full-size slide

  24. rktの意思を継ぐもの、OCID(CRI-O)とPodman
    ● Red Hatが2016年に発表したOCIDは現在CRI-Oという名前で現役で活躍
    ○ Linuxケイパビリティの制限やセキュリティ周りの対応など、 rktでも培われたいくつかの思想が
    垣間見える
    ○ Red Hat OpenShift 4からはデフォルトのランタイムに採用
    ● デーモンレスなコンテナランタイム「Podman」
    ○ Red Hatを主体としたオープンソースプロジェクトとして現在も鋭意開発中
    ○ Docker Compose互換な実装やネットワークへの対応、ユーザー名前空間の実装など、デーモ
    ンを使わずによく頑張ってるなと思う

    View full-size slide

  25. rktの意思を継ぐもの、OCID(CRI-O)とPodman
    ● Red Hatが2016年に発表したOCIDは現在CRI-Oという名前で現役で活躍
    ○ Linuxケイパビリティの制限やセキュリティ周りの対応など、 rktでも培われたいくつかの思想が
    垣間見える
    ○ Red Hat OpenShift 4からはデフォルトのランタイムに採用
    ● デーモンレスなコンテナランタイム「Podman」
    ○ Red Hatを主体としたオープンソースプロジェクトとして現在も鋭意開発中
    ○ Docker Compose互換な実装やネットワークへの対応、ユーザー名前空間の実装など、デーモ
    ンを使わずによく頑張ってるなと思う
    ● 手元のDockerを置き換えるPodman
    ● Kubernetesのために作られたランタイムとしてのCRI-O
    それぞれの違いを理解して使い分けてみるのも良いかもし
    れません

    View full-size slide

  26. 閑話休題:
    Dockerをやめるのはどうなのか

    View full-size slide

  27. Dockerが持つ主な3つのサービス
    ● ランタイムサービス
    ○ Containerdが管理するコンテナを動かすためのコア
    ● ネットワークサービス
    ○ docker network 配下のAPI
    ● ボリュームサービス
    ○ docker volume 配下のAPI

    View full-size slide

  28. Kubernetesが使うDockerの機能...
    ● ランタイムサービス
    ○ Containerdが管理するコンテナを動かすためのコア
    ● ネットワークサービス
    ○ docker network 配下のAPI
    ● ボリュームサービス
    ○ docker volume 配下のAPI
    つかう
    つかわない

    View full-size slide

  29. Kubernetesが持つ複数のインターフェース
    ● CRI
    ○ ランタイム
    ● CNI
    ○ ネットワーク
    ● CSI
    ○ ストレージ
    ● CPI
    ○ クラウドプロバイダー
    Dockerはどのレイヤとも被りうる・・・

    View full-size slide

  30. Dockershimの存在
    https://jaco.udcp.info/entry/2020/12/03/172843
    CRIの登場により
    CRI -> Docker API変換のため
    のDockershimが登場

    View full-size slide

  31. CRI対応済みランタイム
    ● Containerd
    ○ Dockerの裏側で動くランタイムサービス
    ○ DockerネイティブなAPIとCRIの両方をサポート
    ● CRI-O
    ○ Kubernetesのためのランタイム仕様である CRIを満たすべく作られたランタイム
    ● Docker(with Dockershim)
    ○ DockershimがなけりゃただのDocker

    View full-size slide

  32. コンテナランタイムの役割(Docker)
    dockerd
    docker pull
    docker run
    REST API
    containerd
    gRPC
    runC
    OCI(containerd内でJSON
    のコンフィグを渡しながらバ
    イナリを直接実行)
    OCI
    High level
    runtime
    Low level
    runtime

    View full-size slide

  33. コンテナランタイムの役割(Kubernetes)
    Kubernetes
    kubectl run
    kubectl apply
    REST API
    containerd
    CRI
    (gRPC)
    kube-apiserverとかetcdとか
    kubeletとかいろいろ含む
    ※CRIは各ノード上のkubeletが喋る
    runC
    OCI(containerd内でJSON
    のコンフィグを渡しながらバ
    イナリを直接実行)
    OCI
    High level
    runtime
    Low level
    runtime

    View full-size slide

  34. コンテナランタイムの役割(Kubernetes)
    Kubernetes
    kubectl run
    kubectl apply
    REST API
    containerd
    CRI
    (gRPC)
    kube-apiserverとかetcdとか
    kubeletとかいろいろ含む
    ※CRIは各ノード上のkubeletが喋る
    runC
    OCI(containerd内でJSON
    のコンフィグを渡しながらバ
    イナリを直接実行)
    OCI
    High level
    runtime
    Low level
    runtime
    CRI: Kubernetesレイヤで動くランタイム
    OCI: Linux kernelレイヤで動くランタイム

    View full-size slide

  35. ここまでのまとめ
    ● Kubernetesは当初、アプリケーションをコンテナで動かすために
    事実上唯一の選択肢だったDockerを採用(Dockerに寄せた実装)
    ● コミュニティの成長とともに、さまざまな実装、アイデア、選択肢が
    増えてきた
    ● Kubernetesコア(kubelet)における実装及びメンテナンスコストを抑える
    ための仕組みとしてCRI(Container Runtime Interface)を考案、現在の
    スタンダードとなった
    ● 分離の過程でOCIという団体、仕様が生まれ、イメージやコンテナを
    動かすための低いレベルでの仕組みが標準化された

    View full-size slide

  36. ここから先は時間と体力があれば
    軽くやります

    View full-size slide

  37. CRIとOCI、各ランタイムの違いをもう少し
    ● CRIランタイム
    ○ KubernetesからのgRPC命令を受け付けるサーバープロセス
    ○ 各ノード上にプロセスとして動いている (systemd status containerd/cri-o すると見れる)
    ○ コンテナの作成や起動そのものは OCIランタイムにおまかせ
    ● OCIランタイム
    ○ ただのバイナリファイル
    ○ Linuxのcgroups/namespaceと対話してコンテナを生成 /削除する役割
    ○ ただし!!バイナリファイルは実行したらおわりで、その後コンテナのプロセスの
    面倒をみる役割が必要(なんで???)
    ■ Runtime Shimというやつを使う
    ■ とても良い入門資料 : https://speakerdeck.com/moricho/deep-dive-into-runtime-shim

    View full-size slide

  38. OCIランタイムの役割

    View full-size slide

  39. OCIランタイムの分離レベル
    ● OCIランタイムの役割は
    ○ ホスト上で動くコンテナ (プロセス)や、隔離に使う名前空間などの作成と削除
    ○ 分離の方法は一つではなく、 Linuxの名前空間を使う方法もあれば、コンテナを動かすための
    VMを作成してその上でアプリケーションを動かすような方法もある
    ■ OCIの仕様を満たしていればわりとなんでもよい

    View full-size slide

  40. OCIランタイム
    ● runC
    ○ 何も考えてなけりゃみんなが使ってる
    ○ Dockerなどで使われる最も基本形 (Linux namespace + cgroups on host)
    ● gVisor
    ○ Googleが作ったサンドボックスランタイム
    ○ ゲストカーネルを動かしてコンテナに提供。コンテナはホストに直接悪いことができない
    ● Kata container
    ○ Intelのプロジェクトが発端のランタイム
    ○ KVMを立ち上げて分離するので起動オーバーヘッドが大きい代わりに分離レベルが高い
    ● Firecracker
    ○ 今回はややこいので説明なし

    View full-size slide

  41. runCの仕組み
    ホストマシン
    Linuxカーネル
    コンテナ コンテナ コンテナ
    runC
    Docker
    &
    CRI
    ファイルシステムの展開
    プロセスの初期化
    イメージの管理

    View full-size slide

  42. gVisorの仕組み
    ホストOS (ホストカーネル)
    コンテナ コンテナ コンテナ
    gVisorのゲストカーネル
    runSC

    View full-size slide

  43. Kata containersの仕組み
    ホストOS (ホストカーネル)
    KVM
    (qemu)
    KVM
    (qemu)
    KVM
    (qemu)
    Kata runtime
    コンテナ コンテナ コンテナ
    ホストカーネルを利用して
    KVMベースのマシンを起動

    View full-size slide

  44. 分離レベルを気にしないといけない理由は何?
    ● runCはカーネルを呼べる権限を剥奪されるとホスト全体に影響がある
    ● マルチテナントなどのユースケースでは分離レベルの高いほかのランタイムを
    使うことも考慮すべき
    ● Kubernetesでは、1クラスター上で複数のランタイムを使える機能がある
    ○ RuntimeClass
    ■ Podで指定できる
    ■ 神資料↓
    ■ https://speakerdeck.com/makocchi/lets-learn-about-kubernetes-runtime-class
    ■ https://blog.inductor.me/entry/2021/04/30/022505

    View full-size slide

  45. まとめ
    ● Kubernetesは当初、アプリケーションをコンテナで動かすために
    事実上唯一の選択肢だったDockerを採用(Dockerに寄せた実装)
    ● コミュニティの成長とともに、さまざまな実装、アイデア、選択肢が
    増えてきた
    ● Kubernetesコア(kubelet)における実装及びメンテナンスコストを抑える
    ための仕組みとしてCRI(Container Runtime Interface)を考案、現在の
    スタンダードとなった
    ● 分離の過程でOCIという団体、仕様が生まれ、イメージやコンテナを
    動かすための低いレベルでの仕組みが標準化された
    ● さまざまな要件に答えるために複数の違うアプローチを取ったランタイムがコミュニティ
    から提供されている

    View full-size slide

  46. おわり!!!!!

    View full-size slide