Kubernetes 1.20から始まるDockerランタイムの非推奨化に備えよう!我々が知っておくべきこと・すべきこと

2020年12月11日(金)
太田 航平
SNSでトレンドに上がるなど話題になったKubernetes 1.20におけるDockershim非推奨化について解説します。

はじめに

Kubernetesの次のマイナーバージョン1.20が、2020年12月8日にリリースされました。今回のリリースではGraceful Node Shutdownの追加kubectl debugのBeta昇格など、運用に嬉しいさまざまな機能のアップデートがあります。その中でも、12月初頭にGitHubや公式Slack、Twitterなどを賑わせたのがDockershimの非推奨化でした。公式のリリースノートには以下のように書かれています。

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.

参考リンク:kubernetes/CHANGELOG-1.20.md

今回はこの変更に着目して、DockerとKubernetesの関係から、なぜ非推奨になったのかを解説しつつ、運用者・開発者がどのような対応をとればよいかについてご紹介します。

具体的に何がどうなるのか

バージョン1.20から「Dockershim」が非推奨になることで、KubernetsをDockerランタイムで動かしている場合は非推奨の注意書きがKubernetesのクラスターログに表示されるようになります。この変更によってすぐにKubernetesが動かなくなるわけではありません。しかし、来年後半にリリースを予定しているバージョン1.23からはDockershimがKubernetesから削除され、KubernetesをDockerと一緒に動かすためには自前で別途準備が必要になります。

まずは、このDockershimについて何をしているものなのか見てみましょう。

Dockershimの役割

DockershimはDockerとKubernetesのAPIをつなぐブリッジの役割を持ちます。Kubernetesが作られた当時に、アプリケーションを動かすために最も便利で汎用性のあったDockerがコンテナランタイムとして採用されました。一方、Docker社はKubernetesの公開後まもなく、独自のオーケストレーションツールであるDocker Swarmを発表しました。そのほかにもCoreOS社のrktやRancher社のCattleコンテナ管理のためのツールが生まれる中で、KubernetesにとってのDockerは依存すべき関係ではなく選択肢の一つとして考えていく必要がありました。

そこで、Kubernetesに必要な「コンテナを操作するためのAPI仕様」としてCRI(Container Runtime Interface)が作られ、DockershimはCRIとDockerのAPIを変換するためのブリッジとなり、現在も内部的に使われています。

DockerとKubernetesの現在の状態(便宜上kubeletとDockershimを分割して表現していますが、実際にはkubeletバイナリにDockershimが含まれています)

DockerとKubernetesの現在の状態(便宜上kubeletとDockershimを分割して表現していますが、実際にはkubeletバイナリにDockershimが含まれています)

なお、削除される予定のDockershimは、今後Mirantis社がhttps://github.com/Mirantis/cri-dockerdというリポジトリで管理を継続していくと発表しています。「自前で別途準備が必要になる」という点では変わりませんが、Dockerを使っていても、Kubernetesが一切動かなくなる、というわけではなさそうです。

また、Mirantis社が提供する「Mirantis Kubernetes Engine」もあるため、こちらをお使いの場合はDockerとの統合に関する将来的な期待ができそうです。

KubernetesはDockerの一部の機能しか使わない

「Docker」という言葉にはいろいろな意味合いが含まれます。これは、手元で作った環境をDockerコマンドでイメージにBuildし、作成したイメージをレジストリでShareし、それを他の環境でRunできるという、一般に「Build、Share、Run」と呼ばれる仕組みが開発者にとって広く浸透してきたことのあらわれでもあると筆者は考えていますが、KubernetesはDockerが持つ機能の中でも一部しか利用していません。

Kubernetesが使うDockerの機能

Dockerの中でもDockerコンテナを作成して動かし、管理する機能のことを「ランタイム」と呼びます。Kubernetesでは、このDockerが持つランタイム機能を使ってアプリケーションの実行や削除、アップデートなどを実現しています。

Kubernetesが使わないDockerの機能

