Dockerの概要と特徴について調べてみたので、学習メモを残す




# はじめに

はじめまして。

最近、[Dockerをまともに使えないエンジニアはかなり遅れている](https://qiita.com/poly_soft/items/fb649573c19b7a5c0227 '2018年の最先端バックエンドエンジニアに必要なスキルについて考えてみました。')という旨の記事を見ました。
私は約2年ほど前にDockerの存在を知り、何となく触った事はあるのですが、「Dockerは凄い」ということはなんとなく知っていても、何がそんなに凄いのかを理解していませんでした。

そのため、Dockerについて調べて、概要と何が凄いのかをまとめました。
その際の学習メモを共有させて頂きます。

Dockerについて引用している書籍は以下です。
とても良い本ですので、一度手にとって見ることをオススメします。

[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/dp/B07GP1Q3VT/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1 "Docker/Kubernetes 実践コンテナ開発入門")

その他、Dockerに関する記事は以下ですので、こちらもご参照頂けるとありがたいです。

[Dockerイメージの操作に関するコマンドをまとめてみた](https://qiita.com/ya6maDev/items/f216cd1052fa1a02e672 'Dockerイメージの操作に関するコマンドをまとめてみた')
[Dockerコンテナの操作に関するコマンドをまとめてみた](https://qiita.com/ya6maDev/items/9f163fbc32ef8477b99d 'Dockerコンテナの操作に関するコマンドをまとめてみた')

# Dockerの概要

Dockerとは以下、2つから成るプロダクトです。

* コンテナ型仮想化技術を実現するために実行される常駐アプリケーション。
* 上記を操作するためのコマンドフロントインターフェース。

**アプリケーションのデプロイに特化しており、コンテナを中心とした開発・運用を可能にする。コンテナ型仮想化技術によってコンテナを軽量に作成、利用、破棄できる**ことが特徴です。

**「コンテナ型仮想化技術」**とは、仮想化ソフトウェアを使わずにOSのリソースを隔離し、仮想OSにする技術のこと。この仮想OSをコンテナと呼びます。コンテナを作り出すためのオーバーヘッドは、他の仮想化ソフトウェアと比較して少ないです。高速に起動・終了でき、必要なマシンリソースも少なくて済みます。

# Dockerの何が凄いのか

[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/dp/B07GP1Q3VT/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1 "Docker/Kubernetes 実践コンテナ開発入門")では、Dockerを利用する意義は以下にあると仰っています。

1. 不変な実行環境による冪等性の確保
1. 実行環境構築とアプリケーション構成のコード化
1. 実行環境とアプリケーションの一体化によるポータビリティ性の向上
1. システムを構成するアプリケーションやミドルウェアの構成管理の容易さ

## 環境差異問題からの脱却
開発環境でテストOKだったため、いざ本番環境にデプロイしてみると環境差異のため、期待通りの動作をしないことがあります。
または同じ手順で開発環境を作成したのに、自分だけ、アプリが動かないなんてこともあります。

これは**「可変的なインフラ（MutableInfrastructure）を許容していること」**で発生する問題です。
環境差異の問題を避けるには、**「いつ、何度実行しても同じ結果が保証される冪等性を保つこと」**が重要になります。

そのためには以下の考え方が必要となり、Dockerはこれを実現するのを容易にします。

* 「InfrastructureasCode（インフラの構成管理）」
* 「ImmutableInfrastructure（不変なインフラ）」


### InfrastructureasCode

**「InfrastructureasCode」はコードベースでインフラ構築を定義する考え方**です。

どのようなサーバの構成にするか、インストールするライブラリ、ツール等は何かをコードベースで定義します。
手作業が介する余地を減らし、コード中心にすることで、複数の同じ構成のサーバを再現しやすくなります。
Dockerでは「Dockerfile」によって、インフラの構成管理を実現します。

現場で開発環境構築マニュアルなるものを開発メンバーみんなに配布して、手作業で環境構築みたいな作業が不要になるということですね。

### ImmutableInfrastructure

**「ImmutableInfrastructure」はある地点のサーバの状態を保存し、複製可能にする考え方**です。

インフラ構築がコードベースで管理されていても、冪等性を保証するためのコードを恒久的に書き続ける運用は大きな負担となり得ます。

扱うサーバの台数が多いほど、全てのサーバに構成を適用する時間もかかります。
そこでImmutableInfrastructureを利用して、正しくセットアップされた状態のサーバを常に使えるようにします。サーバに変更を加えたい場合は、既存のインフラをアップデートするのではなく作り直して新しいサーバのイメージとして保存し、複製できるようにします。一度セットアップしたサーバは二度と手を加えずに破棄するため、冪等性を気にする必要はありません。

## 実行環境とアプリケーションの一体化によるポータビリティ性の向上

DockerコンテナはOS（インフラ）とアプリケーションを同梱した箱のようなものです。Dockerイメージのビルドはインフラとアプリケーションをセットでビルドできることに他なりません。分断がおきないために作業環境の差異が生まれづらくなります。コンテナはDockerイメージとして保存、再利用もできます。

作成したDockerイメージは**Dockerがインストールされているマシンであればどこでも実行できます**。
アプリケーションとインフラをセットで管理することで、ポータビリティが高くなります。

## システムを構成するアプリケーションやミドルウェアの構成管理の容易さ

複数のアプリケーションやミドルウェアを組み合わせて正確に動作させることは、たとえDockerを利用していなくても難しいことです。複数コンテナを利用したアプリケーションの管理をしやすくするために**「DockerCompose」**というツールを提供しています。DockerComposeはyaml形式の設定ファイルで実行するコンテナを定義したり、依存関係を定義しての起動順を制御したりできます。DockerとDockerComposeを介すことで、本来複雑だった複数のアプリケーションやミドルウェアの依存関係がコードで簡潔に管理できるようになりました。

# さいごに

[Docker/Kubernetes 実践コンテナ開発入門](https://www.amazon.co.jp/dp/B07GP1Q3VT/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1 "Docker/Kubernetes 実践コンテナ開発入門")を参考にDockerの概要と何が凄いのかをまとめました。

個々人が手作業で開発環境を構築している現場からすると、Dockerを導入してコードで構成管理をして、コマンドベースで開発環境を構築出来ることは非常に魅力的であると感じました。
遅れを取り戻すためにも、Dockerを勉強して、業務で使えるくらいのレベルになりたいと思います。

ありがとうございました。