【コンテナ】Dockerの概要と使い方(基本操作)の紹介

こんにちは、Aireです。

今回はコンテナ仮想化技術の1つである「Docker」について紹介します。

はじめにDockerの概要を説明し、その後、Dockerの使い方として、Dockerのインストール方法や実運用で必要なコマンドと具体的な使い方を説明します。

目次

Dockerとは

Dockerとは、コンテナ仮想化技術を用いてアプリケーションを迅速に構築・デプロイ・実行するためのプラットフォームです。Docker社が開発したものであり、現在ではオープンソースソフトウェア(OSS)として公開されています。

以下に、従来のサーバ仮想化とコンテナ仮想化のイメージ図を記載します。サーバ仮想化の場合はハイパーバイザ上に仮想マシンを作成し、その上にアプリケーションを構築することになりますが、コンテナ仮想化の場合はホストOS上にDocker Engineを載せて、その上でコンテナと呼ばれる空の入れ物のようなもの(厳密には空ではない)を動作させ、その中にアプリケーションを構築します。

以下、コンテナ仮想化の基本的なメリット・デメリットを記載します。

コンテナ仮想化のメリット
コンテナ仮想化のデメリット
  • アプリケーションの迅速な構築・デプロイ・実行が可能
  • 単一のOSを使用するため、処理が軽量であり、システムの負荷を抑えられる
  • サーバ仮想化に比べて比較的新しい技術であり、学習難易度が高い
  • コンテナは基本的にLinux OS上で動作するものであり、コンテナの中に入れるのもLinux用のソフトウェアのみ

Dockerをインストールする

ここでは、Dockerの使い方に入る前に、Dockerのインストール方法を紹介します。

Dockerのインストール方法はいくつかありますが、Dockerのインストール先となるホストOSごとに方法が異なります。

ホストOS インストール方法(手順や用件はリンク先を参照)
Linux OS コマンドラインでDockerをインストールする
Windows OS Docker Desktop for Windowsをインストールして使用する
仮想環境(VirtualBox等)を導入後、Linux OS(VM)を作成し、コマンドラインでDockerをインストールする
Docker Toolboxを使用してDockerをインストールする(非推奨)
macOS Docker Desktop for Macをインストールして使用する
仮想環境(VirtualBox等)を導入後、Linux OS(VM)を作成し、コマンドラインでDockerをインストールする
Docker Toolboxを使用してDockerをインストールする(非推奨)

Dockerを動かすためには、基本的にLinux OSが必要です。これは、DockerのコンポーネントであるDockerデーモンが、Linux固有のカーネル機能を使用するためです。

Linux OS上でDockerを動かす場合、Linux OSは既に用意されているので、Dockerのみをインストールします。

一方、Windows OSまたはmacOSの場合、例えば、Docker Desktop for Windows/Macを使用してDockerをインストールします。これはDockerに加えて、他に必要なものをまとめてパッケージ化したもので、ホストOS上に仮想環境を用意し、その上にLinux OS(ユーザからは見えない)を導入することで、Windows OSやmacOSでもDockerを動かすことが可能になります。

仮想環境について、Windows OSの場合はHyper-V(Windowsで予め用意されている)を使用し、macOSの場合はHyperKit(Docker社が公開したオープンソース)を使用します。

なお、Windows OSとmacOSの場合、Docker Toolboxと呼ばれるものを使用したインストール方法もありますが、こちらは旧式の方法で非推奨とされているようですので、Windows OSやmacOS上にDockerをインストールする場合は、Docker Desktop for Windows/Macを使用してください。

Dockerコンテナのライフサイクルと基本操作(作成・起動・停止・削除)

コンテナのライフサイクルとして、コンテナの「作成」→「起動」→「停止」→「削除」→「作成」……という一連の流れがあります。コンテナを使用中にソフトウェアのアップデートがリリースされた場合、コンテナ内のソフトウェアをアップデートして使い続けるのではなく、アップデートされたソフトウェアを含むイメージをベースに作り直すことが一般的です。