Dockerイメージをビルドするための「イメージビルダー」や、Dockerコンテナが動く上で必要な「ボリューム」、「ネットワーク」といった機能はKubernetesでは利用しません。その代わり、実際にはコンテナを管理することに特化した「containerd」を中心とした機能が使われます(下図参照)。

Dockerの中でKubernetesが使う機能は、赤枠のcontainerdを中心とした機能である

Dockerの中でKubernetesが使う機能は、赤枠のcontainerdを中心とした機能である

Dockerが非推奨となる最も大きな理由はDockershim自体のメンテナンスコストが高いことですが、一部の理由としては、このように使われない機能を多く含むDockerを「基盤の根幹」として使い続けることによるリソースのオーバーヘッドなどの問題が指摘されてきたという背景があります。

containerdについて

containerdは、Dockerがmoby projectを発表したのと同時期にCNCFに寄贈されたDockerの一部です。moby projectはDocker社が2017年に発表したOSSのプロジェクトで、Dockerを構成する機能を切り出すことによって、開発者が好きな機能を自分のプロジェクトに取り入れられるようにしたり、車輪の再発明をしなくてもよくなるような工夫がなされているプロジェクトです。containerdはこのプロジェクトの発足と同時に発表されたコンテナランタイムのOSSで、ほぼ同じタイミングでCNCF Projectに寄贈されました。

2017年にDocker社よりOSSとして発表されたmoby project

2017年にDocker社よりOSSとして発表されたmoby project

containerdはDockerの持つランタイムそのものでありながら、CRIが実装されています。そのため、Kubernetes上でこれまでDockerを使っていた基盤運用者がDockerからの移行を考えるにあたっては最も有力な候補と言えます。

なお、Kubernetesの世界ではこのようなCRIを備えるランタイムを「CRIランタイム」と呼びます。

CRIランタイム

CRIランタイムは高レベルランタイムとも呼ばれ、Dockerと同じくKubernetesがコンテナを管理するための機能を提供します。2020年12月現在、CRIランタイムには「containerd」と「CRI-O」という2つの実装があります。

containerd

containerdはKubernetesと同じくCNCFのプロジェクトの一つで、Dockerの裏側で動くランタイムです。CRIを備えつつDockerにもさまざまな機能を提供しています。ランタイムとしてはDockerが必要なものをすべて持っているため、これまでKubernetesでランタイムにDockerを使ってきた利用者にとっても、多くの場合で何も気にすることなく移行をすることができるかと思います(移行に考慮が必要なケースについては後述します)。

containerdはパブリッククラウドで利用されているケースが多く、例えばAWSのEKS FargateやBottlerocketではDockerの代わりにcontainerdが動くほか、GCPのGKEでもcontainerdを動かすことができ、1.19からはデフォルトのコンテナランタイムがDockerからcontainerdに変更されています。AzureのAKSについては2020年12月頭の段階ではプレビューフェーズで、少なくとも1.23のリリースまでにはGAになるものと思われます。

CRI-O

CRI-OはRed Hat社が中心となって開発しているOSSで、containerdとは違い純粋なCRI実装であるため、「Kubernetesを動かすために作られたコンテナランタイム」と呼ぶこともできます。現在はRed Hatの主力製品の一つである「Red Hat OpenShift」のコンポーネントとして導入され、Dockerの代わりにコンテナを動かすためのツールとしてさまざまな環境で利用されています。containerdとの一番の違いはその実装背景にあります。「CRIのためのランタイム」と呼ばれるだけあって、軽量かつよりセキュアなランタイムである、と公式ドキュメントでも謳っています。

ランタイム移行のメリット

CRIランタイムに移行すると、kubeletはDockershimを経由することなく直接ランタイムと会話することができます。そのため、コードベースも軽量になりつつ通信のオーバーヘッドが改善される、といったメリットがあります。

kubeletがCRIランタイムと直接通信するようす

kubeletがCRIランタイムと直接通信するようす

OCIランタイム

