Dockerって難しくね

Docker 勉強会#

この間 Docker について会社の人の前で話す機会があって Docker の基本的なことについて話しました。で思ったんだけど、 Docker って難しくないですか。改めて。

例えば仮想化に関する話をしようとすると、完全仮想化(e.g. VirtualBox)や準仮想化(e.g. Hyper-V)とコンテナ型仮想化の違いとか、systemd-nspawn と Docker って何がちゃうんやろとか1。ではアプリケーションコンテナってなんやとか、Registry/Image/Container と pull/build/run/exec/push などの各コマンドがどう関連しているのかとか(つまりはこのコマンドは何に対してどんな操作をするのかとか)。 docker コマンドの体系複雑すぎないとか。

自分がイチから Docker を学んだときってどう学んだっけな、って考えると正直真面目に学んだ記憶がない。だけどいつの間にか Docker の思想を内面化していて、できるようになっていったんですよね。それは才能とかセンスとかではなくて、誰かが教えてくれたり、「こうしたほうが楽じゃん」に遠回りして気づいたり、というのを長い時間かけてやってきたからだと思う。

あまりにも当たり前過ぎて Docker を使うの別に難しくないじゃんくらいに思っていたんだけど、改めて自分が知っていることを書き出してみたらなんとまぁ多いこと。もちろん知らないこともいっぱいあるし、 docker run -idocker run -it の違いを説明せよとか言われたらちょっと勘弁してくれって思う。だけどそんな僕でも Docker はそこそこ使えるなって実感があるし、そのそこそこ使えるぞにたどり着くまでにかかった時間って決して短くない(最低半年はかかってる)。

Docker の難しさ#

Docker がなんで難しいかって、結局アプリケーションのものだからだと思う。

それ以前は開発環境にせよ本番環境にせよ環境はポータブルではないので、環境とアプリケーションがある意味で切り離されていた。Windows で動く Web アプリケーションが Linux でも動くとは限らないので Linux サーバーを立ててデプロイしてみて動くやんけ動かんやんけとワイワイやって、頑張ってサーバー起動してうんぬんということをしていたわけだ。でもそれはアプリケーションの開発とは全く別枠として行われていた。

一方で、 Docker は Dockerfile だとかでラップしているけれど、ある種むき出しのインフラが、語弊を承知で言うとむき出しの Linux がアプリケーションエンジニアの前に表出している状態ではある。僕はちょっと変な人なのでデスクトップ Linux を常用しているし2apt-getdnfpacman もなんでもござれ、シェルとか環境変数とか慣れっこな人だけど、普通の人はそうではない。

Docker の登場で、アプリケーションがアプリケーションを動作する環境を規定することが簡単にできるようになった。例えば hadolint とかはすごい。コマンドラインツールだが、標準入力を受け取るだけなので、コンテナの中で全てが完結する3。hadolint の実行環境は hadolint の開発者の一存で決められるし、環境を変えてもユーザーになんの影響もない。これは本当にすごいことだ。

もちろん Web サービスであれば、本番環境で動かすなら ECS だとか Kubernetes だとか Nomad だとか Swarm だとか、考えるべきところはいろいろある。だけどそこまで行くとインフラエンジニアと協業する枠で、アプリケーションエンジニアだけのものという感覚がない、と個人的には感じる。

一方で、Docker は既に完全にアプリケーションのものだと思う。アプリケーションの実行環境はアプリケーションが規定するべきだし、そのコストは Docker を学ぶこと以外存在しない。アプリケーションの実行環境はインフラエンジニアが「用意するもの」ではなく、開発者が自分たちで「規定するもの」であり、そして変化するソフトウェアの一部になっている。何年か前から。

唯一の障壁#

ただ、残念ながら Docker は難しい。改めて思った。

勉強会では、仮想化についての話は一切しなかった。 docker コマンドの本当にごく一部、 run, exec, pull, ps, images, prune などについて簡単な解説をしたが、それでも十分大変だった。

Git の難しさと似ている。それができれば何ができるのか、よくわかっている人には当たり前なんだけどその凄みを伝えるのは難しいと感じる。たとえばさっきの hadolint ってめちゃくちゃすごいと思うし、Docker があればこそ成立する配布方法なのだが、それをすごいと思ってくれる人は既に Docker の凄さをわかっている人だと思う。

空気のように存在しているものは、それが当たり前すぎて却ってその凄みを感じづらい。昔クラスがある言語を使うことはあらゆる言語がクラスをサポートするほどには先進的だったのだろうけど、今はそれが当たり前すぎてクラスがない言語を触ると「なんでないの?」と思うことだろう。それが例えば Git であり、 Docker であるのだと思う。わたしはバックエンド側の人間だからよく知らないけど、仮想 DOM とかもそういう存在になりつつある(もうなっている?)のではないか。

あとコンテナを軽い仮想マシンと思うとかえって使いづらいと感じると思う、という話は加算無限回しているけど、なんとなく軽い仮想マシンとして使っている人はまだこの世にいっぱいいそうな気がする。

終わりに#

ここまで書いてアプリケーションって書きまくったけどだいたい Web を想定していた。モバイルとかそういうのは想定していません。ごめんなさい。

何をすれば Docker をわかった気になるのか、ということを考えて、とりあえず用語の整理と基礎的なコマンドを紹介する、以上の手が浮かばなかった。たぶん Git 勉強会をやっても同じことを思う気がする。

価値が見えづらいものの価値を伝える、ということはすごく意義があることだと思うので僕は好きだ。だけど、楽な仕事かというと決してそうではない。なんとか Docker の価値を伝え続けていきたいなと感じてはいる。

そのうち Git についても小言を書こうかなと思ったり思わなかったり。


  1. これを書いている筆者も知りません。 ↩︎

  2. このブログも ThinkPad T480s にインストールした Ubuntu 20.04 で書いている。 ↩︎

  3. ちなみに hadolint は Dockerfile の Lint ツールなので Docker がインストールされていることを前提にしてよい、という大前提があってこれが成立している。 ↩︎