以降では、ライフサイクルの各ステップで使用するdockerの基本操作を紹介します。

コンテナの作成

コンテナのライフサイクルは、コンテナ用のイメージを基にコンテナを作成するところから始めます。

ここではApacheのイメージ「httpd」をオプションとして指定して「container run」コマンドを実行し、コンテナ「container4httpd」を作成します。

オプション項目オプションの説明
–name container4httpd作成するコンテナの名前「container4httpd」を指定する
-dコンテナをバックグラウンドで実行する
httpdコンテナのイメージ「httpd」を指定する

「container ls」コマンドを実行し、稼働中のコンテナを表示します。

「-a」オプションを追加し、全てのコンテナを表示します。

コンテナを作成する場合、イメージのダウンロード(image pull)、コンテナの作成(container create)、コンテナの起動(container start)が必要ですが、「container run」コマンドを使用すると、それらの操作を一括して実行することが可能です。

コンテナの停止

コンテナの運用開始後、ソフトウェアのアップデート等により不要になったコンテナは、一旦停止させてから削除します。

ここでは「container stop」コマンドを実行し、コンテナ「container4httpd」を停止します。

「container ls」コマンドを実行し、稼働中のコンテナを表示します。

「-a」オプションを追加し、全てのコンテナを表示します。

コンテナの起動

一旦停止させたコンテナを再度起動する場合、以下のように「container start」コマンドを使用します。

ここでは「container start」コマンドを実行し、コンテナ「container4httpd」を起動します。

「container ls」コマンドを実行し、稼働中のコンテナを表示します。

「-a」オプションを追加し、全てのコンテナを表示します。

コンテナの削除

不要になったコンテナを削除する場合、「container rm」コマンドを使用します。

ここでは「container rm」コマンドを実行し、コンテナ「container4httpd」を削除します。

「container ls」コマンドを実行し、稼働中のコンテナを表示します。

「-a」オプションを追加し、全てのコンテナを表示します。

コンテナを削除する場合、「container stop」コマンドでコンテナを停止しておく必要があります。

イメージの削除

コンテナを削除したら、ベースとなったイメージは基本的に不要であるため、ディスクの空き容量を圧迫しないよう併せて削除していくことが望ましいです。

ここでは「image rm」コマンドを実行し、コンテナのイメージ「httpd」を削除します。

「image ls」コマンドを実行し、コンテナのイメージを削除したことを確認します。

コンテナのイメージを削除する場合、そのイメージを基に作成したコンテナが消去されている必要があります。

Dockerコンテナの追加操作

前章では、コンテナのライフサイクルに対応した基本操作を紹介しましたが、実際の運用においては以下のような操作も発生します。

  • 外部からアクセスできるようにコンテナを作成する
  • ホスト-コンテナ間でファイルをコピーする
  • コンテナに記憶領域をマウントする
  • コンテナの記憶領域のバックアップを取得する
  • コンテナのイメージを作成する

本章では、前章と同じように「httpd」イメージを使用してApacheのコンテナを作成し、Dockerの運用に必要な追加の操作方法を紹介します。

外部からアクセスできるようにコンテナを作成する

前章で実行例として紹介した、「docker container run –name container4httpd -d httpd」コマンドによって作成したApacheコンテナには、外部からアクセスすることができません。ウェブブラウザに「http://localhost:8080/」と入力しても、localhostに接続できない旨のメッセージが表示されると思います。

外部からコンテナへアクセスできるようにするためには、コンテナを作成する際にホストのポートとコンテナのポートを対応付けるためのオプションを使用します。

ここでは前章と同様に「container run」コマンドを実行し、Apacheのコンテナ「container4httpd」を作成します。ただし、「-p」オプションを使用してポートの対応付けを行い、外部からコンテナにアクセスできるようにしています。

オプションの項目オプションの説明
–name container4httpd作成するコンテナの名前「container4httpd」を指定する
-dコンテナをバックグラウンドで実行する
-p 8080:80ホストのポート8080(未使用の任意のポート番号を指定可)とコンテナのポート80(指定する値は、コンテナのイメージのドキュメント等で確認)を対応付ける
httpdコンテナのイメージ「httpd」を指定する

