Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

CRI-O Introduction

orimanabu
January 28, 2021

CRI-O Introduction

CRI-O Introduction

orimanabu

January 28, 2021
Tweet

More Decks by orimanabu

Other Decks in Technology

Transcript

  1. 自己紹介 ▸ 名前: 織 学 (@orimanabu) ▸ 所属: Red Hat

    ▸ 仕事: OpenStack、OpenShiftのコンサルティング
  2. 目次 ▸ CRI-Oとは (概要) ▸ CRI-O開発の経緯 (政治の話) ▸ CRI-Oの特徴 (マニア向け)

    ・ Metadata only copy up ・ Pause Containerの廃止 ・ User namespace ・ その他
  3. 概要 ▸ https://github.com/cri-o/cri-o ▸ Kubernetes Incubatorプロジェクトとして始動 ・ 今はCNCF Incubating Project

    ▸ KubeletとCRIの通信をしながら、OCI準拠のコンテナを管理 ・ いわゆるHigh level runtime ▸ Kubernetesから呼び出されるユースケースにフォーカス ・ Kubernetesの全e2eテストを通すことが前提 ・ 他の機能は入れない ▸ 安定性、セキュリティ重視 ▸ (開発当初言っていたこと) ・ (高レベルランタイムとしての)Dockerの代替 ・ Dockerのエコシステムは壊さない ・ docker buildで作ったイメージをCRI-Oで実行できる
  4. Runtime Kubelet CRI-O runc CRI (gRPC) OCI (config.json) k8s worker

    node High level runtime Low level runtime https://github.com/kubernetes/kubernetes/blob/release-1.20/staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto
  5. 特徴 ▸ やること ・ コンテナイメージのpull ・ Dockerイメージ、OCIイメージをサポート ・ コンテナイメージをCopy-on-Writeベースのファイルシステムに展開する ・

    コンテナプロセスのライフサイクル管理 ・ モニタリング、ロギング ・ リソース分離 ▸ やらないこと ・ コンテナイメージのビルド、署名、push ・ (CRI-Oを操作するCLIツールとして、crictlというツールがあります) ・ https://github.com/kubernetes-sigs/cri-tools
  6. 特徴 ▸ 主な開発メンバー ・ Red Hat, SUSE, Intel, ... ▸

    CRI-Oを使っている製品、サービス等 ・ Red Hat OpenShift Container Platform ・ Oracle Linux Cloud Native Environment ・ SUSE CaaS Platorm ・ openSUSE Kubic ・ Digital Science ▸ Kubernetesにフォーカス ・ Kubernetes以外のユースケースはスコープ外、余計な機能は入れない ・ Kubernetesのe2e testを全てクリアすることがPR mergeの前提条件 ・ サポートのライフサイクル、バージョン付けもKubernetesにアライン ・ CRI-O v1.xはKubernetes v1.xをサポート https://github.com/cri-o/cri-o/blob/master/README.md https://github.com/cri-o/cri-o/blob/master/ADOPTERS.md
  7. cry・o- | kráɪə, -oʊ | (超)低温の、冷凍の E.g. • cryoanesthesia •

    cryobiology • cryogenic 余談: ロゴの由来 ▸ 雪の結晶 ・ CRI-Oと同じ発音の "cryo" は、「極低温の」という意味の接頭辞 ・ (航海には直接関係ないけど) Kubernetesの舵を模したロゴと似た形にできる ・ 雪の結晶は小さな氷の結晶(=コンテナ)が集まったもの、Kubernetesはランタイム (CRI-O)を通してコンテナの集まりを美しい雪の結晶として配置する ・ Inkscapeでデザイン ▸ その他の候補 ・ 氷山 ・ Mr Freeze from Batman ・ マンモス https://twitter.com/rhatdan/status/834757706355466240 http://blog.linuxgrrl.com/2017/02/22/a-logo-for-cri-o/
  8. 余談: バイナリサイズ ▸ CRI-O v1.20.0, conmon v2.0.24 ▸ containerd v1.4.3

    $ containerd --version containerd containerd.io 1.4.3 269548fa27e0089a8b8278fc4fc781d7f65a939b $ ls -lh /usr/bin/containerd* -rwxr-xr-x. 1 root root 55M Dec 2 22:20 /usr/bin/containerd -rwxr-xr-x. 1 root root 7.0M Dec 2 22:20 /usr/bin/containerd-shim -rwxr-xr-x. 1 root root 9.5M Dec 2 22:20 /usr/bin/containerd-shim-runc-v1 -rwxr-xr-x. 1 root root 9.6M Dec 2 22:20 /usr/bin/containerd-shim-runc-v2 $ crio version | grep ^Version INFO[0000] Starting CRI-O, version: 1.20.0, git: d388528dbed26b93c5bc1c89623607a1e597aa57(dirty) Version: 1.20.0 $ conmon --version conmon version 2.0.24 commit: 9cbc71d699291dfb14e7c1e348a0d48feff7a27d-dirty $ ls -lh /usr/local/bin/{crio,conmon,runc,crun} -rwxr-xr-x. 1 root root 1.8M Jan 20 09:08 /usr/local/bin/conmon -rwxr-xr-x. 1 root root 45M Jan 20 09:08 /usr/local/bin/crio -rwxr-xr-x. 1 root root 2.6M Jan 20 09:08 /usr/local/bin/crun -rwxr-xr-x. 1 root root 14M Jan 20 09:08 /usr/local/bin/runc
  9. CRI-O関連のコンポーネント ▸ OCI準拠の低レベルランタイムをサポート ・ runc, Kata Containers (CRI-O発足当時はIntel Clear Containers),

    crunでテスト済み ▸ ライブラリ ・ https://github.com/containers/storage ・ レイヤー化されたコンテナイメージを展開しルートファイルシステムを汲み上げる処 理 ・ Dockerのgraphdriversからforkして大幅に書き換え ・ https://github.com/containers/image ・ コンテナレジストリからイメージをpullする処理 ▸ CNI ▸ conmon ・ 後述
  10. conmon ▸ https://github.com/containers/conmon ▸ Container Monitor ・ コンテナのライフサイクル全体を管理する、Cで書かれた小さい常駐プログラム ▸ 1コンテナにつき1つのconmonが起動する

    ・ Kubelet → CRI-Oがconmonを起動 → conmonがruncを起動 → runcがコンテナプロセスを起動 ・ containerd-shimに相当、やってることもほぼ同じ ▸ ロギング ▸ TTY制御 ▸ クライアントからのアタッチ処理 ▸ OOMの検知、通知
  11. conmon ▸ コンテナプロセスのstdin, stdoutはconmonと接続する ・ CRI-Oが死んでいてもconmonがログをハンドリングできる ▸ conmonはコンテナの親プロセスになる ・ CRI-Oが死んでもコンテナは稼動し続ける

    ・ CRI-Oをアップデートするときもコンテナのダウンタイムは発生しない ▸ コンテナプロセス終了時のCRI-Oへの通知 ・ コンテナプロセスが終了すると、conmonはpipeを通して検知できる ・ conmonはコンテナプロセスの終了を検知すると、"--exit-dir" で指定したディレクトリにファ イルを生成する ・ ファイル名: コンテナID, 中身: exit status, exit message ▸ CRI-Oはfsnotifyを使ってそのファイル生成を検知する
  12. Red HatとDocker ▸ Red Hatはかなり初期からDockerを推していた ・ Red Hat and dotCloud

    Collaborate on Docker to Bring Next Generation Linux Container Enhancements to OpenShift Platform-as-a-Service (2013-09) ・ (Docker Inc.がdotCloudと名乗っていた頃に出したプレスリリース) ・ FedoraにDockerのrpmを用意する ・ ストレージのサポート拡充のため一緒に開発 ・ OpenShift(当時はv2)のCartridgeの代わりにDockerを使えるようにする ・ Docker and Red Hat Expand Collaboration Around Container Technologies (2014-04) ・ RHEL7 BetaにDockerのrpmを含める ・ Red Hatによるコンテナイメージの認定制度を作る ・ OpenShiftのDockerサポートを進める ・ RHELのサブスクリプションで、Docker Inc.のDeveloper supportを受けられる
  13. Red HatとDocker ▸ Red HatによるDockerへの機能追加 ・ SELinux対応 ・ ストレージ周り ・

    dm-thinpool, overleyfs, btrfs ・ とかいろいろ ▸ Red Hat製品へのインテグレーション ・ RHEL7へのDockerの同梱 ・ High Touch Betaから (Docker v0.11) ・ Project Atmic/RHEL Atomic Host発表 ・ RHELベースのDocker専用ホストOS ・ OpenShift v3でDocker+Kubernetesをベースにイチから作り直し
  14. コンテナ業界のできごと振り返り (1) ▸ Project Atmic/RHEL Atomic Host発表 (2014-04) ・ RHELベースのDocker専用ホストOS

    ▸ Docker v1.0 GA (2014-06) ▸ RHEL7.0 GA (2014-06) ▸ OpenShift v3でDocker+Kubernetesをベースに作り直すことを表明 (2014-08) ▸ Docker Swarm発表 (2014-12) ▸ OpenShift v3.0 GA (2015-06) ▸ Docker社によるrunCの発表 (2015-06) ・ Docker Engineと同じlibcontainer上に実装 ・ Windows, ARMサポート ▸ Docker、CoreOS他によるOpen Container Project (後のOpen Container Initiative) 発足 (2015-06) ・ DockerがOpen Container FormatとrunCを寄贈
  15. コンテナ業界のできごと振り返り (2) ▸ Google、Kubernetes v1.0 GA (2015-07) ▸ Kubernetesの開発主体がCNCFに移管 (2016-03)

    ▸ CoreOS社 rkt v1.0 GA (2016-02) ▸ Docker Engine v1.11 GA (2016-04) ・ OCIのコンテナ標準に準拠、runc, containerd等のモジュール化 ▸ Docker Engine v1.12 GA (2016-07) ・ EngineがSwarmモード内蔵 ▸ CRI-OをSIG Nodeに提案 (2016-09) ▸ containerdがDockerから分離 (2016-12) ▸ Docker CE v17.03 (2017-03) ・ v1.13の次、以降はリリースした YY.MM がバージョン番号に ・ EEも発表
  16. コンテナ業界のできごと振り返り (3) ▸ containerdとrktがCNCFへ (2017-03) ▸ Moby Project (2017-04) ▸

    Docker CE v17.06 GA (2017-06) ・ Moby Projectベース ▸ OCI v1.0 GA (2017-07) ・ ライタイムとイメージフォーマットの標準化完了 ▸ CRI-O v1.0 (2017-10) ▸ containerd v1.0 (2017-12)
  17. OCIとCRI-O ▸ 2015-06: OCI (Open Container Initiative) 始動 ・ Dockerのコンテナランタイムとイメージフォーマットをベースに標準化

    ・ runtime-spec ・ image-spec ▸ 2016-09: OCID (Open Container Initiative Daemon, 後のCRI-O)始動 ・ OCI specに基づいた、Kubernetesに特化したコンテナランタイム ・ OCI compatible CRI implementation ・ Kubernetesの進化/ライフサイクルに同期 ・ Kubernetes Incubator Projectとして開発 ▸ さらにbuildah, skopeoを作り ▸ そしてPodmanへ
  18. ▸ dockerdのモノリシック構造がセキュリティ的につらい ▸ DockerのサポートポリシーがRHEL/OpenShiftと合わない ・ RH: 開発・修正はupstream first policy、その後製品(downstream)にback port

    ・ Docker: バックポートしない、長期サポートなし ▸ そしてMoby登場...にともなってDockerのtrademark policyの改訂? ・ コード改変したものをDockerと呼んで再配布したら怒られる可能性? ・ 一方、RHEL同梱DockerにはRH独自パッチが含まれている ・ RHELイメージをDocker Hubにpushしないようにする ・ Host Entitlementをコンテナ内で使えるようにする 等 ▸ 結果として、RHEL7同梱のDockerはv1.13 (Moby化直前のバージョン) が最終バージョンになる ・ そしてv1.13に残った不具合を独自に直し続ける苦行 ▸ そんなこんなで、RHEL8ではDockerを同梱しないことに... ※ 個人の見解です 参考文献: 「Docker、OCI やめるってよ」http://blog.gachapin-sensei.com/archives/5174099.html
  19. Metadata only copy upとは ▸ chmod,chown等のメタデータのみを更新するような操作の場合、(ファイルデータ全体ではな く)メタデータのみをcopy upする機能 ・ upper

    layerに、「lower layerのファイルデータへの参照情報を含む拡張属性をつけた i-node」を作成する ・ メタデータのみcopy upされたファイルには、以下の拡張属性がセットされる ・ trusted.overlay.metacopy="" ・ trusted.overlay.origin=<lower layerのファイルのファイルハンドル> ▸ containers/storageがmetaonlyを活用できる仕組みを持っている ・ 特にUser Namespace使用時の起動時のコンテナストレージのセットアップにかかる時 間を大幅に改善 https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#metadata-only-copy-up https://github.com/torvalds/linux/commit/d5791044d2e5749ef4de84161cec5532e2111540
  20. metaonlyを使う設定 ▸ 以下のいずれかで、overlayfsでmetaonlyを使えるようになる ・ カーネルのコンフィグオプション "CONFIG_OVERLAY_FS_METACOPY" を有効化する ・ カーネルモジュール overlay

    のパラメータとして "metaonly=on" を指定する ・ マウント時のオプションとして "metaonly=on" を指定する ▸ CRI-O/Podmanのコンテナストレージでmetaonlyを使う設定 ・ /etc/containers/storage.confに以下を設定する ・ mountopt="metaonly=on"
  21. metaonlyの動作例 (1) ▸ マウントする $ mkdir lower upper work merged

    $ touch lower/{1,2} $ sudo mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work,metacopy=on merged ▸ ファイルのリスト $ ls -l merged total 0 -rw-rw-r--. 1 ori ori 0 Jan 13 17:08 1 -rw-rw-r--. 1 ori ori 0 Jan 13 17:08 2 $ ls -l upper total 0 ▸ ファイルのメタデータのみを更新 $ chmod +x merged/1 マウント時のオプションで metacopy=onを指定 upper layerにはまだ何もcopy upされていない overlayマウントしたディレクトリには、 lower layerの ファイルが見えている
  22. metaonlyの動作例 (2) ▸ ファイルのリスト $ ls -l merged total 0

    -rwxrwxr-x. 1 ori ori 0 Jan 13 18:24 1 -rw-rw-r--. 1 ori ori 0 Jan 13 18:24 2 $ ls -l upper total 0 -rwxrwxr-x. 1 ori ori 0 Jan 13 18:24 1 ▸ ファイルの拡張属性 $ sudo getfattr -dm- upper/* # file: upper/1 security.selinux="unconfined_u:object_r:user_home_t:s0" trusted.overlay.metacopy="" trusted.overlay.origin=0sAPshAIGjB0b1hnJJGJO2Y7/DMyHj0KMPQQAAAADEy6gr メタデータのみがcopy upされたファイルには、拡 張属性 trusted.overlay.metacopy が設定される
  23. metaonlyの動作例 (3) ▸ ファイルデータの更新 $ echo 1 > merged/1 ▸

    ファイルの拡張属性 $ sudo getfattr -dm- upper/* # file: upper/1 security.selinux="unconfined_u:object_r:user_home_t:s0" trusted.overlay.origin=0sAPshAIGjB0b1hnJJGJO2Y7/DMyHj0KMPQQAAAADEy6gr ファイルデータ全体が copy upされたため、拡張属 性 trusted.overlay.metacopy が消えている
  24. 実行例 $ kubectl get pod centos-tools-df64d94b6-w4wv6 NAME READY STATUS RESTARTS

    AGE centos-tools-df64d94b6-w4wv6 1/1 Running 0 11m $ kubectl exec centos-tools-df64d94b6-w4wv6 -- ls -l /anaconda-post.log -rw-r--r--. 1 root root 12076 Dec 5 2018 /anaconda-post.log $ sudo bash -c '(cd /var/lib/containers/storage/overlay/a680bd0a22905631265daca9029a7df960e3bbc5ddce850ed145c836e30728b3; getfattr -dm- diff/anaconda-post.log)' # file: diff/anaconda-post.log security.selinux="system_u:object_r:container_ro_file_t:s0" trusted.overlay.metacopy="" trusted.overlay.origin=0sAPshAIHiTS8xahxHr51coE1+jCsdTElIAAAAAAC3tFXt $ kubectl exec centos-tools-df64d94b6-w4wv6 -- chmod 400 /anaconda-post.log $ kubectl exec centos-tools-df64d94b6-w4wv6 -- ls -l /anaconda-post.log -r--------. 1 root root 12076 Dec 5 2018 /anaconda-post.log $ mount | grep /var/lib/containers/storage/overlay/a680bd0a22905631265daca9029a7df960e3bbc5ddce850ed145c836e30728b3 overlay on /var/lib/containers/storage/overlay/.../merged type overlay (rw,nodev,relatime,lowerdir=/var/lib/containers/storage/overlay/...,upperdir=/var/lib/containers/storage/overlay/a680b d0a22905631265daca9029a7df960e3bbc5ddce850ed145c836e30728b3/diff,workdir=/var/lib/containers/storage/overlay/.../work, metacopy=on)
  25. Pause Container ▸ Pause Container もしくは Infra Container ▸ Pod内で「親コンテナ」として振る舞う

    ・ Pod内のコンテナ間で共有するnamespaceを保持する ・ Pod内でシェアするnamespaceを提供する ・ 各PodでPID1として稼動し、ゾンビプロセスを回収する ▸ Pod起動時の流れ ・ Pauseコンテナを起動する ・ Pauseコンテナのnetnsに入って、IPアドレスを付与する ・ Pod manifestに書かれた各コンテナを、Pauseコンテナと同じnamespace内に起動する
  26. Pause Containerの歴史 ▸ PodにIPアドレスをつけるためにPause Containerが発明される ・ コード上は "netContainer" ▸ ipc等、他のnamespaceの管理する機能が追加される

    ・ "netContainer"から"infraContainer"に改名 ▸ pid namespaceの管理機能が追加されて、Pod内のPID1的な位置付けになる
  27. Pause ContainerなしのPodの起動 ▸ config.jsonでPod内のコンテナ間で共有するnamespaceをLow level runtimeに渡すが、この指定でbind mountを使う ・ 従来 (Pause

    Containerを使う場合): ・ /proc/${Pause ContainerのPID}/ns/${nstype}の形式で指定 ・ Pause Containerを使わない場合: ・ unshareでnet namespaceを作成し、/proc/${pid}/ns/${nstype} を /var/run/${nstype}ns/${uuid} にbind mountする ・ config.jsonでは、/proc/${pid}/nsではなくbind mount先のパスを指定 ▸ この「最初にnamespaceを作成してホストのディレクトリにbind mountする」ために pinns コマンドを開発 ・ https://github.com/cri-o/cri-o/tree/master/pinns ・ Cで書かれており、"ip netns" コマンドからインスパイアされている ・ CRI-Oがpinnsを実行、返ってきたbind mountされたnamespaceをコンテナに渡してPod作成
  28. ▸ Pause Containerあり (デフォルト) $ grep ^drop_infra_ctr /etc/crio/crio.conf drop_infra_ctr =

    false [centos@crio-node2 ~]$ systemd-cgls -u kubepods-besteffort-podc713282c_9801_4948_a7c3_c0eac0fe5089.slice Unit kubepods-besteffort-podc713282c_9801_4948_a7c3_c0eac0fe5089.slice (/kubepods.slice/kubepods-best...): ├─crio-1c56c73540cebaa505a2e649fb2d4adb935c62fdcb6196fef82b6e496984c812.scope │ ├─5217 nginx: master process nginx -g daemon off; │ └─5264 nginx: worker process └─crio-56ff059cc4a7b4759c212d0935fb05a2a75d894721cbe300cc4b7b93b0174587.scope └─5185 /pause ▸ Pause Containerなし $ grep ^drop_infra_ctr /etc/crio/crio.conf drop_infra_ctr = true [centos@crio-node1 ~]$ systemd-cgls -u kubepods-besteffort-podd20f27c7_c715_4740_9247_f2476abd821e.slice Unit kubepods-besteffort-podd20f27c7_c715_4740_9247_f2476abd821e.slice (/kubepods.slice/kubepods-best...): └─crio-5fb0d863f52e5779c8d42c57a9a86b4f3d69c9a6243ad6be52a26e28a66caf8d.scope ├─26106 nginx: master process nginx -g daemon off; └─26152 nginx: worker process 実行例
  29. 実行例 ▸ Pause Containerあり - Pause Containerのconfig.json $ sudo crictl

    pods POD ID CREATED STATE NAME NAMESPACE ATTEMPT 37cfe82e21c69 About an hour ago Ready nginx-deployment-7b54d48599-pvnrp default 0 ff5675b8171a3 16 hours ago Ready coredns-74ff55c5b-psnl8 kube-system 0 f52553a8ebc62 16 hours ago Ready weave-net-lh4q6 kube-system 0 39a11fcdc7016 16 hours ago Ready kube-proxy-tvndg kube-system 0 $ sudo /usr/local/bin/runc list | grep 37cfe82e21c69 37cfe82e21c69aa68f22aa731cd0c73a752cdc41e76d0c30512f9647be84e45f 24454 running /run/containers/storage/overlay-containers/37cfe82e21c69aa68f22aa731cd0c73a752cdc41e76d0c30512f9647be84e45f/userdata 2021-01-27T06:31:19.422405517Z root $ systemctl status crio-37cfe82e21c69aa68f22aa731cd0c73a752cdc41e76d0c30512f9647be84e45f.scope | grep -A1 CGroup CGroup: /kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod1e06c6eb_8a7c_4b4d_b0b7_96e843a3ce15.slice/crio-37cfe 82e21c69aa68f22aa731cd0c73a752cdc41e76d0c30512f9647be84e45f.scope └─24454 /pause
  30. 実行例 ▸ Pause Containerあり - Pause Containerのconfig.json $ sudo jq

    '.linux.namespaces[]' /run/containers/storage/overlay-containers/37cfe82e21c69aa68f22aa731cd0c73a752cdc41e76d0c30512f9647be84e45f/userdata/c onfig.json { "type": "pid" } { "type": "network" } { "type": "ipc" } { "type": "uts" } { "type": "mount" }
  31. 実行例 ▸ Pause Containerあり - nginxコンテナのconfig.json $ sudo crictl ps

    CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID ab154ea6f90e6 f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74 About an hour ago Running nginx 0 37cfe82e21c69 e750052642fc5 bfe3a36ebd2528b454be6aebece806db5b40407b833e2af9617bf39afaff8c16 17 hours ago Running coredns 0 ff5675b8171a3 6814e215cb5a4 9c10b22775a295fd1484f95a2f37037502d00edaa209b97574535676a6ceabe1 17 hours ago Running weave 1 f52553a8ebc62 <snip> $ sudo /usr/local/bin/runc list | grep ab154ea6f90e6 ab154ea6f90e6fe8b5898be1ef0795b2990941fd8f3bc573921e7fe01d4e64eb 24509 running /run/containers/storage/overlay-containers/ab154ea6f90e6fe8b5898be1ef0795b2990941fd8f3bc573921e7fe01d4e64eb/userdata 2021-01-27T06:31:19.556045212Z root $ systemctl status crio-ab154ea6f90e6fe8b5898be1ef0795b2990941fd8f3bc573921e7fe01d4e64eb.scope | grep -A2 CGroup CGroup: /kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod1e06c6eb_8a7c_4b4d_b0b7_96e843a3ce15.slice/crio-ab154 ea6f90e6fe8b5898be1ef0795b2990941fd8f3bc573921e7fe01d4e64eb.scope ├─24509 nginx: master process nginx -g daemon off; └─24558 nginx: worker process
  32. 実行例 ▸ Pause Containerあり - nginxコンテナのconfig.json $ sudo jq '.linux.namespaces[]'

    /run/containers/storage/overlay-containers/ab154ea6f90e6fe8b5898be1ef0795b2990941fd8f3bc573921e7fe01d4e64eb/userdata/c onfig.json { "type": "pid" } { "type": "network", "path": "/proc/24454/ns/net" } { "type": "ipc", "path": "/proc/24454/ns/ipc" } { "type": "uts", "path": "/proc/24454/ns/uts" } { "type": "mount" } Pause Containerのコンテナプロセスの PID
  33. 実行例 ▸ Pause Containerなし - (Pause Containerはいない) $ sudo crictl

    pods POD ID CREATED STATE NAME NAMESPACE ATTEMPT 4abff760c2454 2 hours ago Ready nginx-deployment-7b54d48599-bnb2s default 0 1a4e464cb9285 16 hours ago Ready coredns-74ff55c5b-wmpws kube-system 0 ca18c1b45b2ba 16 hours ago Ready client default 0 e2296056797bd 16 hours ago Ready weave-net-wk8mp kube-system 0 da351f219f338 16 hours ago Ready kube-proxy-wstbz kube-system 0 $ sudo /usr/local/bin/runc list | grep 4abff760c2454
  34. 実行例 ▸ Pause Containerなし - nginxコンテナのconfig.json $ sudo crictl ps

    CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID d79b974502128 f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74 2 hours ago Running nginx 0 4abff760c2454 de9f0b6905cfa docker.io/centos/tools@sha256:81159542603c2349a276a30cc147045bc642bd84a62c1b427a8d243ef1893e2f 16 hours ago Running centos-tools 0 ca18c1b45b2ba b3ba747901aed bfe3a36ebd2528b454be6aebece806db5b40407b833e2af9617bf39afaff8c16 16 hours ago Running coredns 0 1a4e464cb9285 956d4064a13f2 9c10b22775a295fd1484f95a2f37037502d00edaa209b97574535676a6ceabe1 16 hours ago Running weave 1 e2296056797bd $ sudo /usr/local/bin/runc list | grep d79b974502128 d79b974502128aea8f7e69f73f95947f7962b97805b4d8de7bb88e6873204402 1107066 running /run/containers/storage/overlay-containers/d79b974502128aea8f7e69f73f95947f7962b97805b4d8de7bb88e6873204402/userdata 2021-01-27T06:31:19.380222697Z root $ sudo systemctl status crio-d79b974502128aea8f7e69f73f95947f7962b97805b4d8de7bb88e6873204402.scope | grep -A2 CGroup CGroup: /kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod6c376082_508c_4a34_ab30_c0ff4992d96f.slice/crio-d79b9 74502128aea8f7e69f73f95947f7962b97805b4d8de7bb88e6873204402.scope ├─1107066 nginx: master process nginx -g daemon off; └─1107116 nginx: worker process
  35. 実行例 ▸ Pause Containerなし - nginxコンテナのconfig.json $ sudo jq '.linux.namespaces[]'

    /run/containers/storage/overlay-containers/d79b974502128aea8f7e69f73f95947f7962b97805b4d8de7bb88e6873204402/userdata/c onfig.json { "type": "pid" } { "type": "network", "path": "/var/run/netns/b2b78182-f2a5-4755-9a73-222dadf15e6e" } { "type": "ipc", "path": "/var/run/ipcns/b2b78182-f2a5-4755-9a73-222dadf15e6e" } { "type": "uts", "path": "/var/run/utsns/b2b78182-f2a5-4755-9a73-222dadf15e6e" } { "type": "mount" } pinnsがbind mountしたパス
  36. 実行例 ▸ containerd - cgroupsの階層 $ systemd-cgls -.slice ├─kubepods <snip>

    │ └─besteffort <snip> │ ├─pod5aae891e-efd2-44aa-9925-a632f515e5bc │ │ ├─e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b │ │ │ └─3194 /pause │ │ └─277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687 │ │ ├─3225 nginx: master process nginx -g daemon off; │ │ └─3262 nginx: worker process
  37. 実行例 ▸ containerd - Pause Containerのconfig.json $ sudo crictl --runtime-endpoint

    /run/containerd/containerd.sock pods POD ID CREATED STATE NAME NAMESPACE ATTEMPT e403c69ae4d05 17 hours ago Ready nginx-deployment-7fbd46f9ff-jpnjf default 1 d876d9ff1c42b 17 hours ago Ready client default 1 a1c0ee77cf87b 17 hours ago Ready coredns-74ff55c5b-qntmc kube-system 1 b0b048a354e07 17 hours ago Ready kube-proxy-ls9f2 kube-system 1 fb0ef49b5556a 17 hours ago Ready weave-net-m6js2 kube-system 1 b1c90b5757f9d 6 days ago NotReady client default 0 6a415a369243d 6 days ago NotReady nginx-deployment-7fbd46f9ff-jpnjf default 0 8b6246d9ca647 6 days ago NotReady coredns-74ff55c5b-qntmc kube-system 0 1f60446957069 6 days ago NotReady weave-net-m6js2 kube-system 0 e02564e941be6 6 days ago NotReady kube-proxy-ls9f2 kube-system 0 $ sudo runc --root /run/containerd/runc/k8s.io list | grep e403c69ae4d05 e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b 3194 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b 2021-01-26T15:40:44.820717662Z root
  38. 実行例 ▸ containerd - Pause Containerのconfig.json $ sudo jq '.linux.namespaces[]'

    /run/containerd/io.containerd.runtime.v2.task/k8s.io/e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b/ config.json { "type": "pid" } { "type": "ipc" } { "type": "uts" } { "type": "mount" } { "type": "network", "path": "/var/run/netns/cni-467e3246-b8b0-a008-6056-18c33f532117" }
  39. 実行例 ▸ containerd - nginxコンテナのconfig.json $ sudo crictl --runtime-endpoint /run/containerd/containerd.sock

    ps CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID 277da9929586e f6d0b4767a6c4 17 hours ago Running nginx 1 e403c69ae4d05 125847a0f1c12 fd317373544e2 17 hours ago Running centos-tools 1 d876d9ff1c42b daa3979d50058 bfe3a36ebd252 17 hours ago Running coredns 1 a1c0ee77cf87b 9961db1e7be83 9c10b22775a29 17 hours ago Running weave 2 fb0ef49b5556a b2fec31098fd9 43154ddb57a83 17 hours ago Running kube-proxy 1 b0b048a354e07 1b06e2c047289 0215a709bdd9b 17 hours ago Running weave-npc 1 fb0ef49b5556a $ sudo runc --root /run/containerd/runc/k8s.io list | grep 277da9929586e 277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687 3225 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687 2021-01-26T15:40:45.183504303Z root
  40. 実行例 ▸ containerd - nginxコンテナのconfig.json $ sudo jq '.linux.namespaces[]' /run/containerd/io.containerd.runtime.v2.task/k8s.io/277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687/

    config.json { "type": "pid" } { "type": "ipc", "path": "/proc/3194/ns/ipc" } { "type": "uts", "path": "/proc/3194/ns/uts" } { "type": "mount" } { "type": "network", "path": "/proc/3194/ns/net" } Pause Containerのコンテナプロセスの PID
  41. はじめに ▸ Podのannotationに "io.kubernetes.cri-o.userns-mode" を指定することで user namespace を有効化 ▸ ...されると思ったのですが、動きませんでしたすみません

    ▸ このPRで動くようになったと思ったのですが... ・ user namespaces: add support for userns-mode annotation ・ https://github.com/cri-o/cri-o/pull/3944
  42. 一応やったことをメモ ▸ 環境 ・ CentOS Stream 8 ・ Kubernetes 1.20.2

    ・ CRI-O 1.20.0 ▸ 準備 ・ /etc/sub[ug]idに以下を追加 ・ containers:200000:268435456 ・ /etc/crio/crio.confに以下を追加 ・ allowed_annotations = ["io.kubernetes.cri-o.userns-mode"]
  43. 一応やったことをメモ ▸ Deployment apiVersion: apps/v1 kind: Deployment metadata: name: top-deployment

    labels: app: top spec: replicas: 2 selector: matchLabels: app: top template: metadata: labels: app: top annotations: io.kubernetes.cri-o.userns-mode: "auto:size=8192;map-to-root=true" spec: containers: - name: top image: docker.io/alpine command: ["top"] securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000
  44. 一応やったことをメモ ▸ エラー Events: Type Reason Age From Message ----

    ------ ---- ---- ------- Normal Scheduled 19s default-scheduler Successfully assigned default/top-deployment-946458c86-jcswj to crio-node2 Warning FailedCreatePodSandBox 18s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to create pod network sandbox k8s_top-deployment-946458c86-jcswj_default_78c99147-1d5f-4827-bc59-836afae0c83c_0(d3b66c67821677c227632a4e96b6e20eb674 dbd8d6ab3a48a522923f2d4ce718): initializing veth: error setting up interface: open /proc/sys/net/ipv4/neigh/eth0/base_reachable_time: no such file or directory
  45. 一応やったことをメモ ▸ これを設定してみる default_sysctls = [ "net.ipv4.neigh.eth0.base_reachable_time = 30", ]

    ▸ スケジューリングされた後ContainerCreatingのまま何も進まなくなった...
  46. $ kubectl describe pod top-deployment-946458c86-9t8dt <snip> Status: Pending <snip> Containers:

    top: Container ID: Image: docker.io/alpine Image ID: Port: <none> Host Port: <none> Command: top State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-zkmqk (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True <snip> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 5m57s default-scheduler Successfully assigned default/top-deployment-946458c86-9t8dt to crio-node2 Warning FailedCreatePodSandBox 117s kubelet Failed to create pod sandbox: rpc error: code = DeadlineExceeded desc = context deadline exceeded
  47. Pod annotations ▸ Podのmetadataに設定するキー・バリューペア ・ Allow passing of unstructured data

    to varying levels of the stack ・ CRI-O 用のannotationがいくつか用意されている ・ io.kubernetes.cri-o.userns-mode ・ io.kubernetes.cri-o.Spoofed ・ io.kubernetes.cri-o.ShmSize ・ io.kubernetes.cri-o.Devices ・ cpu-load-balancing.crio.io ・ cpu-quota.crio.io ・ irq-load-balancing.crio.io https://github.com/cri-o/cri-o/blob/release-1.20/pkg/annotations/annotations.go https://static.sched.com/hosted_files/kccncna20/14/Control%20Room%20-%20Kube Con%20NA.pdf
  48. Linux capabilities ▸ CRI-OのデフォルトのCapabilities ・ CHOWN ・ DAC_OVERRIDE ・ FSETID

    ・ FOWNER ・ MKNOD ・ NET_RAW ・ SETGID ・ SETUID ・ SETFCAP ・ SETPCAP ・ NET_BIND_SERVICE ・ SYS_CHROOT ・ KILL ・ AUDIT_WRITE ▸ DockerのデフォルトのCapabilities ・ CHOWN ・ DAC_OVERRIDE ・ FSETID ・ FOWNER ・ MKNOD ・ NET_RAW ・ SETGID ・ SETUID ・ SETFCAP ・ SETPCAP ・ NET_BIND_SERVICE ・ SYS_CHROOT ・ KILL ・ AUDIT_WRITE https://github.com/moby/moby/blob/20.10/oci/caps/defaults.go#L6-L19 https://github.com/cri-o/cri-o/blob/release-1.20/internal/config/capabilities/capabilities.go#L17-L25
  49. Podmanとの統合 ▸ ストレージ管理、イメージ管理周りはCRI-O、Podmanで共有 ・ CRI-Oで稼動するコンテナのイメージは `podman images` で見れる ▸ 実行中のPod/コンテナの管理は今は別実装

    ・ CRI-Oで稼動するコンテナの情報は `podman ps` では見えない (`crictl ps`を使う) ・ このランタイム管理の部分の統合を徐々に進めているところ ▸ 歴史 ・ もともとCRI-Oが先に生まれて ・ そのPod管理部分がlibpodとしてライブラリ化され ・ libpodが(CRI-Oとは別に)進化してPodmanになる
  50. 参考文献 ▸ KubeConの資料いろいろ ▸ CRI-O Shallow Dive ・ https://speakerdeck.com/inductor/cri-o-shallow-dive ・

    https://www.youtube.com/watch?v=lQNwxbQnBGU&t=4h43m49s ▸ Deep Dive into Runtime Shim ・ https://speakerdeck.com/moricho/deep-dive-into-runtime-shim ・ https://www.youtube.com/watch?v=5CxGID8_jOY&t=2h44m24s ・
  51. linkedin.com/company/red-hat youtube.com/user/RedHatVideos facebook.com/redhatinc twitter.com/RedHat Red Hat is the world’s leading

    provider of enterprise open source software solutions. Award-winning support, training, and consulting services make Red Hat a trusted adviser to the Fortune 500.
  52. CRI-Oとは ▸ CRI-O (くらいお) ・ KubeletとCRIの通信をしながら、OCI準拠のコンテナを管理するコンポーネント ・ CRI: Container Runtime

    Interface ・ O: Open Container Initiative, OCI ▸ 仲間 ・ (Dockershim + Docker) ・ containerd ▸ 特徴
  53. CRI-O ▸ crio is meant to provide an integration path

    between OCI conformant runtimes and the kubelet. Specifically, it implements the Kubelet Container Runtime Interface (CRI) using OCI conformant runtimes. The scope of crio is tied to the scope of the CRI. ・ 1. Support multiple image formats including the existing Docker and OCI image formats. ・ 2. Support for multiple means to download images including trust & image verification. ・ 3. Container image management (managing image layers, overlay filesystems, etc). ・ 4. Container process lifecycle management. ・ 5. Monitoring and logging required to satisfy the CRI. ・ 6. Resource isolation as required by the CRI.` ▸
  54. Architecture ▸ tmp Infra Container (runc) Pod (ipc, net, pid

    namespaces) Container A (runc) Container B (runc) conmon conmon conmon
  55. Sysdigさんのレポート ▸ Sysdig 2021 container security and usage report: Shifting

    left is not enough https://sysdig.com/blog/sysdig-2021-container-security-usage-report/ ▸
  56. conmon ▸ Dockerは、dockerdが全てのログを受け取る ・ dockerdが死ぬと、コンテナプロセスのstdoutがブロックする ・ Dockerにはnon-blocking log modeがある (デフォルト設定ではない)

    ・ https://docs.docker.com/config/containers/logging/configure/ ・ dockerdは、SIGTERMを受けると、自身が終了する前に全てのコンテナを終了させる ・ live-restoreオプションを使うとそうではなくなる、が非推奨? ・ https://docs.docker.com/config/containers/live-restore/ ▸ CRI-Oは、デーモンが死んでもconmonがログを受け取ってくれる
  57. for latency sensitive apps ▸ Pod annotation: cpu-load-balancing.crio.io, cpu-quota.crio.io ▸

    がついていたらPodに割り当てたCPUでIRQを処理しないようにする ▸ リアルタイムアプリ向け? ・ https://github.com/cri-o/cri-o/pull/4022 ・ https://github.com/cri-o/cri-o/pull/4441 ▸ infra containerに特定のCPUを割り当てる ・ https://github.com/cri-o/cri-o/pull/4459 ・
  58. Metadata only copy up ▸ “Metadata only copy up” ・

    https://www.kernel.org/doc/html/latest/filesystems/overlayfs.html#metadata-onl y-copy-up ・ https://lwn.net/Articles/755891/ ・ https://github.com/torvalds/linux/commit/d5791044d2e5749ef4de84161cec553 2e2111540 ・
  59. デモ ▸ $ sudo crictl ps CONTAINER ID IMAGE CREATED

    STATE NAME ATTEMPT POD ID 72c5e9fa632da docker.io/centos/tools@sha256:81159542603c2349a276a30cc147045bc642bd84a62c1b427a8d243ef1893e2f 50 seconds ago Running centos-tools 0 05d8f26f0808b 87d0c58b2d92b docker.io/centos/tools@sha256:81159542603c2349a276a30cc147045bc642bd84a62c1b427a8d243ef1893e2f 9 minutes ago Running centos-tools 0 57ed5cc00955f 136de7460054b bfe3a36ebd2528b454be6aebece806db5b40407b833e2af9617bf39afaff8c16 9 minutes ago Running coredns 0 7b3bfbe6552ad 3bde36cbea8ec f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74 9 minutes ago Running nginx 0 786b503ae9d17 67fa85e867493 9c10b22775a295fd1484f95a2f37037502d00edaa209b97574535676a6ceabe1 9 minutes ago Running weave 1 c43311372b581 8479f127bfea7 0215a709bdd9b6507c5f2615bddef2c7b3a7412ca35ea83822268befdae614f3 9 minutes ago Running weave-npc 0 c43311372b581 ad765fb5f2190 43154ddb57a83de3068fe603e9c7393e7d2b77cb18d9e0daf869f74b1b4079c0 9 minutes ago Running kube-proxy 0 e2f651a2e886a $ sudo /usr/local/bin/runc list | grep 72c5e9fa632da 72c5e9fa632da9b3f6d8ab598bdfc613b67f0864d5cd4c93513945a6953a1fcf 14734 running /run/containers/storage/overlay-containers/72c5e9fa632da9b3f6d8ab598bdfc613b67f0864d5cd4c93513945a6953a1fcf/userdata 2021-01-27T12:04:19.927123743Z root $ sudo jq -r .root.path /run/containers/storage/overlay-containers/72c5e9fa632da9b3f6d8ab598bdfc613b67f0864d5cd4c93513945a6953a1fcf/userdata/c onfig.json /var/lib/containers/storage/overlay/a680bd0a22905631265daca9029a7df960e3bbc5ddce850ed145c836e30728b3/merged
  60. ▸ イメージサイズ [centos@crio-node2 ~]$ sudo crictl images IMAGE TAG IMAGE

    ID SIZE docker.io/library/nginx 1.19 f6d0b4767a6c4 137MB docker.io/weaveworks/weave-kube 2.8.0 9c10b22775a29 107MB docker.io/weaveworks/weave-npc 2.8.0 0215a709bdd9b 39.7MB k8s.gcr.io/coredns 1.7.0 bfe3a36ebd252 45.4MB k8s.gcr.io/kube-proxy v1.20.2 43154ddb57a83 120MB k8s.gcr.io/pause 3.2 80d28bedfe5de 688kB ▸ メモリ使用量 [centos@crio-node2 ~]$ ps ax | grep pause | head -n 1 1378 ? Ss 0:00 /pause [centos@crio-node2 ~]$ sudo pmap 1378 1378: /pause 0000000000400000 4K r---- pause 0000000000401000 496K r-x-- pause 000000000047d000 144K r---- pause 00000000004a1000 28K rw--- pause 00000000004a8000 4K rw--- [ anon ] 00000000019a3000 140K rw--- [ anon ] 00007ffe128be000 132K rw--- [ stack ] 00007ffe12977000 16K r---- [ anon ] 00007ffe1297b000 8K r-x-- [ anon ] ffffffffff600000 4K r-x-- [ anon ] total 976K
  61. デモ ▸ containerd $ sudo crictl --runtime-endpoint /run/containerd/containerd.sock pods POD

    ID CREATED STATE NAME NAMESPACE ATTEMPT e403c69ae4d05 17 hours ago Ready nginx-deployment-7fbd46f9ff-jpnjf default 1 d876d9ff1c42b 17 hours ago Ready client default 1 a1c0ee77cf87b 17 hours ago Ready coredns-74ff55c5b-qntmc kube-system 1 b0b048a354e07 17 hours ago Ready kube-proxy-ls9f2 kube-system 1 fb0ef49b5556a 17 hours ago Ready weave-net-m6js2 kube-system 1 b1c90b5757f9d 6 days ago NotReady client default 0 6a415a369243d 6 days ago NotReady nginx-deployment-7fbd46f9ff-jpnjf default 0 8b6246d9ca647 6 days ago NotReady coredns-74ff55c5b-qntmc kube-system 0 1f60446957069 6 days ago NotReady weave-net-m6js2 kube-system 0 e02564e941be6 6 days ago NotReady kube-proxy-ls9f2 kube-system 0 $ sudo runc --root /run/containerd/runc/k8s.io list | grep e403c69ae4d05 e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b 3194 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b 2021-01-26T15:40:44.820717662Z root $ systemd-cgls -.slice ├─kubepods <snip>
  62. デモ ▸ containerd $ sudo jq '.linux.namespaces[]' /run/containerd/io.containerd.runtime.v2.task/k8s.io/e403c69ae4d059f27f980f5f081af81651bbf2681999bfe4eb7742fcbe0d215b/ config.json {

    "type": "pid" } { "type": "ipc" } { "type": "uts" } { "type": "mount" } { "type": "network", "path": "/var/run/netns/cni-467e3246-b8b0-a008-6056-18c33f532117" }
  63. デモ ▸ containerd $ sudo crictl --runtime-endpoint /run/containerd/containerd.sock ps CONTAINER

    ID IMAGE CREATED STATE NAME ATTEMPT POD ID 277da9929586e f6d0b4767a6c4 17 hours ago Running nginx 1 e403c69ae4d05 125847a0f1c12 fd317373544e2 17 hours ago Running centos-tools 1 d876d9ff1c42b daa3979d50058 bfe3a36ebd252 17 hours ago Running coredns 1 a1c0ee77cf87b 9961db1e7be83 9c10b22775a29 17 hours ago Running weave 2 fb0ef49b5556a b2fec31098fd9 43154ddb57a83 17 hours ago Running kube-proxy 1 b0b048a354e07 1b06e2c047289 0215a709bdd9b 17 hours ago Running weave-npc 1 fb0ef49b5556a $ sudo runc --root /run/containerd/runc/k8s.io list | grep 277da9929586e 277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687 3225 running /run/containerd/io.containerd.runtime.v2.task/k8s.io/277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687 2021-01-26T15:40:45.183504303Z root
  64. デモ ▸ containerd $ sudo jq '.linux.namespaces[]' /run/containerd/io.containerd.runtime.v2.task/k8s.io/277da9929586e1c5818b4976d489e421aca750020a09912ba89cab41206e4687/ config.json {

    "type": "pid" } { "type": "ipc", "path": "/proc/3194/ns/ipc" } { "type": "uts", "path": "/proc/3194/ns/uts" } { "type": "mount" } { "type": "network", "path": "/proc/3194/ns/net" }