CRIランタイムの話をしたので、OCIランタイムについても簡単に触れておきましょう。OCIはOpen Container Initiativeの略称で、Dockerコンテナに必要なさまざまな規格を標準化している団体です。規格には以下のようなものがあり、その中でもRuntime Specを満たしているのがOCIランタイムです。CRIランタイムが高レベルランタイムと呼ばれるのに対し、OCIランタイムは低レベルランタイムと呼ばれています。

CRIランタイムとOCIランタイムについては非常に関係性が複雑なので、下記の図を用意しました。

KubernetesにおけるCRI、OCIそれぞれのランタイムの役割

KubernetesにおけるCRI、OCIそれぞれのランタイムの役割

Kubernetesからランタイムを利用する場合、はじめにkubectlコマンドなどを用いてPodを作成します。このとき、Kubernetes内部ではetcdにPodを作成するための情報が書き込まれ、スケジューリングなどの処理を経て特定ノードのkubeletがPodの情報を取得します。

kubeletは作成するPodの情報をCRIを通じて高レベルランタイムに渡します。CRIランタイムはそれをJSONの構成ファイルに変換し、最終的に「OCIランタイム」のバイナリを実行することによって作成します。

このとき、Linuxカーネルとの対話などはOCIランタイムが請け負っており、CRIランタイムはあくまでそれらの管理のために動くプロセスです。

OCIランタイムもCRIランタイムと同様いくつかの実装がありますが、今回は直接関係のないトピックのため、名前を列挙するまでにとどめます。興味がある方はそれぞれの特徴や違いについて調べてみてください。

Dockershimの削除によるOCI規格への影響

Dockerランタイムが使えなくなることで、これまで使っていたDockerイメージやレジストリが使えなくなるのでは?と不安に思う方も一部いらっしゃるようですが、CRI、OCIの関係はこれまでもこれからも変わりません。

CRIランタイムはそれぞれOCIイメージやレジストリを扱うための実装を含んでいるので、ローカルマシンで作成したDockerイメージをレジストリにプッシュしておけば、これまでと同じようにPodがKubernetes上で動きます。

対応の有無の判断基準

今回こちらの記事をお読みになっている方の多くはKubernetesを触ったことがあるか、すでに何らかの環境で動かしている方だと思います。その中でもマネージドサービスを使われている方に関しては、ワーカーノードのタイプを変更するだけでcontainerdへの移行が終わってしまうかと思います。実際の移行例については、イギリスの決済サービスPaybase社のエンジニアがKubeCon EU 2019にて発表した動画「Lessons Learned Migrating Kubernetes from Docker to containerd Runtime」についても合わせてご覧いただくとよさそうです。

確認方法

お使いのKubernetesクラスターに向けて以下のコマンドを実行します。

リスト1:対応が必要かどうかを確認するにはこのコマンドを実行してみる

kubectl get node -o wide
NAME       STATUS   ROLES    AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION                CONTAINER-RUNTIME
minikube   Ready    master   4d18h   v1.19.4   192.168.49.2   <none>        Ubuntu 20.04.1 LTS   4.19.128-microsoft-standard   docker://19.3.13

上記の例のように、CONTAINER-RUNTIMEの項目がdockerになっている場合は、対応が必要となります。以下に対応が必要な場合とそうでない場合のケースについてまとめました。

対応が不要なケース

Kubernetesを使っていない方、使う予定がない人

今回の非推奨はKubernetesにおけるDockerの扱い方が変わるという話なので、今Kubernetesをお使いになられていない場合は特に何も気にする必要がありません。

Kubernetesで動くアプリケーションをDocker(Docker Compose)で開発している開発者

対応不要です。本番を動かす基盤側は影響があるかもしれませんが、手元の開発は変わらないと思ってください。

対応が必要なケース

手元の環境でKubernetesを利用する開発者

