第1回 Dockerとは?コンテナ、概要、仕組みについて。
第1回 Docker解説 コラム
この連載コラムでは、仮想化技術のDockerとは?について、数回に分けてお伝えします。
はじめは入門編として、概要や簡単な仕組みを説明します。最後は実践編として、実際のコマンドの動かし方を紹介します。
本連載は、次のような想定・目的で記述しています。
想定する読者 |
|
想定する読者の 知識レベル |
|
本連載を読んだ後に得られる期待値 |
|
目次
1. Dockerとは
コンテナとは
最初に、簡単にコンテナについて説明しておきましょう。
よく目にするものでは、貨物コンテナをご存じだと思います。船に積まれていたり、道路でトレーラーに引っ張られていたりする箱ですね。あれは、運搬を効率化するためにブロックとして扱えるようにしたものです。規格化したパッケージとして取り扱い、中に何が入ってるかは気にしなくていいようになっています。それをソフトウェアに応用したもの、中に何が詰まってるかを気にしなくていいようにしたものが、ここで言うコンテナです。
ソフトウェアを標準化されたユニットにパッケージ化したものである
構成は、オペレーティングシステムの上に、コンテナエンジンが介在し、その上で各アプリケーションが動く、という形です。この図はDockerのものですが、Dockerがコンテナエンジンであり、その上のApp AやApp Bといったアプリケーションが、たとえばJavaの実行環境やDBなどに相当します。
Dockerのコンセプト
アプリケーションのビルド・実行環境を共有するプラットフォームである
従来、開発環境とリリース後の実行環境は違っていました。それを、コンテナを使用することによって、開発時とリリース後に、完全に同じプラットフォームを利用できるようにする、というのがDockerのコンセプトです。
Dockerの公式チュートリアルでは、Dockerの特徴として、Flexible、Lightweight、Portable、Loosely coupled、Scalable、Secureの6点が挙げられています。(https://docs.docker.com/get-started/#docker-concepts, 参照 2020-10)
- 高順応(Flexible):
複雑なアプリケーションでもコンテナ化が可能です。 - 軽量(Lightweight):
コンテナはホストのリソースを共有して使用するため、これまでの仮想マシンという仕組みよりも、リソースの点ではるかに効率的です。 - ポータブル(Portable):
開発環境でも実行環境(リリース環境)でも、ローカルでもクラウドでも、まったく同じものが実行可能です。 - 疎結合(Loosely coupled):
基本的に1つのコンテナには1つの機能を収めることが推奨されています。そうすることによって自己完結型でカプセル化されるため、他のコンテナへの影響を限りなく少なくして、機能単位でアップグレードすることが可能になります。 - 高拡張性(Scalable):
レプリカによりコンテナの数を簡単に増やせるため、大規模なデータセンターのようなサーバを構築している場合でも、分散が可能で、必要になったらスケールアップ、使わなくなったらスケールダウンというのが、容易にできるようになっています。 - 安全(Secure):
標準で他のプロセスと分離されているため、たとえばあるプロセスがハックされたとしても、よそのコンテナに入り込むためにはまた一からセキュリティホールをついて侵入することをしなければ攻撃ができません。
クリーンな開発環境
コンテナの大きな利点に、クリーンな開発環境を利用できることが挙げられます。
「何もしてないのにビルドエラーになりました」という話を日常の仕事で聞いたことがあるのではないでしょうか。ビルド環境は、さまざまな要因で変わっていきます。ソースファイルが追加された、差分makeで中間生成物がたまっていった、環境変数が追加されたが各自の環境に導入されなかった――そういった原因で、あるとき突然動作しなくなることがあります。
Dockerの場合、ある1つのイメージを新しく使用し、使い終わったら廃棄することが簡単になります。“docker pull”し、 “docker run”することで、手間なく、常に同じ環境、常にクリーンな状態でビルドを実行できます。
開発環境配布が軽量
開発段階では、仮想マシンで開発環境を構築したものを共有して使うことがあります。たとえばVirtualBoxやQEMUで開発環境を構築し仮想マシンイメージを作成し、配布する場合などがこれに該当します。ただし、これにはいくつか難点があります。
- スナップショットサイズが大きい:
数GBになることが通常で、ダウンロードして手元へ展開するにも手間がかかります。また、更新して不具合が出たときに古いものに戻すのも大変です。 - スナップショットの内容が記録できない:
履歴管理は可能ですが、仮想マシンに何が含まれているかは別途管理する必要があります。「Aというアプリケーションを入れました、次にBというアプリケーションを入れました、設定はこうです……」というのを逐次記録しておかないと、何が行われたのかわからないものとなります。この記録のメンテナンスはとても大変です。
こういった問題がDockerでは解決されています。
- イメージが非常に軽量:
Dockerイメージは数MB程度の場合がほとんどです。 - イメージの取得も簡単:
コマンド1つ実行すれば新しいイメージを取得できます。明示的に消さない限りは古いイメージも残っているので、起動時のコマンドを少し変えれば、すぐに古いものも使用できます。 - コンテナの管理にはDockerfile:
Dockerfileという、システム構築の定義書がテキストファイルとして用意されていて、どういうものをどういう順番で実行して作成したかが明確になっています。そのため、どこでも誰でも全く同じイメージを作ることができます。 - 公式イメージを利用可能:
提供されている公式イメージを使用すると、イメージ生成作業が不要になります。たとえばPythonの公式イメージを取得すれば、Pythonが動く環境が簡単に入手できます。また、JenkinsのようなCI環境が入ったものや、PostgreSQLなどのデータベースが入ったものも用意されています。
Docker利用例
こういったことを踏まえて、具体的なDockerの利用例を見てみましょう。
利用例1:pyenvを使わずにPythonのバージョンを切り替える
Pythonのバージョンを切り替えるには、通常はpyenvを使用します。ただし、頻繁に切り替える場合、どちらのバージョンで走らせているのか混乱しますし、バージョンをまたいで影響が生じるものかわかりにくいのも難点です。
Dockerではどのように切り替えられるでしょうか。たとえば、Dockerホスト(Dockerを実行するPC)上のPythonスクリプト「hello_docker.py」を、異なるバージョンのpythonで実行する例を見てみましょう。
print("Hello!! Everybody in eXmotion.")
print("python's version is")
print(sys.version)
コマンドに指定するDockerイメージの名前を変えるだけで、これをPython 2.7.8と最新版のPythonで実行することができます。通常、Dockerからはホストのファイルは見えないのですが、「-v "$PWD":/usr/src/myapp」の部分でコンテナから同じファイルを見えるようにすることで、両コマンドで同じスクリプトを実行させています。
Python 2.7.8
python's version is
2.7.8 (default, Dec 3 2014, 02:28:14)
[GCC 4.9.1]
最新Python(3.8.5)
python's version is.
3.8.5 (default, Sep 10 2020, 16:58:22).
[GCC 8.3.0]
これは次のように実行されています。
- python環境は事前インストール不要です。Dockerさえインストールしておけば、このコマンドだけでPython2.7.8や最新版のPythonが動きます。
- イメージがホスト上に存在しない場合、上記コマンドのみで公開レジストリであるDockerHubからイメージを自動的にダウンロードして実行します。
- pyenvによる切り替えの代わりにdockerを使用するため、相手のコンテナ(Python 2.7.8を実行したコンテナ)の存在はまったく認識できず、互いへの影響は皆無です。
利用例2:GCCバージョンを切り替えて動作確認する
こちらは、gccの4.9と最新版を切り替える例です。この場合も、違いがあるのはDockerイメージの部分だけです。他のgccコマンドなどは、4.9と10.2.0とまったく同じでバージョンの切り替えができます。(プログラムコードは省略)
gcc4.9
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
hello docker world with gcc!!
最新gcc(10.2.0)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
hello docker world with gcc!!
これは次のように実行されています。
- 利用例1と同様、gccは事前インストール不要です。
- イメージがホスト上に存在しない場合、上記コマンドのみで公開レジストリであるDockerHubからイメージを自動的にダウンロードして実行します。
- 相手のコンテナ(gcc4.9を実行したコンテナ)への影響はありません。ただし、コンパイル系の言語の場合、オブジェクトファイルや実行形式ファイルが生成されるため、makeを作って差分コンパイルをするような場合には、中間生成物の生成場所に注意する必要があります。中間生成物などはコンテナの中に出力し、ソースファイルだけをホストと共有して、EXE実行形式やライブラリなどの最終生成物を決まった場所に出力する、といった仕組みを使うとよいでしょう。この例では、バインドマウント(実践編にて説明します)にて、コンパイル生成物をソースファイルと同じディレクトリに出力しています。
Eureka Boxは厚生労働省が実施している助成金、人材開発支援助成金の適用対象となります。
2. 仮想化の種類と特徴
仮想化技術を導入すると、1つの物理マシン上で複数のマシンがあるように見せることができます。物理マシンのプロセッサやメモリと言ったリソースを、仮想化されたサーバそれぞれに分配して使用します。トータルで物理マシンの能力を超えることはできないので、サービスの質を上げようと思うと、最終的には物理マシンを複数台にしたり強力なマシンを用意したりする必要が生じます。
物理マシンの上で動作する仮想マシンは、それぞれ独立したOSであり、それぞれ任意のOSを選択することができます。仮想マシン上で動いているアプリケーションは別の仮想マシンの状態をまったく認識することができないため、高い独立性を実現できます。
このようにサーバを仮想化するのが、「ハイパーバイザ型」と「ホスト型」です。
ハイパーバイザ型(別名:Type1ハイパーバイザ)
ハイパーバイザ型は、別名「Type1ハイパーバイザ」とも言い、「ネイティブ」あるいは「ベアメタル」と表現されることもあります。
長所 | ハイパーバイザにより、ハードウェアアクセスのオーバーヘッドが最小限になるため、実行効率に優れている |
短所 | Type2と比較して導入や管理の難易度が高い |
https://member.eureka-box.com/products/4/categories/2147775733/posts/2148510536
ハードウェアの上で、Linuxや、その他のUnix系のOS、Windows Serverなど、通常のOSをハイパーバイザ専用として動作させて、その上にゲストOSを入れて使用します。ゲストOSには任意のOSを使用でき、WindowsでもUbuntuやCentOSでも構いません。ハイパーバイザ上でもアプリケーションを動かすことはできるのですが、そのアプリケーションに何か問題が起きて、たとえばリブートが必要になるなどの状況が生じると全ゲストOSをリブートさせることになるので、通常ハイパーバイザでは一般のアプリケーションは動かしません。
Type1ハイパーバイザには以下のものがあります。
- Xen
- KVM
- Hyper-V
- BHyVe
- VMWare ESX, ESXi, vSphere
ホスト型(別名:Type2ハイパーバイザ)
ホスト型は、別名「Type2ハイパーバイザ」と言います。
長所 | 既存OS上に構築するため簡単に導入できる |
短所 | ゲストOSによるハードウェアアクセスのオーバーヘッドがType1と比べて大きくなる |
サンドボックス用に仮想マシンを手軽に用意したい場合などに使われます。たとえば普段はWindowsを使っているが、Linuxで開発を行う必要があるといった場合に、Windows上でLinuxを動作させるためによく使う方法です。
https://member.eureka-box.com/products/4/categories/2147775733/posts/2148510536
Type1と大きく違うのが、図の左端、ホストOSの上で直接アプリが動く点です。ゲストOSというのはホストOSから見ると一つのプロセスなので、仮にこの左端のアプリが致命的なセキュリティホールを持っていると、ホストOSを経由して、他のゲストOSに「いたずら」することが可能になります。最近は仮想ハードウェア支援により、侵入は困難になってきていますが、仕組みとしては同じプロセスなので、Type1に比べるとセキュリティ的な分離性という意味で弱くなります。
ただ、別のOS環境をVirtualBoxで用意するといったことが簡単にできるので、サンドボックスとして使用するケースはよくありますし、本格的なサーバとして運用しないのであれば特に問題はないかと思います。
Type2ハイパーバイザには以下のものがあります。
- QEMU(ユーザエミュレーション)
Linuxユーザランドの仮想化(ホストOSと同じアーキテクチャで動くアプリケーション用) - QEMU(システムエミュレーション)
ホストと異なるアーキテクチャのエミュレーション - VirtualBox
デスクトップでGUI操作など - VMWare Server, Workstation, Player, Fusion
- Virtual PC
コンテナ型
さて、前置きが長くなりましたが、いよいよコンテナ型です。コンテナ型にもいろいろと種類があるのですが、現状ではほぼ「コンテナ型=Docker」だと思ってよいでしょう。
次のような長所があります。
- ハイパーバイザ型、ホスト型との組み合わせが可能
- マイクロサービス化によりサービス同士を隔離できる
- 全開発者、CI、プロダクションそれぞれの環境で容易に同じ実行環境を実現できる
ハイパーバイザ型やホスト型は、任意のOSを使用できて便利なのですが、使用リソースが大きく、CPUやメモリやストレージといったマシンリソースが圧迫されるという欠点がありました。また、OSのインストールや管理も負担になります。
これらの問題が、Dockerですべて解決できます。
Dockerを使う事で、アプリケーション分離をこれまでより軽量、手軽にでき、しかも分離性もかなり高くなっているため、あるコンテナでroot権限を持つ侵入を許しても他のコンテナは安全に保たれるなど、セキュリティが強固になります。また、コンテナの配布・実行が非常に楽なので、簡単に環境を揃えられます。
コンテナ型の構成は次のようになっています。
https://member.eureka-box.com/products/4/categories/2147775733/posts/2148510536
ホストOSとコンテナエンジンの部分がハイパーバイザに該当するという意味でハイパーバイザ型と似ていて、コンテナエンジンがホストOS上のプロセスであるという意味ホスト型と似ています。
コンテナ型は、仮想化のレベルの階層が違うので、ホスト型やハイパーバイザ型の上に構築することも可能ですし、物理マシンの上に直接コンテナ型を構築することも可能です。全く考え方が違う仕組みになっています。
3. これからのDockerに求められる技術を知るには
Dockerの技術を実際に学んでみたいという方に、まずは無料でお試しいただけるオンライン学習プラットフォームを準備しています。
業務が多忙なエンジニアでも、スキマ時間で効率的に実践的な学習が出来るEureka Boxは、エンジニアの現場の声から生まれたツールです。
ソフトウェア開発を改善するための開発技術を“知り・学び”“実践する”
超実践的オンライン学習プラットフォーム
Eureka Box(ユーリカボックス)
Dockerを正しく理解した上で適用し、最大限の効果を得られるようスキルアップしたい方にもEureka Boxでの学習はお勧めで、無料会員登録だけでも以下の特典が受けられます。
- 各連載コラムの全容、未公開コラムも一気にまとめて読める(一部動画解説付!)
- USDM(要求記述)、MBD(モデルベース開発)、システムズエンジニアリング、AWS Greengrass(新世代エッジエンジニアのための技術講座)など、ソフトウェア開発に関わる知識がギュッと凝縮、困った時のお助けアイテムとしても長期で活用出来る
- ソフトウェア開発に関わる無料お試しコンテンツも充実
デジタル人材が不足している今の時代、特にソフトウェア開発の現場では「上流技術」のスキルを持つ人が必要とされています。
そのスキルが効率よく身につくように設計されたのが「オンライン学習のEureka Box(ユーリカボックス)」
Eureka Boxの運営企業であるエクスモーションは、日本を代表する大手自動車メーカー、医療機器メーカー等、ソフトウェア開発の支援を実際に行っている企業だからこそ、
社会で実践出来るレベルまでサポートされた学習ツールが実現しました。
「Eureka Box(ユーリカボックス)」を是非ご活用ください。
今回はDockerと、コンテナ型を含むさまざまな仮想化の種類について、概要を紹介しました。次回はいよいよDockerの具体的な詳細に入っていきます。
Dockerの技術を習得されたい方、ご質問事項は、エクスモーションへお気軽にお問い合わせください。
執筆者プロフィール
株式会社エクスモーション シニアエキスパート
専門分野:
DevOps(CI/CD)、クラウドコンピューティング、Quick Hack(Quick Fix), Agile、ロボティクス、ネットワーク、防衛システム