Kubernetesのdockershim非推奨とコンテナランタイムまとめ

# はじめに

Kubernetes v1.20 で、kubeletによるDockerサポートが非推奨になるとのアナウンスがあったので影響などメモ。

>Docker support in the kubelet is now deprecated and will be removed in a future release. The kubelet uses a module called "dockershim" which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community. We encourage you to evaluate moving to a container runtime that is a full-fledged implementation of CRI (v1alpha1 or v1 compliant) as they become available.


https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation

結論は

- コンテナを利用する側のアプリケーション開発者などはあまり気にしなくてよい（dockerベースのアプリ開発自体は影響ない）
- k8sクラスタを管理するインフラエンジニアは気にすることはある（ただし焦る必要はない）



# Dockerとcontainerd

Kubernetesでは、コンテナイメージの実行環境（ランタイム）として複数のツールをサポートしている

- Docker（https://www.docker.com/）
- containerd（https://containerd.io/）
- CRI-O（https://cri-o.io/）

https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

この中のDocker（moby）について、厳密にいえばcontainerdはDockerの構成要素の１つで、コンテナランタイム機能部にあたる。
Dockerはコンテナランタイム（containerd）以外にもイメージビルドやdocker APIなどアプリ開発フローに必要な機能などたくさんの構成要素があり、containerdはその中の１つで、標準ツールとしてCNCFへ寄贈されたもの（スピンオフ的な）。

Kubernetes自体はDockerのランタイム機能だけあればよいので、わざわざリッチなDockerそのものを必要とせず、ランタイム機能だけが切り出されたcontainerdや、同様にシンプルなランタイム実装のcri-oだけで事足りる。

さらに、Kubernetes（厳密にはkubelet）がコンテナランタイムと連携するには、CRI:Container Runtime Interface という標準IFを利用するが、DockerはもともとそのCRI IFに準拠していなかったため、Docker内部ではdockershimというブリッジ要素がCRI IFで受け取り、docker APIへの通訳をしている。
ただし、containerdは前述の通りオープン化されており、直接CRIで外部（kubelet）から連携できちゃうので、わざわざDocker(dockershm + containerd)を利用せず、containerdを直接利用すればいいからシンプルに非推奨に　という話らしい。

### パフォーマンス比較

下記記事によると、Dockerを仲介するよりcontainerdを直接利用した方が、CPU/MEM等の比較でパフォーマンス向上している。

>Kubernetes対応コンテナランタイム「containerd 1.1」正式リリース。CRIにネイティブ対応し、Dockerより軽量で高速な動作を実現
https://www.publickey1.jp/blog/18/kubernetescontainerd_11cridocker.html

# コンテナランタイム スタック

一言でコンテナランタイムと言っても、High-level Container RuntimeとLow-level Container Runtimeと役割によってレイヤーがあり、今回の話は前者のレイヤーの話。
下記にスタック図を示す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/9c888ec0-d8ef-905a-7c7c-d269d933a45d.png)



### High-level Container Runtime

- 通称CRIランタイム
- 外部(kubelet)からCRIインターフェースで命令を受け付ける
- コンテナイメージの管理を担い、Low-levelへ指示を出す
- 例：containerd、CRI-O

### Low-level Container Runtime

- 通称OCIランタイム
- 標準仕様OCIに準拠することで、High/Lowの異なるランタイム間で連携可能
- High-levelからの指示に基づき、コンテナの起動/停止など直接的な制御を行う
- 例：runc、gVisor

# その他参考リンク

Dockerは非推奨じゃないし今すぐ騒ぐのをやめろ
https://jaco.udcp.info/entry/2020/12/03/172843

Kubernetes 1.20から始まるDockerランタイムの非推奨化に備えよう！我々が知っておくべきこと・すべきこと
https://thinkit.co.jp/article/18024

コンテナランタイムの動向を整理してみた件
https://qiita.com/mamomamo/items/ed5db2ab1555078f8a24

# Dockerに依存しないビルドツール

今回はコンテナランタイムの話だが、コンテナのビルドについてもDockerに依存しないツールも色々出ている

例

- **BuildKit** (https://github.com/moby/buildkit)
    - Mobyプロジェクトの１つ
    - Docker v18.06以降の docker build コマンドのバックエンドとしても使われているビルドツール
    - コンテナビルドを含むCICDワークフローをKubernetes上でセキュアに（非root権限で）実行できる
    - 参考
        - https://medium.com/nttlabs/buildkit-on-kubernetes-d37a03150192
        
- **Kaniko** (https://github.com/GoogleContainerTools/kaniko)
    - Google,Inc.が開発しオープンソースとして公開したビルドツール
    - BuildKit同様にKubernetes上でのセキュアなビルド実行を実現する
    - GCP **Cloud Build** サービスのバックエンドとしても使われている
    - 参考
        - https://knowledge.sakura.ad.jp/15321/