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

Ad22fcf5773b906c08330f4d57242212?s=128

Kohei Ota

May 12, 2021
Tweet

Transcript

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

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

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

  4. Kubernetesの特徴(リリース時) • Google Borgの10年以上に渡る運用知見を集約した基盤のOSS ◦ リリース当初はGoogleがメインで開発 • Docker、etcdを中心とした分散型コンテナ実行基盤 • APIを起点に、etcdに書かれたステートを正とし

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

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

    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム • 管理用のコントロールプレーン、実行用のワーカーからなる Dockerが非推奨になったの!? で話題になった1.20.0リリース時のアレ
  7. ランタイムのこれまでについて お話していきます

  8. Kubernetes初期のランタイムとの関係 • Google Borgの10年以上に渡る運用知見を集約した基盤のOSS ◦ リリース当初はGoogleがメインで開発 • Docker、etcdを中心とした分散型コンテナ実行基盤 • APIを起点に、etcdに書かれたステートを正とし

    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム • 管理用のマスター、実行用のミニオンと呼ばれるマシンからなる
  9. Kubernetes 1.0 当時の実装 https://github.com/kubernetes/kubernetes/blob/release-1.0/pkg/kubelet/dock ertools/manager.go kubeletのdockertools配下にDockerのための実装があった → 完全にDockerで動くことだけを想定

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

  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周りの実装(!)

  12. rktとはなんだったのか • CoreOS社(Red Hatが2018年に買収)が作ったコンテナランタイム ◦ CoreOS社は他にもetcdやコンテナホスト用LinuxディストロCoreOSを開発するなど、 Kubernetesのエコシステムに貢献してきた ◦ CoreOS Meetup

    Tokyo #1 の資料を見ると当時の状況がよくわかって面白い • Docker社が事実上独占していたコンテナのエコシステムを打破する きっかけになった ◦ Dockerはデーモンを配置してノード上に常駐させるモデルなのに対し、 rktはsystemdによる隔 離を応用した”デーモンレス”なコンテナ技術 ◦ Dockerとは違いPodのネイティブサポートをするなど、 Kubernetesの仕組みを意識
  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/
  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
  15. Kubernetes 1.3: rktをランタイムとして採用 • これまでDockerだけを前提に作られていたkubeletやランタイム周りの仕組みを 外部注入可能な形に置き換えるきっかけに • コンテナイメージの署名やコンテナケイパビリティの制限をデフォルトで実装した 「secure by

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

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

    default」な実装 • UNIX哲学に基づいたシンプルなプロセスモデル ◦ Dockerdがないのでrkt process = pod process • 当時としてはまだ新しかったユーザー名前空間の採用やSELinuxへの対応、軽 量VMへの対応など夢がてんこ盛り flyと呼ばれる分離とオーバー ヘッドが少ないシンプルなモー ドもあった
  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
  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 よさそうでは?
  20. Kubernetes 1.5: CRIの登場 • これまでDockerに依存していた部分を、(Kubernetesにとって)コンテナを動かす ための仕組み、すなわち「CRI(Container Runtime Interface)」として仕様を定 義 ◦

    ノード上にDaemonを配置 ◦ イメージとコンテナを操作するための gRPCサービス(サーバーの存在が前提 ) ◦ ランタイムを外部ソケット通信にすることで Kubernetes側とライフサイクルを切り離し
  21. なぜCRI? • ランタイムに依存するコードがKubernetes内部に多かった ◦ rktにしてもDockerにしても、それぞれが持つ APIを呼び出すためのコード ◦ 各ランタイムのバージョンに依存する修正が発生すると、 Kubernetesに変更が発生 ◦

    各ランタイム自体(特にDocker)はKubernetesだけを対象にしてないので、容赦なしに変更を加 えてバージョンアップしてくる • 外部コンポーネント化することで関心を分離しないとメンテナンスが大変 ◦ Kubeletは各ノードにいるので、 gRPC over UNIX Socketな構成が都合よかった ◦ 結局DockerもMoby projectを発表し、containerdがのちにCRIランタイムとして台頭
  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/
  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/
  24. rktの意思を継ぐもの、OCID(CRI-O)とPodman • Red Hatが2016年に発表したOCIDは現在CRI-Oという名前で現役で活躍 ◦ Linuxケイパビリティの制限やセキュリティ周りの対応など、 rktでも培われたいくつかの思想が 垣間見える ◦ Red

    Hat OpenShift 4からはデフォルトのランタイムに採用 • デーモンレスなコンテナランタイム「Podman」 ◦ Red Hatを主体としたオープンソースプロジェクトとして現在も鋭意開発中 ◦ Docker Compose互換な実装やネットワークへの対応、ユーザー名前空間の実装など、デーモ ンを使わずによく頑張ってるなと思う
  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 それぞれの違いを理解して使い分けてみるのも良いかもし れません
  26. 閑話休題: Dockerをやめるのはどうなのか

  27. Dockerが持つ主な3つのサービス • ランタイムサービス ◦ Containerdが管理するコンテナを動かすためのコア • ネットワークサービス ◦ docker network

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

    配下のAPI • ボリュームサービス ◦ docker volume 配下のAPI つかう つかわない
  29. None
  30. Kubernetesが持つ複数のインターフェース • CRI ◦ ランタイム • CNI ◦ ネットワーク •

    CSI ◦ ストレージ • CPI ◦ クラウドプロバイダー Dockerはどのレイヤとも被りうる・・・
  31. Dockershimの存在 https://jaco.udcp.info/entry/2020/12/03/172843 CRIの登場により CRI -> Docker API変換のため のDockershimが登場

  32. CRI対応済みランタイム • Containerd ◦ Dockerの裏側で動くランタイムサービス ◦ DockerネイティブなAPIとCRIの両方をサポート • CRI-O ◦

    Kubernetesのためのランタイム仕様である CRIを満たすべく作られたランタイム • Docker(with Dockershim) ◦ DockershimがなけりゃただのDocker
  33. コンテナランタイムの役割(Docker) dockerd docker pull docker run REST API containerd gRPC

    runC OCI(containerd内でJSON のコンフィグを渡しながらバ イナリを直接実行) OCI High level runtime Low level runtime
  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
  35. コンテナランタイムの役割(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レイヤで動くランタイム
  36. ここまでのまとめ • Kubernetesは当初、アプリケーションをコンテナで動かすために 事実上唯一の選択肢だったDockerを採用(Dockerに寄せた実装) • コミュニティの成長とともに、さまざまな実装、アイデア、選択肢が 増えてきた • Kubernetesコア(kubelet)における実装及びメンテナンスコストを抑える ための仕組みとしてCRI(Container

    Runtime Interface)を考案、現在の スタンダードとなった • 分離の過程でOCIという団体、仕様が生まれ、イメージやコンテナを 動かすための低いレベルでの仕組みが標準化された
  37. ここから先は時間と体力があれば 軽くやります

  38. 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
  39. OCIランタイムの役割

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

    ▪ OCIの仕様を満たしていればわりとなんでもよい
  41. OCIランタイム • runC ◦ 何も考えてなけりゃみんなが使ってる ◦ Dockerなどで使われる最も基本形 (Linux namespace +

    cgroups on host) • gVisor ◦ Googleが作ったサンドボックスランタイム ◦ ゲストカーネルを動かしてコンテナに提供。コンテナはホストに直接悪いことができない • Kata container ◦ Intelのプロジェクトが発端のランタイム ◦ KVMを立ち上げて分離するので起動オーバーヘッドが大きい代わりに分離レベルが高い • Firecracker ◦ 今回はややこいので説明なし
  42. runCの仕組み ホストマシン Linuxカーネル コンテナ コンテナ コンテナ runC Docker & CRI

    ファイルシステムの展開 プロセスの初期化 イメージの管理
  43. gVisorの仕組み ホストOS (ホストカーネル) コンテナ コンテナ コンテナ gVisorのゲストカーネル runSC

  44. Kata containersの仕組み ホストOS (ホストカーネル) KVM (qemu) KVM (qemu) KVM (qemu)

    Kata runtime コンテナ コンテナ コンテナ ホストカーネルを利用して KVMベースのマシンを起動
  45. 分離レベルを気にしないといけない理由は何? • runCはカーネルを呼べる権限を剥奪されるとホスト全体に影響がある • マルチテナントなどのユースケースでは分離レベルの高いほかのランタイムを 使うことも考慮すべき • Kubernetesでは、1クラスター上で複数のランタイムを使える機能がある ◦ RuntimeClass

    ▪ Podで指定できる ▪ 神資料↓ ▪ https://speakerdeck.com/makocchi/lets-learn-about-kubernetes-runtime-class ▪ https://blog.inductor.me/entry/2021/04/30/022505
  46. まとめ • Kubernetesは当初、アプリケーションをコンテナで動かすために 事実上唯一の選択肢だったDockerを採用(Dockerに寄せた実装) • コミュニティの成長とともに、さまざまな実装、アイデア、選択肢が 増えてきた • Kubernetesコア(kubelet)における実装及びメンテナンスコストを抑える ための仕組みとしてCRI(Container

    Runtime Interface)を考案、現在の スタンダードとなった • 分離の過程でOCIという団体、仕様が生まれ、イメージやコンテナを 動かすための低いレベルでの仕組みが標準化された • さまざまな要件に答えるために複数の違うアプローチを取ったランタイムがコミュニティ から提供されている
  47. おわり!!!!!