今話題のこれ。
これに関しての日本語情報として、 @inductor が相当詳細に記事を書いてくれている。
にも関わらず、未だに完全に間違った解釈をしている人が多く観測される。記事をちゃんと読めば理解できるはずなのだけど、たぶんタイトルしか読んでいない。
タイトルしか読まないのであれば、あえて強めのタイトルにしておけば目にはつくかなと思い、改めて書いてみることとした。
Dockerは非推奨じゃないし、これからもバンバン使え
まず @inductorが解説しているとおり、k8sを使っていない人には全く関係のない話なので、今まで通りDockerを使って良い。 が、もう一つ誤解を解いておきたいのが
自分の環境でDockerを使ってイメージ作成し、Kubernetesにデプロイしている人にも、今回の件は関係が無い。
Kubernetesを使っていてもDockerはバンバン使っていいし、今のあなたたちが行っているワークフローには何の変化もない。
今回の件で騒いでいる人たちは、この部分を勘違いしているように思う。
今までもこれからも、Dockerを使うことは推奨するし、本番で動かすときはDockerで作ったイメージをKubernetesに持って行って良い。
じゃあ何で非推奨って話になったのか
今回の件は、Kubernetes内部のコンテナランタイムとしてDockerを利用するのがDeprecatedになったという話。言い方を変えると、Kubernetesを自前で構築して使ってる人くらいにしか影響がない。 上記の記事で十分に説明されていると思うけど、自分が他の人に説明する際に使った絵を使うとこんな感じだ。
普通にDockerを使う場合
普段 docker run
のようなコマンドを使っていると思うが、内部的にはざっくりこんな感じの動きになっている。 docker
コマンドはDockerのAPIを通じて、最終的には裏側にいるコンテナランタイムによって実行される。Dockerは内部で containerd
という仕組みを使っていて、そこで動く。
KubernetesでDockerを使っている場合
KubernetesのコンテナランタイムでDockerを指定している場合はこうなる。人間がdockerコマンドを叩く代わりに、kubernetesの中の人がDocker APIを叩いてくれるイメージだ。
上記の絵を、もうちょっと付け加えるとこう。Kubernetesがコンテナランタイムと喋るときにはCRIという仕様を元に行うのだけど、DockerはCRIに対応していない。なので、 dockershim
というブリッジを経由して通信を行っている。
今回の話
でも実は、Docker内部の containerd
は、CRIに対応しているのである。
え、じゃあcontainerdと直接通信すれば、dockershimもdocker apiも要らないんじゃない?
そう、今回の話は、ただそれだけの話なのである。
ふつうに考えればcontainerdを直接叩いた方が運用の面でも、セキュリティの面でも、リソース効率の面でも効率がいい。実際多くのディストリビューションがcontainerdやcri-oといったCRIを喋れるコンテナランタイムを直接使うようになっている。
ならば、もうそろそろDockerのところは必要性が薄れてきたよね、となったのが今回の話。
Dockerが大きく普及したのが2013年ごろ。Kubernetesが登場したのが2014年。この段階ではKubernetesがDockerをコントロールする構図は自然な流れだった。
その後様々なコンテナ規格の乱立が始まったため、標準規格を定めようという動きになったのが2015年から2016年にかけて起こり、そこでcontainerdやCRIが登場した。こうした歴史的な経緯を経て、より効率の良い方向へと変わってきたわけだ。
これからもバンバンDockerを使えというワケ
繰り返しになるが、今回の件はKubernetes内部の一部品としてDockerが使われなくなるというだけなので、Kubernetesの利用者には何の影響もないと言って良い。
ごく一部の利用者には影響があるかもしれないが、そういった深い使い方をしている人であれば、そもそも今回の件で慌てることはないだろう。
利用者には影響はないという理由
Dockerがここまで普及したのは、Build, Ship, Runというワークフローを確立したところにある。
- Dockerfileを書き、
docker build
コマンドでイメージを作成する。 docker push
コマンドでイメージをRegistryにpushする- 他の人がpushしたイメージをそのまま使うことも出来る
docker run
でコンテナを実行するdocker-compose
を使うとより便利
Kubernetesを使う場合も、このワークフローはそのまま利用することが出来る。
Build, Shipのフェーズはそのままで、Runのところが変わる。 docker run
や docker-compose up
する代わりに、YAMLでManifestを書き kubectl apply
するわけだ。開発のワークフローはそのままに、より高度な運用(Run)が出来るようになったのがKubernetesの利点である。
じゃあ今回の件で何が変わるか? 何も変わらない。
今まで通りにDockerfileを書いてDocker image作ればいいし、kubectl apply
するところも全く同一だ。 デプロイした先でのKubernetesの内部コンポーネントの通信先がちょこっと変わっているだけである。
そう、だからDockerは今まで通り便利なツールとして使い続けられるし、もちろんDocker以外のツールを使ってもいい。
標準規格によって、利用者はどんなツールを使っても互換性の問題に悩むこと無く恩恵にあずかれるのが、今のCloud Native技術だしCNCFの存在意義である。そして今回の話は、標準規格がしっかりしているからこそ出来た、極めて健全な発展を裏付けるものなのだ。 だって大きな互換問題が発生するんであればこうも簡単にDeprecatedに出来ないよね。
互換性の問題でレガシーを引きずるソフトウェアがごまんとある中でこういった移行ができるのは、むしろ賞賛されるべきことだと考える。
ビジネスとしてのDocker(社)の動きについて
Docker社がビジネス的な観点で大きなチャンスをモノにできなかった話は、言わんとすることは分かるし自分としても思うところはたくさんある。
しかし、今回の件は決してDockerがビジネス的に衰退したから切り捨てられるってわけじゃなくて、技術的にあるべき形に進化したというだけだ。
そりゃ確かにDocker swarmあたりを成功させていれば、ここまでのKubernetes1強にはならなかったかもしれない。しかしそれは全く別次元の話であって、今回の件に絡めて『Dockerはオワコン』みたいな話に持って行くのも、なんか違うんじゃないかな。
結論
もう何度目の繰り返しになるか分からないけど、 DockerもKubernetesも超便利な仕組みだし、まだまだ発展していくのでこれからも便利に使っていこう。
追記
良いタイミングで良い本が出たので紹介。今回の件で慌てちゃった人にはすごくお勧め