上記コマンドで作成したコンテナが稼働していることを確認します。

ウェブブラウザに「http://localhost:8080/」と入力すると、Apacheの初期画面が表示されると思います。

コンテナのポート設定は基本的に、コンテナ作成時のみ可能であり、作成後に変更することはできません。

「-p」オプションの代わりに、ポート番号を指定しない「-P」オプションを使用することもできます。「-P」オプションを使用すると、ホストの未使用ポート(範囲:32768〜61000)がランダムにコンテナのポートと対応付けられます。

ホスト-コンテナ間でファイルをコピーする

コンテナを運用する上で、ホストからコンテナに直接ファイルを格納したいケースはたびたび出てくることになりますので、その方法も紹介しておきます。

ここでは「container cp」コマンドを実行し、ホストから前節で作成したApacheコンテナへ、適当に用意した「index.html」をコピーします。

オプションの項目オプションの説明
/Users/ユーザー名/Documents/index.htmlコピー元パス「/Users/ユーザー名/Documents/index.html」を指定する
container4httpd:/usr/local/apache2/htdocsコピー先のコンテナの名前「container4httpd」とコピー先パス「/usr/local/apache2/htdocs」を指定する

ウェブブラウザに「http://localhost:8080/」と入力すると、以下の例のようにApacheの画面が初期画面から変更されると思います。

コンテナからホストにファイルをコピーすることも可能です。以下では、「container cp」コマンドを実行し、Apacheコンテナからホストへ「index.html」をコピーします。

コンテナに記憶領域をマウントする

コンテナを運用する場合、実際のデータはコンテナ外部の記憶領域に格納して使用(データの永続化)することが一般的です。Dockerコンテナに記憶領域をマウントする方法は基本的に3種類あります。

  • ボリュームマウント…Docker Engineが管理する領域内にボリュームを作成し、コンテナにマウントする方法です。
  • バインドマウント…Dockerをインストールしたホストのディレクトリまたはファイルをコンテナにマウントする方法です。
  • メモリマウント…一時メモリ(tmpfs)をコンテナにマウントする方法です。他のマウント方法と比べて高性能ですが、Docker Engineやホストの停止・再起動によってデータは消えるため、非永続化データを扱う場合に使用します。

本記事では紹介しませんが、プラグインを使用するとiSCSI、NFS、FCのような共有ストレージをマウントすることも可能です。共有ストレージにアクセス可能なホストにプラグインをインストールすることで、コンテナがどのホスト上で動いてもその共有ストレージを使用可能です。

以下、ボリュームマウントとバインドマウントの具体的な手順を紹介します。

ボリュームマウント

はじめにDocker Engineの領域にボリュームを作成します。

ここでは「volume create」コマンドを実行し、ボリューム「volume4httpd」を作成します。

次に「container run」コマンドでコンテナを作成する際に「-v」オプションを追加して、ボリューム名とコンテナ内の記憶領域パス(ボリュームのマウント先)を指定します。

オプションの項目オプションの説明
–name container4httpd作成するコンテナの名前「container4httpd」を指定する
-dコンテナをバックグラウンドで実行する
-p 8080:80ホストのポート8080(未使用の任意のポート番号を指定可)とコンテナのポート80(指定する値は、コンテナのイメージのドキュメント等で確認)を対応付ける
-v volume4httpd:/usr/local/apache2/htdocsボリューム「volume4httpd」とボリュームのマウント先「/usr/local/apache2/htdocs」を対応付ける
httpdコンテナのイメージ「httpd」を指定する

「container inspect」コマンドを実行すると、以下のようにマウント状況を確認できます。

「volume inspect」コマンドを実行すると、ボリュームの詳細情報を確認することができます。

ボリュームマウントでは、「container run」コマンドの実行時にボリュームが存在しなければ、指定した名前のボリュームが自動的に作成されます。ただし、この方法は推奨されていないようなので、あらかじめボリュームを作成しておく方が良いです。

