仮想マシンとDocker: 重い家と軽いテント

「Linux の仮想マシンを入れて、環境をまったく同じにしてみて」

入社3か月目、オフィスの空気はどこか落ち着かなかった。唯一の先輩は別プロジェクトへの異動が決まり、引き継ぎどころか自分の荷物をまとめるので手いっぱいだったし、チーム長は実際の開発現場から長く離れていて、最新技術の流れにはかなり疎かった。

ある日、チーム長が私を呼んだ。 「先輩がいなくなったら、サーバーを見られるのは君しかいない。サーバーが落ちても一人で復旧できるようにならないといけない。今使っている開発用ノートPC、Windows に Linux を仮想マシン(VM)として入れて、本番サーバーと同じ環境を作ってみて」

その日から私の泥沼が始まった。VMware を入れ、Ubuntu の ISO ファイルを落としてインストールするだけで半日かかった。社内 wiki をあさりながら Java、Node.js、PostgreSQL を入れた。「新しいほうがいいだろう」と思って Java 17 を入れたら、レガシーコードは Java 8 前提で、ビルドすら通らないことが分かった。結局アンインストールして入れ直しだ。コードを1行直すたびに mvn build を回し、jar ファイルを VM に持っていって実行する作業は、まさに苦行だった。

そんなある時、ふと疑問が浮かんだ。 「待って、この前本番サーバーにデプロイしたときって、docker service update を1行打っただけで終わってなかったっけ?」

自分のローカル仮想マシンはこんなにも重く、設定することも山ほどあるのに、本番サーバーにいるあの「Docker」とは一体何者で、どうしてコマンド一発で更新できるのだろう?

環境を丸ごと運ぶもっとも軽い方法、それが Docker だ。

重い解決策: 仮想マシン (Virtual Machine)

チーム長に言われた方法、つまり Windows の上に Linux をもう一つ入れる方法こそが「仮想マシン(VM)」だ。これは物理コンピュータ、Host の上に「仮想の家」、つまり Guest OS を丸ごと建てるようなものだ。

結局、VM は「環境の分離」という点では確実だが、開発やデプロイのたびにやり取りするには、あまりにも重くて遅かった。

軽い革命: Docker

そこで登場したのが「Docker」、つまり「コンテナ(Container)」技術だ。Docker は VM のように家を丸ごと建てない。代わりに「テント」を張る。

私が本番サーバーで打った update コマンドは、重い OS を入れ直していたわけではない。ただ「古いテントをたたんで、新しいコードが入ったテントを張り直していた」だけなのだ。だから一瞬で終わるしかなかった。

[Code Verification] Docker は本当に軽いのか?

口先だけで軽いと言うのではなく、実際に確かめてみよう。Linux、Ubuntu 環境を動かすとしたとき、VM と Docker の差ははっきりしている。

# Dockerコマンドでubuntuを実行(イメージがなければダウンロードも自動)
$ docker run -it ubuntu:latest /bin/bash

結果:

Enter を押した瞬間、私はもう Ubuntu 環境の中にいる。これが可能なのは、Docker コンテナが本物の OS ではないからだ。つまり「Host OS、自分のコンピュータ、のカーネルを借りながら、あたかも別の OS のように振る舞う隔離空間」にすぎない。

実務アドバイス: Docker を使う本当の理由

実務で Docker を導入してから、私の仕事のやり方は完全に変わった。

おわりに: 実行ファイルではなく「環境」を届ける

Docker の登場によって、開発のパラダイムは変わった。私たちはもうソースコード、.java、だけをサーバーに送らない。そのコードが動くための OS 設定、ライブラリ、環境変数まで含めて「イメージ(Image)」として固め、丸ごと届けるようになった。

では、この魔法のような「Docker イメージ」は一体どうやって作られるのだろう? ただの圧縮ファイルなのだろうか? 驚くべきことに、Docker イメージは「ケーキ」のように複数のレイヤー(Layer)で積み重なっているらしい。

次回は、Docker の効率性の秘密である「イメージとレイヤー構造」について掘り下げてみよう。

コメントする