のび太でもわかる「コンテナ」とは何か?
0.はじめに
最近、業務をしていると、毎日のように「コンテナ」という言葉を耳にします。
いざ、コンテナって何なんだろうと調べてみると、何を言っているのかよく分かりませんでした。(RedHatさんごめんなさい🙇今はとてもよく分かります。)
コンテナは、アプリケーションとランタイム環境全体、つまり実行に必要なすべてのファイルをパッケージ化し、分離させるテクノロジーです。これにより、コンテナ内のアプリケーションを、すべての機能を維持したまま複数の環境 (開発、テスト、本番環境など) の間で容易に移行することができます。
そこで、のび太でもわかるようにコンテナの正体に迫ってみました。
1.コンテナはホストOS上のバカでかプロセス
ざっくり言うと、コンテナの正体はホストOS上に浮かぶバカでかプロセスです。
このプロセスの中に、アプリケーションの実行に必要なすべてが詰まっているのです。
プロセス、コンテナ、VMを比較しながら全体を見てみましょう。
いちばん左側のプロセスは、ホストOS上で浮かぶ、ごく普通のプロセスです。
一方、真ん中のコンテナは、ホストOS上に直接プロセスを起動するのではなく「コンテナエンジン(Dockerなど)」経由でコンテナ(プロセス)を立ち上げます。
ホストOS上から見ると、コンテナはプロセスの一種なので、普通のプロセスと同じ色にしてます。
右側のVMは、ハードウェア上にハイパーバイザー(VMwareなど)がインストールされ、各VMが実行されます。各VMは独自のOS(ゲストOS)を持ち、その上でプロセスが実行される形になります。
「コンテナエンジン」がどのようにコンテナを「特別なプロセス」として生成しているのかですが、それは以下のようなホストOS上の機能をうまく使って実現しております。
- Linux Namespaces:OSリソースの割り当て
- cgroups:物理リソースの制限
コンテナを支える技術は少しややこしいので詳細は省きますが、以下記事に詳しく載っているのでご興味ある方はぜひお読みください。
コンテナ技術入門 - 仮想化との違いを知り、要素技術を触って学ぼう
2.コンテナの中身は階層レイヤー
コンテナ中身がどうなっているかというと、複数のソフトウェアパッケージ(イメージ)を細分化(レイヤー)したものから成り立ちます。
レイヤー管理することにより、共通して使用されるOSレイヤーなどを再利用し、効率化を図ってます。
Linuxなど基本となるOSレイヤーをベースにミドルウェアやアプリケーションが積み重ねることによって1つの「イメージ」が形成され、それを元にコンテナを作ります。
次の章で、コンテナの作り方を見ていきましょう。
3.コンテナの作り方
コンテナのイメージは構成ファイル(Dockerfileなど)にイメージ作成の手順を記述するのが一般的です。その中で、イメージに変更を加える命令が実行されるたびに新規のレイヤーが作成されていきます。
コンテナファイルに手順を記述することで、構成管理を兼ねることができ、デプロイの再現性も高くなります。
docker run
やdocker pull
でイメージをダウンロードしてきた後は、Linuxの場合、ローカルの/var/lib/docker
配下にイメージが保存されます。
また、docker history
で、各イメージが作成されたときのコマンド一覧を表示できますが、その際に「SIZE」欄に変更があるコマンドが新しいレイヤー作ることになります。
$ docker history 30973f336f15
IMAGE CREATED CREATED BY SIZE COMMENT
30973f336f15 25 hours ago CMD ["jupyter" "lab" "--ip=0.0.0.0" "--allow… 0B buildkit.dockerfile.v0
<missing> 25 hours ago WORKDIR / 0B buildkit.dockerfile.v0
<missing> 25 hours ago RUN /bin/sh -c pip install --upgrade pip # b… 13.8MB buildkit.dockerfile.v0
<missing> 25 hours ago ENV PATH=/opt/anaconda3/bin:/usr/local/sbin:… 0B buildkit.dockerfile.v0
<missing> 25 hours ago RUN /bin/sh -c wget https://repo.anaconda.co… 3.23GB buildkit.dockerfile.v0
<missing> 25 hours ago WORKDIR /opt 0B buildkit.dockerfile.v0
<missing> 25 hours ago RUN /bin/sh -c apt-get update && apt-get ins… 114MB buildkit.dockerfile.v0
<missing> 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:7f9a3c5a4231ed191… 77.9MB
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
4.コンテナのメリット
さいごに、コンテナ化をすると何が嬉しいのかを述べます。
- 1.環境によらずアプリケーションを安定して稼働できる
- 2.起動やデプロイが高速
- 3.デプロイ作業が楽で再現性が高い
4.1.環境によらずアプリケーションを安定して稼働できる
開発環境からテスト環境や本番環境へコンテナを移動する場合や、オンプレミスの環境からクラウドの環境へコンテナを移動する場合でも、同じようにアプリケーションが稼働できる点です。
コンテナ化しない場合、環境変数や依存関係が環境毎にきちんと揃っていないと、環境によってアプリケーションの動作が違ったり、最悪動作しないことがあります。
しかし、コンテナではそれらを内包している(イメージ化)ため環境の違いに左右されにくく、安定して稼働させることができます。
4.2.起動やデプロイが高速
VMと比較したとき、各コンテナはホストOSを共通して利用するため、起動が非常に早いです(体感、秒単位VS分単位)。
また、コンテナの元になるコンテナイメージはVMのイメージと比較してサイズも小さいため、デプロイを迅速に行うことが可能です。
起動やデプロイが迅速に行えることで、メンテナンス時間や障害時の復旧時間短縮に貢献できます。
4.3.デプロイ作業が楽で再現性が高い
伝統的なアプリケーション構築ではデプロイの手順をまとめた手順書があり、エンジニアがそれを元に手動でファイルをインストールするようなことが行われていました(すごく大変で時間が掛かります)。
コンテナは、ファイルの配置方法などの手順が記述された構成ファイル(Dockerfileなど)を元に作成されます。
そのため、コンテナを利用すると一連のデプロイ作業の大部分がすでに終わった状態で利用できるようになります。
また、この構成ファイルはソースコード管理システムでバージョン管理が可能なため、再現性の高いデプロイを行うことが可能です。
5.おわりに
最後までお読みいただきありがとうございました。
冒頭のRedHatさんの説明文がいかに端的で分かりやすく記述されているかご理解いただけましたでしょうか?
コンテナ関連技術は、実際に手を動かしてみるとすごくよくわかるので、ぜひお試しください。
次回以降、具体的な手を動かす内容について記事を書けたらなと思います。
Discussion