以下、参考ですが、ボリュームマウントが正しく行われているか確認してみます。

STEP
ボリュームにデータを格納する

ホストからApacheコンテナにマウントしたボリュームにファイルをコピーします。

以下のコマンドでは、ボリューム「volume4httpd」のマウント先「/usr/local/apache2/htdocs」にファイル「index.html」を格納しています。

STEP
Linuxコンテナを作成し、ボリュームをマウントする

別途Linuxコンテナを用意し、そのコンテナにボリュームをマウントします。

以下のコマンドでは、BusyBoxコンテナ「container4busybox」を作成し、ボリューム「volume4httpd」をコンテナ内のパス「/home」にマウントしています。

BusyBoxとは、UNIX系OSで使用される多数の標準コマンドを単一の実行ファイルに組み込んだソフトウェアのことです。Linux上で最小の実行ファイルとなるように設計されているので、Ubuntu等のLinuxディストリビューションを導入するよりも軽量で使いやすいです。

STEP
Linuxコンテナに入り、格納したデータを確認する

Step1でデータが格納できたか確認するため、Step2で用意したコンテナにアクセスし、Linuxコマンドを実行します。

以下のコマンドでは、BusyBoxコンテナ「container4busybox」の中でshを起動しています。

「container exec」コマンドは、コンテナの中でコマンドを実行するためのコマンドです。

lsコマンドを実行し、マウント先に指定したコンテナ内のパス「/home」の直下にファイル「index.html」があることを確認します。

バインドマウント

はじめにホスト(ローカル端末等)上でディレクトリまたはファイルを作成します。

ここでは「Users/ユーザー名/Documents/docker_directory」というディレクトリを用意しておきます。

次に「container run」コマンドでコンテナを作成する際に「-v」オプションを追加して、ディレクトリとコンテナ内の記憶領域パス(ディレクトリのマウント先)を指定します。

オプションの項目オプションの説明
–name container4httpd作成するコンテナの名前「container4httpd」を指定する
-dコンテナをバックグラウンドで実行する
-p 8080:80ホストのポート8080(未使用の任意のポート番号を指定可)とコンテナのポート80(指定する値は、コンテナのイメージのドキュメント等で確認)を対応付ける
-v /Users/ユーザー名/Documents/docker_directory:/usr/local/apache2/htdocsディレクトリ「/Users/ユーザー名/Documents/docker_directory」とディレクトリのマウント先「/usr/local/apache2/htdocs」を対応付ける
httpdコンテナのイメージ「httpd」を指定する

「container inspect」コマンドを実行すると、以下のようにマウント状況を確認できます。

コンテナの記憶領域のバックアップを取得する

コンテナを運用する上で、障害等に備えてデータのバックアップを取得することは必要です。また、バックアップ方法は以下のケース(データの格納先)ごとに異なります。

  • コンテナ内にデータが格納されているケース
  • コンテナ外部の記憶領域にデータが格納されているケース(記憶領域のマウント方法は前節を参照)

コンテナ内にデータが格納されているケース

コンテナ内にデータが格納されている場合、以下の手順でコンテナ自身のバックアップを行います。

STEP
コンテナをイメージに変換する

「container commit」コマンドを実行し、コンテナ「container4httpd」をイメージ「httpd4aire」に変換します。

STEP
イメージをアーカイブとして保存する

「image save」コマンドを実行し、ホスト上のディレクトリにイメージ「httpd4aire」をアーカイブとして保存します。

ここではイメージをローカルに保存していますが、Docker Hubレジストリに保存することも可能です。その場合は「image push」コマンドを使用します。詳細はdocker docsを参照してください。

アーカイブからイメージをリストアしてコンテナを作成する場合、以下の手順でリストアを行います。

STEP
コンテナをイメージに変換する

「image load」コマンドを実行し、アーカイブ「httpd4aire.tar」からイメージ「httpd4aire」をリストアします。

