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

Kubernetesをとりまくコンテナランタイムの栄枯盛衰 / The rise and fa...

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の特徴(現在) • Google Borgの10年以上に渡る運用知見を集約した基盤のOSS ◦ CNCFがホスティング、コミュニティを主体とした開発体制 • コンテナランタイム、etcdを中心とした分散型コンテナ実行基盤 • APIを起点に、etcdに書かれたステートを正とし

    あるべき状態を定義されたとおりに基盤上で維持する自立型のシステム • 管理用のコントロールプレーン、実行用のワーカーからなる Dockerが非推奨になったの!? で話題になった1.20.0リリース時のアレ
  2. rktとはなんだったのか • CoreOS社(Red Hatが2018年に買収)が作ったコンテナランタイム ◦ CoreOS社は他にもetcdやコンテナホスト用LinuxディストロCoreOSを開発するなど、 Kubernetesのエコシステムに貢献してきた ◦ CoreOS Meetup

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

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

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

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

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

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

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

    CSI ◦ ストレージ • CPI ◦ クラウドプロバイダー Dockerはどのレイヤとも被りうる・・・
  17. CRI対応済みランタイム • Containerd ◦ Dockerの裏側で動くランタイムサービス ◦ DockerネイティブなAPIとCRIの両方をサポート • CRI-O ◦

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

    runC OCI(containerd内でJSON のコンフィグを渡しながらバ イナリを直接実行) OCI High level runtime Low level runtime
  19. コンテナランタイムの役割(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
  20. コンテナランタイムの役割(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レイヤで動くランタイム
  21. 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
  22. OCIランタイム • runC ◦ 何も考えてなけりゃみんなが使ってる ◦ Dockerなどで使われる最も基本形 (Linux namespace +

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

    ファイルシステムの展開 プロセスの初期化 イメージの管理
  24. Kata containersの仕組み ホストOS (ホストカーネル) KVM (qemu) KVM (qemu) KVM (qemu)

    Kata runtime コンテナ コンテナ コンテナ ホストカーネルを利用して KVMベースのマシンを起動
  25. まとめ • Kubernetesは当初、アプリケーションをコンテナで動かすために 事実上唯一の選択肢だったDockerを採用(Dockerに寄せた実装) • コミュニティの成長とともに、さまざまな実装、アイデア、選択肢が 増えてきた • Kubernetesコア(kubelet)における実装及びメンテナンスコストを抑える ための仕組みとしてCRI(Container

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