本人がなにか対応しないといけないというよりは、使うツールによって対応状況を確認する必要があります。

  • Docker DesktopのKubernetesを使っている場合
    • 2020年12月初頭の段階において、Docker Desktopが今回の措置にどう対応するか発表がなく、またオープンソースでもないため、現状はDocker社の対応を待つしかないでしょう。ただしまだ1年近くは猶予があるため、すぐに問題は発生しません
    • Docker EE(Enterprise Edition)を買収したMirantisがDockershimの継続開発を表明しているため、今後も何らかの形で対応が進んでいくものと思われます
  • Minikubeのnone driverまたはMicrok8sを使っている場合
    • 現状はホスト上のDockerが使われているため、今後はcontainerdのソケットを指定して動かす必要があります
    • Minikubeの場合は「--container-runtime='containerd'」または「'cri-o'」オプションを利用すればよいでしょう
  • Minikubeのdocker driverまたはkindを使っている場合
    • これらは「Docker環境の上でKubernetesを動かす」ためのツールなので、特に開発者が対応することはありません

NVIDIA DockerをKubernetes上で使っている場合

機械学習のアプリケーションがKubernetesの上で動く環境では、多くの場合で「NVIDIA Docker」と呼ばれるツールが使われています。これを移行する場合、現状であればNVIDIA/nvidia-container-runtimeがcontainerdに対応しているため、そちらを利用することができます。

また、NVIDIA/gpu-operatorcontainerdに関する対応を1.4.0で行うと予告しているため、近いうちにリリースされるようです。

Kubernetes上で「Docker in Docker」や「Docker API」を使うワークロードを動かしている場合

例えばDockerイメージのビルド処理や、バッチ処理の都合でDocker APIから何らかのメタデータを取得するなどの処理を行っている場合、何も検討せずにDockerをcontainerdやCRI-Oに入れ替えてしまうとDocker APIが使えなくなってしまうので注意が必要です。

なお、コンテナ関連のメタデータの取得に関してはできる限りKubernetes APIを使うか、Podの環境変数から取得する方向で調査・検討をすすめるほうがよいでしょう。

Dockerイメージのビルド処理については、代替のOSSが存在するためそちらへの移行を検討してください。Dockerが持つイメージビルダーと違いDockerの有無に依存しないため、コンテナ単体で動かすことができるようなものも存在します。

ここでは代表的なOSSを挙げておきます。

また、NTTの須田瑛大氏がKubeCon EU 2019にて発表した「Building Images Efficiently and Securely on Kubernetes with BuildKit」(動画)についても合わせてご覧ください(本人による発表レポートはこちら)。

おわりに

今回の対応は国内外ともに一部ソーシャルメディアでトレンドに上がるなど話題を呼びましたが、Kubernetesにおけるさまざまなユースケースの中でも一部にのみ影響を与えるものとなっています。本記事の情報が基盤運用者、開発者の方にとって技術的な指針となっていれば幸いです。

HPE ソリューションアーキテクト

2018年4月より2年間ZOZOテクノロジーズにてインフラエンジニアとして従事。Kubernetesを用いた機械学習基盤・マイクロサービス基盤や、CI/CDの設計構築を担当。

2020年4月にHPEに入社し、ソリューションアーキテクトとして国内外の顧客へのクラウドネイティブ技術を用いた基盤の提案や導入などに携わる。CNCFアンバサダーとして国内向けに海外の最新事情を発信するなどOSSコミュニティでも活動中。

連載バックナンバー

システム開発イベント

OpenShift Commons Gatheringで語られたOpenShiftに最適なCI/CDとは

2021/3/2
レッドハット株式会社のクラウドソリューションアーキテクト、北山晋吾氏によるCI/CDのセッションを紹介。
働き方イベント

オンラインならではの工夫でリアル開催を凌ぐ盛り上がりに! 「3年後の未来を描け! 悩み爆発 クリエイター1000人祭り」レポート

2021/2/9
2020年12月にオンラインで開催された「3年後の未来を描け!悩み爆発クリエイター1000人祭り」を紹介します。
ITインフライベント

ビルドからリリースまでを抽象化するWaypointにディープダイブ

2021/2/4
HashiCorpがリリースしたWaypointの内部構造など詳細について解説されたセッションを紹介する。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています