はじめまして。4月で入社4年目になります「トッキー」です。はじめてのブ
はじめまして。4月で入社4年目になります「トッキー」です。
はじめてのブログは技術ブログを書こうと思います。
近年のマイクロサービス化のはやりから需要が爆増している、「コンテナとDocker」をご紹介できればと思います。
はじめに
コンテナとは仮想化技術の一つです。
従来の仮想化技術として、仮想マシンが広く普及していましたが以下のような課題がありました。
- 仮想マシンごとにOSを起動するため、サービス開始までに時間がかかる
- 仮想マシンごとにOSをインストールするため、OSが利用するリソース(CPU,メモリなど)消費量が多い
- 複製やバックアップに使用するイメージサイズが大きいため、バックアップに必要なディスク容量が大きい
以上のような課題を解決するために、コンテナ型仮想化(以降コンテナと呼ぶ)が開発されました。
コンテナを用いることで、
- 高速な起動
- リソース消費の効率化
- 軽量なパッケージングによる可搬性
などを実現することができます。
コンテナとは
コンテナとはアプリケーションとその実行に必要な全てをパッケージングしたものです。
コンテナの特徴として以下が挙げられます。
- コンテナは、コンテナエンジンと呼ばれる実行環境上で動作する
- ゲストOSを必要としないため、起動が速い
- 各コンテナはホストOSのカーネルを共有する
- コンテナ間でお互いのプロセスを参照することができない
- 基本的に1つのコンテナで1つのサービスを動作させる

仮想マシンと比べて、コンテナは以下のような違いがあります。
- コンテナはゲストOSを必要としないため、仮想マシンと比べて起動が速い
- コンテナはゲストOSを必要としないため、仮想マシンと比べてリソース消費が少ない
- コンテナはサイズが小さく複製が容易なことから可搬性が高いため、同様な環境を素早く構築することができる

近年、小さなサービスを組み合わせて大きなアプリケーションを構築するマイクロサービス化がトレンドであり、小さなサービスを構成する仕組みとして、コンテナが注目されています。
また、一貫した環境を高速に動作させる特性から、開発から運用までを密接に連携させるDevOpsと相性がいいことも、コンテナが注目される一つの理由です。
コンテナを実現する技術として、2013年にDocker社から「Docker」が誕生しました。
Dockerは近年のコンテナを実現する技術として、最もメジャーな技術として知られています。
Dockerとは
Dockerは、コンテナを場所を問わずに構築、移動、実行できるプラットフォームです。

「Docker Engine」はデーモンプロセス(dockerd)で、Docker APIリクエストを受け付け、イメージやコンテナなどのDockerオブジェクトを管理します。コンテナ型仮想化におけるコンテナエンジンの役割を持ちます。
コンテナはDockerイメージから作成され、レジストリにDockerイメージを格納し保管します。レジストリとして「Docker Hub」と呼ばれるWebシステムがあり、公開レジストリから様々なDockerイメージを取得したり、プライベートレジストを作成し、プロジェクトで作成したDockerイメージを保管・管理し運用することができます。
この「共有できるレジストリ」があるおかげで、複数人が同じコンテナを動作させたり、どこでも同じコンテナを動作させる仕組みを実現することができます。
Dockerイメージ
「Dockerとは」でコンテナはDockerイメージから作成されると記述しましたが、コンテナはDockerイメージに基づいて起動される実際のインスタンスです。
Dockerイメージは設計図(テンプレート)のようなもので、複数の読み取り専用のレイヤで構成されています。読み取り専用のレイヤで構成されるテンプレートのような仕組みのおかげで、効率的かつ再現可能なコンテナの生成を可能としています。
DockerイメージはDockerfileと呼ばれるファイルから作られます。

Dockerfile
DockerfileはDockerイメージを作成するためのテキストファイルです。
Dockerfileをビルドすることで、Dockerイメージが作られます。
Dockerイメージは複数のレイヤで構成されていると記述しましたが、Dockerfileに記述した1行がDockerイメージの1レイヤとなります。
レイヤとは前のレイヤからの変更差分です。つまりDockerイメージは変更差分(レイヤ)の集合体であると言えます。

Dockerイメージを作る際はベースとなるDockerイメージを決めます。
例えばJavaアプリケーションをサービスとして動作させたい場合はTomcatのDockerイメージをベースイメージとして選択します。(FROMで宣言)
Dockerfileからコンテナを起動する流れ
それでは実際にDockerfileからコンテナを起動する流れを説明していきます。
例として、「unalus.war」というJavaアプリケーションがTomcatにデプロイされているコンテナで説明します。
①適当なディレクトリを作り、ファイル「Dockerfile」を作成します。
このとき、ディレクトリに「unalus.war」も一緒に格納してあげましょう。
Dockerfileの中身は以下のようにします。
# ベースイメージを指定
FROM Tomcat:latest
# サンプルアプリを配置
COPY unalus.war /uar/local/tomcat
# コンテナ起動時のコマンドを指定
CMD ["catalina","run"]
②ファイル「Dockerfile」のあるディレクトリに移動し、Dockerfileをビルドしてコンテナイメージを作成します。
ビルドには「Dockerコマンド」の「buildサブコマンド」を使用します。
docker build -t unalus .
この時、指定されたパスの「Dockerfile」と名の付くファイルをデフォルトで探します。そのためファイル名を「Dockerfile」としましたが、ファイル指定のオプションを使用することで、任意のファイル名にすることが可能です。
③作成されたコンテナイメージを確認しましょう。
作成されたコンテナイメージを確認するには「dockerコマンド」の「imagesサブコマンド」を使用します。
docker images
④コンテナイメージからコンテナを起動しましょう。
コンテナイメージからコンテナを起動するには、「dockerコマンド」の「runサブコマンド」を使用します。
docker run -p 8080:8080 unalus
この時、オプション「-p」でポートフォワーディングを設定しています。コンテナにアクセスする際にはホストマシンを経由してコンテナにアクセスすることになります。
ホストマシンのポート8080にアクセスが来た場合には、コンテナのポート8080にパス(フォワード)してあげることでコンテナのサービスを動かすことができます。

⑤コンテナの起動を確認しましょう。
コンテナの起動を確認するには「dockerコマンド」の「psサブコマンド」を使用します。
docker ps
STATUSに「up」と表示されていれば起動しています。
コンテナ停止からDockerイメージを削除するまでの流れ
次に起動中のコンテナを停止し、Dockerイメージを削除するまでの流れを説明します。
①コンテナを停止しましょう。
コンテナを停止するには、「dockerコマンド」の「stopサブコマンド」を使用します。
docker stop <コンテナID or コンテナ名>
②コンテナの停止を確認しましょう。
コンテナの停止を確認するには、「dockerコマンド」の「psサブコマンド」に「-aオプション」を使用します。
docker ps -a
「docker ps」はオプションなしの場合、起動中のコンテナしか表示してくれないので注意しましょう。
STATUSに「Exited」と表示されていれば停止しています。
③コンテナを削除しましょう。
コンテナを削除するには「dockerコマンド」の「rmサブコマンド」を使用します。
docker rm <コンテナID or コンテナ名>
「docker ps -a」コマンドを使用して対象のコンテナが表示されていなければ、削除されています。
コンテナ起動中に削除しようとしても、エラーになるため、コンテナを停止してから削除することを覚えておきましょう。
④Dockerイメージを削除する。
Dockerイメージを削除するには、「dockerコマンド」の「rmiサブコマンド」を使用します。
docker rmi <DockerイメージID or Dockerイメージ名>
「docker images」コマンドを使用して、対象のDockerイメージが表示されていなければ削除されています。
対象のDockerイメージを使用したコンテナが起動中・停止中を問わず存在する場合は、Dockerイメージを削除しようとしてもエラーになるため、コンテナを削除してからDockerイメージを削除することを覚えておきましょう。
おわり
以上がコンテナとDockerの概要と、主要なコマンドでした。
今回の内容は弊社の若手社員に与えられる課題のLinuC Level1にも出題される内容も含まれます。
ぜひこれを機会に勉強してみて、わからないことは調べてみてください!