Docker Hubレジストリからイメージをリストアする場合は「image pull」コマンドを使用します。詳細はdocker docsを参照してください。

コンテナ外部の記憶領域にデータが格納されているケース

前節で紹介した記憶領域のマウント方法のうち、バインドマウントの場合は、マウントしているホスト上のディレクトリ/ファイルを直接コピーすれば良いですが、ボリュームマウントの場合は、コンテナ経由でのみディレクトリ/ファイルにアクセスできるため、以下のような手順でバックアップを行います。

STEP
バックアップ対象のボリュームを持つコンテナを停止する

バックアップ対象のコンテナは停止させなくてもバックアップ作業を行うことは可能です。ただし、ファイルが静止化されていない(=ファイルが更新中)状態でバックアップが取得される可能性があるため、確実に静止化されたデータをバックアップするためにはコンテナを停止しておくと良いでしょう。

STEP
新規コンテナを作成し、バックアップを取得する

コンテナの作成とバックアップファイルの圧縮・保存を行います。

以下のコマンドでは、バックアップ用にBusyBoxコンテナ「container4backup」を作成しています。その際、バックアップ対象ボリュームのマウント(ボリュームマウント)と、バックアップ先となるホストのパスのマウント(バインドマウント)を行っています。続けて「tar」コマンドを実行し、マウントしたバックアップ対象ボリューム内のディレクトリやファイルを、バインドマウントで指定したバックアップ先に圧縮・保存しています。

オプションの項目オプションの説明
–rmコンテナ終了時にコンテナを自動的に削除する
–name container4backup作成するコンテナの名前「container4backup」を指定する
-v volume4httpd:/backup_sourceボリューム「volume4httpd」とボリュームのマウント先「/backup_source」を対応付ける
-v /Users/ユーザー名/Documents/docker_directory:/backup_destinationディレクトリ「/Users/ユーザー名/Documents/docker_directory」とディレクトリのマウント先「/backup_destination」を対応付ける
busyboxコンテナのイメージ「busybox」を指定する
tartarコマンドを実行する
czvf新規アーカイブを作成し、gzip形式で圧縮する
/backup_destination/backup_data.tar.gz圧縮ファイルのパス・名前「/backup_destination/backup_data.tar.gz」を指定する
-C /backup_source .バックアップ対象ボリュームのマウント先ディレクトリ「/backup_source」以下を全てアーカイブする(最後の「.」の代わりに「index.html」とすると、「index.html」のみアーカイブされる)

上記の実行方法とは別に、「container run」コマンドの「–volumes-from」オプションを使用して以下のように実行することも可能です。「–volumes-from」オプションを使用すると、ボリューム名を指定する必要がなく、コンテナのボリュームが複数ある場合に一括してマウントすることが可能です。

オプションの項目オプションの説明
–rmコンテナ終了時にコンテナを自動的に削除する
–name container4backup作成するコンテナの名前「container4backup」を指定する
–volumes-from container4httpdコンテナ「container4httpd」のボリュームをマウントする。ボリュームのマウント先は、本オプションで指定したコンテナ内でのボリュームのマウント先と同じ
-v /Users/ユーザー名/Documents/docker_directory:/backup_destinationディレクトリ「/Users/ユーザー名/Documents/docker_directory」とディレクトリのマウント先「/backup_destination」を対応付ける
busyboxコンテナのイメージ「busybox」を指定する
tartarコマンドを実行する
czvf新規アーカイブを作成し、gzip形式で圧縮する
/backup_destination/backup_data.tar.gz圧縮ファイルのパス・名前「/backup_destination/backup_data.tar.gz」を指定する
-C /usr/local/apache2/htdocs .バックアップ対象ボリュームのマウント先ディレクトリ「/usr/local/apache2/htdocs」以下を全てアーカイブする(最後の「.」の代わりに「index.html」とすると、「index.html」のみアーカイブされる)

ここまでのバックアップ方法は愚直にtarコマンドを実行するものでしたが、それ以外に「boombatower/docker-backup」ツール(実体はシェルスクリプト)を使用する方法もあります。本ツールは、公式のDocker Hubに移動して「boombatower/docker-backup」と検索すると見つけられます。

