•  

コラム

  1. TOP
  2. コラム
  3. コラム
  4. Dockerとは?連載第1回入門編。概要や仕組みを簡単に説明。

Dockerとは?連載第1回入門編。概要や仕組みを簡単に説明。

  • LINEで送る
  • このエントリーをはてなブックマークに追加
Dockerとは?連載第1回入門編。概要や仕組みを簡単に説明。

第1回 Docker解説 コラム

この連載コラムでは、仮想化技術のDockerとは?について、数回に分けてお伝えします。

はじめは入門編として、概要や簡単な仕組みを説明します。最後は実践編として、実際のコマンドの動かし方を紹介します。

本連載は、次のような想定・目的で記述しています。

想定する読者
  • Dockerの特徴を知りたい人
想定する読者の
知識レベル
  • 仮想化技術について用語レベルの知識がある人
  • プログラム開発環境、実行環境について知識がある人
本連載を読んだ後に得られる期待値
  • 以下の問いに答えられるようになる
    • 他の仮想化技術ではだめなんですか?(Dockerを使う理由は?)
    • Dockerの特徴について簡単に教えて
    • Dockerについて自力で調査できるようになる

 



1. Dockerとは

コンテナとは

最初に、簡単にコンテナについて説明しておきましょう。

よく目にするものでは、貨物コンテナをご存じだと思います。船に積まれていたり、道路でトレーラーに引っ張られていたりする箱ですね。あれは、運搬を効率化するためにブロックとして扱えるようにしたものです。規格化したパッケージとして取り扱い、中に何が入ってるかは気にしなくていいようになっています。それをソフトウェアに応用したもの、中に何が詰まってるかを気にしなくていいようにしたものが、ここで言うコンテナです。

コンテナとは、開発、出荷、および展開を行うために、
ソフトウェアを標準化されたユニットにパッケージ化したものである
Dockerがコンテナエンジンである
図出典:https://www.docker.com/resources/what-container, (参照 2021-03-25)

構成は、オペレーティングシステムの上に、コンテナエンジンが介在し、その上で各アプリケーションが動く、という形です。この図はDockerのものですが、Dockerがコンテナエンジンであり、その上のApp AやApp Bといったアプリケーションが、たとえばJavaの実行環境やDBなどに相当します。



Dockerのコンセプト

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で実行する例を見てみましょう。

hello_docker.py
import sys

print
print("Hello!! Everybody in eXmotion.")
print("python's version is")
print(sys.version)
print

コマンドに指定するDockerイメージの名前を変えるだけで、これをPython 2.7.8と最新版のPythonで実行することができます。通常、Dockerからはホストのファイルは見えないのですが、「-v "$PWD":/usr/src/myapp」の部分でコンテナから同じファイルを見えるようにすることで、両コマンドで同じスクリプトを実行させています。

Python 2.7.8

[コマンド]
$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7.8-slim python hello_docker.py
[実行結果]
Hello!! Everybody in eXmotion.
python's version is
2.7.8 (default, Dec 3 2014, 02:28:14)
[GCC 4.9.1]

最新Python(3.8.5)

[コマンド]
$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:slim python hello_docker.py
[実行結果]
Hello!! Everybody in eXmotion..
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

[コマンド]
$ docker run -it --rm -v “$PWD”:/usr/src/myapp -w /usr/src/myapp gcc:4.9 gcc --version; gcc -o hello hello.c; ./hello
[実行結果]
gcc (GCC) 4.9.4
 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)

[コマンド]
$ docker run -it --rm -v “$PWD”:/usr/src/myapp -w /usr/src/myapp gcc gcc --version; gcc -o hello hello.c; ./hello
[実行結果]
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と比較して導入や管理の難易度が高い
ハイパーバイザ型(別名:Type1ハイパーバイザ)
※引用 EurekaBox(ユー リカボックス)最新技術【体験版】Docker 連載第1回 https://www.eureka-box.com/media/column/a27#link05

ハードウェアの上で、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を動作させるためによく使う方法です。

ホスト型(別名:Type2ハイパーバイザ)
※引用 EurekaBox(ユー リカボックス)最新技術【体験版】Docker 連載第1回 https://www.eureka-box.com/media/column/a27#link05

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権限を持つ侵入を許しても他のコンテナは安全に保たれるなど、セキュリティが強固になります。また、コンテナの配布・実行が非常に楽なので、簡単に環境を揃えられます。

コンテナ型の構成は次のようになっています。

Docker(コンテナ型)

ホストOSとコンテナエンジンの部分がハイパーバイザに該当するという意味でハイパーバイザ型と似ていて、コンテナエンジンがホストOS上のプロセスであるという意味ホスト型と似ています。

コンテナ型は、仮想化のレベルの階層が違うので、ホスト型やハイパーバイザ型の上に構築することも可能ですし、物理マシンの上に直接コンテナ型を構築することも可能です。全く考え方が違う仕組みになっています。



3. Dockerを使ってみる

Dockerの技術を実際に学んでみたいという方に、まずは無料でお試しいただけるオンライン学習プラットフォームを準備しています。

業務が多忙なエンジニアでも、スキマ時間で効率的に実践的な学習が出来るEureka Boxは、エンジニアの現場の声から生まれたツールです。

ソフトウェア開発を改善するための開発技術を“知り・学び”“実践する”
超実践的オンライン学習プラットフォーム
Eureka Box(ユーリカボックス)
超実践的オンライン学習プラットフォームlink


ご不明点・ご相談ごとがあれば
お気軽にご連絡ください

ソフトウエア開発オンライン学習Eureka Box


今回はDockerと、コンテナ型を含むさまざまな仮想化の種類について、概要を紹介しました。次回はいよいよDockerの具体的な詳細に入っていきます。

Dockerの技術を習得されたい方、ご質問事項は、エクスモーションへお気軽にお問い合わせください。

株式会社エクスモーション シニアエキスパート 野沢 利明

執筆者プロフィール

株式会社エクスモーション シニアエキスパート

野沢 利明

 

専門分野:

DevOps(CI/CD)、クラウドコンピューティング、Quick Hack(Quick Fix), Agile、ロボティクス、ネットワーク、防衛システム

  • LINEで送る
  • このエントリーをはてなブックマークに追加