Cloud Penguins

Flying penguins in the cloud.

Dockerは非推奨じゃないし今すぐ騒ぐのをやめろ

今話題のこれ。

kubernetes.io

これに関しての日本語情報として、 @inductor が相当詳細に記事を書いてくれている。

blog.inductor.me

blog.inductor.me

にも関わらず、未だに完全に間違った解釈をしている人が多く観測される。記事をちゃんと読めば理解できるはずなのだけど、たぶんタイトルしか読んでいない

タイトルしか読まないのであれば、あえて強めのタイトルにしておけば目にはつくかなと思い、改めて書いてみることとした。

Dockerは非推奨じゃないし、これからもバンバン使え

まず @inductorが解説しているとおり、k8sを使っていない人には全く関係のない話なので、今まで通りDockerを使って良い。 が、もう一つ誤解を解いておきたいのが

自分の環境でDockerを使ってイメージ作成し、Kubernetesにデプロイしている人にも、今回の件は関係が無い

Kubernetesを使っていてもDockerはバンバン使っていいし、今のあなたたちが行っているワークフローには何の変化もない

今回の件で騒いでいる人たちは、この部分を勘違いしているように思う。

今までもこれからも、Dockerを使うことは推奨するし、本番で動かすときはDockerで作ったイメージをKubernetesに持って行って良い。

じゃあ何で非推奨って話になったのか

今回の件は、Kubernetes内部のコンテナランタイムとしてDockerを利用するのがDeprecatedになったという話。言い方を変えると、Kubernetesを自前で構築して使ってる人くらいにしか影響がない。 上記の記事で十分に説明されていると思うけど、自分が他の人に説明する際に使った絵を使うとこんな感じだ。

普通にDockerを使う場合

普段 docker run のようなコマンドを使っていると思うが、内部的にはざっくりこんな感じの動きになっている。 docker コマンドはDockerのAPIを通じて、最終的には裏側にいるコンテナランタイムによって実行される。Dockerは内部で containerd という仕組みを使っていて、そこで動く。 f:id:jaco-m:20201203162951p:plain

KubernetesでDockerを使っている場合

KubernetesのコンテナランタイムでDockerを指定している場合はこうなる。人間がdockerコマンドを叩く代わりに、kubernetesの中の人がDocker APIを叩いてくれるイメージだ。 f:id:jaco-m:20201203163334p:plain

上記の絵を、もうちょっと付け加えるとこう。Kubernetesがコンテナランタイムと喋るときにはCRIという仕様を元に行うのだけど、DockerはCRIに対応していない。なので、 dockershim というブリッジを経由して通信を行っている。 f:id:jaco-m:20201203163809p:plain

今回の話

でも実は、Docker内部の containerd は、CRIに対応しているのである。 え、じゃあcontainerdと直接通信すれば、dockershimもdocker apiも要らないんじゃない?

f:id:jaco-m:20201203164237p:plain

そう、今回の話は、ただそれだけの話なのである。

ふつうに考えればcontainerdを直接叩いた方が運用の面でも、セキュリティの面でも、リソース効率の面でも効率がいい。実際多くのディストリビューションがcontainerdやcri-oといったCRIを喋れるコンテナランタイムを直接使うようになっている。

ならば、もうそろそろDockerのところは必要性が薄れてきたよね、となったのが今回の話。

Dockerが大きく普及したのが2013年ごろ。Kubernetesが登場したのが2014年。この段階ではKubernetesがDockerをコントロールする構図は自然な流れだった。

その後様々なコンテナ規格の乱立が始まったため、標準規格を定めようという動きになったのが2015年から2016年にかけて起こり、そこでcontainerdやCRIが登場した。こうした歴史的な経緯を経て、より効率の良い方向へと変わってきたわけだ。

これからもバンバンDockerを使えというワケ

繰り返しになるが、今回の件はKubernetes内部の一部品としてDockerが使われなくなるというだけなので、Kubernetesの利用者には何の影響もないと言って良い

ごく一部の利用者には影響があるかもしれないが、そういった深い使い方をしている人であれば、そもそも今回の件で慌てることはないだろう。

利用者には影響はないという理由

Dockerがここまで普及したのは、Build, Ship, Runというワークフローを確立したところにある。

f:id:jaco-m:20201203165855p:plain

  • Dockerfileを書き、 docker build コマンドでイメージを作成する。
  • docker push コマンドでイメージをRegistryにpushする
    • 他の人がpushしたイメージをそのまま使うことも出来る
  • docker run でコンテナを実行する
    • docker-compose を使うとより便利

Kubernetesを使う場合も、このワークフローはそのまま利用することが出来る。

f:id:jaco-m:20201203170245p:plain

Build, Shipのフェーズはそのままで、Runのところが変わる。 docker rundocker-compose up する代わりに、YAMLでManifestを書き kubectl apply するわけだ。開発のワークフローはそのままに、より高度な運用(Run)が出来るようになったのがKubernetesの利点である。

じゃあ今回の件で何が変わるか? 何も変わらない

f:id:jaco-m:20201203170725p:plain

今まで通りにDockerfileを書いてDocker image作ればいいし、kubectl apply するところも全く同一だ。 デプロイした先でのKubernetesの内部コンポーネントの通信先がちょこっと変わっているだけである。

そう、だからDockerは今まで通り便利なツールとして使い続けられるし、もちろんDocker以外のツールを使ってもいい。

標準規格によって、利用者はどんなツールを使っても互換性の問題に悩むこと無く恩恵にあずかれるのが、今のCloud Native技術だしCNCFの存在意義である。そして今回の話は、標準規格がしっかりしているからこそ出来た、極めて健全な発展を裏付けるものなのだ。 だって大きな互換問題が発生するんであればこうも簡単にDeprecatedに出来ないよね。

互換性の問題でレガシーを引きずるソフトウェアがごまんとある中でこういった移行ができるのは、むしろ賞賛されるべきことだと考える。

ビジネスとしてのDocker(社)の動きについて

Docker社がビジネス的な観点で大きなチャンスをモノにできなかった話は、言わんとすることは分かるし自分としても思うところはたくさんある。

しかし、今回の件は決してDockerがビジネス的に衰退したから切り捨てられるってわけじゃなくて、技術的にあるべき形に進化したというだけだ。

そりゃ確かにDocker swarmあたりを成功させていれば、ここまでのKubernetes1強にはならなかったかもしれない。しかしそれは全く別次元の話であって、今回の件に絡めて『Dockerはオワコン』みたいな話に持って行くのも、なんか違うんじゃないかな。

結論

もう何度目の繰り返しになるか分からないけど、 DockerもKubernetesも超便利な仕組みだし、まだまだ発展していくのでこれからも便利に使っていこう。

追記

良いタイミングで良い本が出たので紹介。今回の件で慌てちゃった人にはすごくお勧め

jaco.udcp.info