使い方は簡単で、「–volumes-from」オプションでバックアップ対象のボリュームを持つコンテナを指定して、「container run」コマンドを実行するだけです。ボリューム情報はこちらで指定する必要がなく、ツールが自動で取得してくれます。以下に実行例を記載します。実行すると、アーカイブ「backup.tar.xz」が指定の場所に作成されます。

オプションの項目オプションの説明
–rmコンテナ終了時にコンテナを自動的に削除する
–volumes-from container4httpdコンテナ「container4httpd」のボリュームをマウントする
-v /Users/ユーザー名/Documents/docker_directory:/backupディレクトリ「/Users/ユーザー名/Documents/docker_directory」とディレクトリのマウント先「/backup」を対応付ける
boombatower/docker-backupコンテナのイメージ「boombatower/docker-backup」を指定する
backupコンテナ作成時にコマンド「backup」を起動する

ボリューム内のディレクトリ/ファイルをリストアする場合は、以下の手順でリストアを行います。

STEP
アーカイブ内のディレクトリ/ファイルをバックアップ対象のボリューム内にリストアする

ここでは、バックアップ対象ボリュームを改めてマウントし、ボリューム内にバックアップデータを書き込みます。

バックアップデータ(ここまでの例の場合、コンテナ「container4httpd」の「/usr/local/apache2/htdocs」配下にあるディレクトリ/ファイル)に差分がある場合、対象データは上書きされるので注意してください。(新規にコンテナを作成し、そちらにリストアしても良いです)

以下の実行例では、「container run」コマンドを実行してバックアップ対象ボリュームをマウントし、アーカイブ「backup.tar.xz」内のバックアップデータを「/usr/local/apache2/htdocs」配下にリストアします。

コンテナのイメージを作成する

コンテナのイメージを作成する方法は2つあります。オリジナルのコンテナを使用・複製したい場合に必要です。

  1. 既存のコンテナをイメージに変換する…既存のコンテナを複製したり、別の場所に移動して起動したいといった場面で使われます。具体的な手順は、前節「コンテナの記憶領域のバックアップを取得する」の「コンテナ内にデータが格納されているケース」で紹介した方法と同じです。
  2. Dockerfileでイメージを作成する…「Dockerfile」という名前のイメージ定義ファイルを用意して、その中に元となるイメージや追加コマンドを記載し、それをビルドすることでオリジナルのイメージを作成します。

以下、2つ目の方法「Dockerfileでイメージを作成する」について紹介します。ここでは「ホスト-コンテナ間でファイルをコピーする」で使用した「index.html」をApacheコンテナのイメージ「httpd」に追加したオリジナルのイメージ「httpd4aire」を作成してみます。

STEP
Dockerfileを作成する

Dockerfileという名前のファイル(拡張子なし)を作成し、以下の内容を記載します。

Dockerfileコマンドの項目Dockerfileコマンドの説明
FROM httpd元にするイメージとして「httpd」を指定する
COPY index.html /usr/local/apache2/htdocs/ファイル「index.html」をイメージ内の「usr/local/apache2/htdocs/」に追加する

一点、コピーするファイル(上記の例では「index.html」)のパスはDockerfileの格納先から見た相対パスで指定してください。上記の例ではDockerfileとindex.htmlは同じ場所に格納しています。(筆者は絶対パスで指定してビルドしようとしたのですが、Step2で以下のようなエラーが発生してしまいしばらくハマってしまいました)

STEP
イメージを作成する

「build」コマンドを実行して、オリジナルイメージ「httpd4aire」を作成します。

オプションの項目オプションの説明
-t httpd4aireオリジナルイメージの名前を「httpd4aire」に指定する
/Users/ユーザー名/DownloadsDockerfileが格納されているパス「Users/ユーザー名/Downloads」を指定する

「image list」コマンドを実行し、オリジナルイメージが作成されたか確認します。

以上、ここまで。

この記事を書いた人

目次