Dockerの本を読んでみた -3章編-

##前回までのおさらい
前回はDockerの本を読むと宣言し、2章まで読み切った
今回は3章から読み進めていくことを想定とし、まとめてみる

##アプリケーションとコンテナの粒度の話
この章では、アプリケーションを実際に構築するとなった場合、どのように構築していくことが望ましいのか、を考える章だった
###1コンテナ＝1プロセス？
Dockerはアプリケーションのデプロイに特化した技術なので、１コンテナ＝1プロセスが望ましいのではないかと考えるかもしれない。
しかし、結論から言うとそれは間違いで、厳密にこれを意識しすぎるとプロセスが逆に複雑化する
よって、「スタック」を構築していくことが重要とあった。スタックの説明は以下に追記
[スタックについて](https://docs.docker.jp/get-started/part5.html)

###1コンテナに1つの関心事
本の中では、公式の文章を引用している
> Each container should have only one concern
コンテナは1つの関心ごとだけに集中すべきだ

1つの関心事、これは1つのコンテナはある1つの役割や問題領域（ドメイン）のみにフォーカスされるべきだとの主張とのこと。
コンテナを使って構築を考える時、
**「それぞれのコンテナが担うべき役割を適切に見定め、かつそれがレプリカとして複製された場合でも副作用なくスタックとして正しく動作できる状態になるか？」**
という考えを念頭に設計すると良い。と本内では述べている。

##コンテナのポータビリティ
Dockerのメリットとして、ポータビリティ（可搬性）が挙げられる
ポータビリティを噛み砕いてまとめると、
>・アプリとインフラを「コンテナ」によって分離できる
　→管理がしやすい
・Dockerがインストールされているホストであれば、ホストOSも問わない
　→実行環境がオンプレでもクラウドでも関係なく動作する

というメリットがあると述べているが、実際は上の通りのポータビリティを絶対的に持っている訳ではない。と締め括っている。
「スタティックリンク」だとか「ダイナミックリンク」だとか良くわからない単語がまた出てきたので、その時は以下サイトを見て対処した
[コンテナを使う動機　なぜDocker（コンテナ）が期待されるか](https://qiita.com/NewGyu/items/d0b0d6074e13acd51f3e)

##Dockerフレンドリなアプリケーション
アプリケーションはDocker化しやすいとのこと。この章ではアプリを構築する為必要な要素について述べられていた。

###そもそもアプリを作る時の話
アプリを作る時、一般的に再利用性や柔軟性を持たせる為にオプションを持たせ、それによって動作を制御するのが一般的とのこと。
そして、柔軟性も兼ね備えたDockerを使い、コンテナにアプリを載せて挙動を制御するには、さまざまな方法がある。
>・実行時引数
・設定ファイル
・アプリケーションの挙動を環境変数で制御
・設定ファイルに環境変数を埋め込む

上記のような手法がある中で、本の中では
**環境変数で制御する**ことのが推奨されている。

###アプリケーションの挙動を環境変数で制御するとは？
環境変数とはーの概念は以下から学びました。

この章の要点をまとめると、
>メリット：「毎日Dockerイメージのビルドを必要としなくて良いこと」
　　　　　※環境変数はアプリとは別のリポジトリで管理し、運用していくのが望ましいとしている。
デメリット：「環境変数はシンプルさが特徴として上がっているので、階層構造を持っていないので、JSONやXMLなど回想的なデータ構造を持てるファイル方式に比べると、アプリケーション側でのオブジェクトへのマッピング処理が手間がかかりがちになる」

となる。
ただし、Go言語であれば、カンマ区切りの環境変数の値を配列変数にマッピングできるライブラリも存在するらしい。

##永続データをどう扱うのか？
Dockerコンテナを実行中に書き込まれたファイルは、ホスト側にファイル・ディレクトリをマウントしない限り、コンテナを破棄したタイミングでディスクから消去される。
一度コンテナを削除してしまうと、コンテナ自体再現性がない為、全く同じものを作ることもできない。
よって、削除は慎重に行う必要がある。
また、新しいバージョンのコンテナがデプロイされても、以前のバージョンのコンテナで利用していたファイル・ディレクトリをそのまま継続して利用できるようにする必要もある。
上記のような、継続して利用する為の手段として、「Data Volume」という概念が存在する。

###Data Volume
Dockerコンテナ内のディレクトリを、ディスクに永続化さする為の仕組みのこと
特徴を以下に挙げる

>・ホスト・コンテナ間でのディレクトリの共有・再利用が可能になる！
・Docker Volumeを設定していると、初回コンテナ作成時にホスト側で指定したパスで共有され、コンテナを停止・破棄した後もパスは残る

つまり、イメージを更新して新しくコンテナを作成しても、同じData Volumeを利用し続けることができるのだ。（作り直しにならないのは便利）
コマンドで使うと以下のような構文になる

```
#----- 構文 -----#
# docker container run options -v ホスト側ディレクトリ：コンテナ側ディレクトリ リポジトリ名:タグ名 コマンド コマンド引数
#----- 例 -----#
# docker container run -v ${PWD}:workspace gihyodocker/imagemagick:latest convert -size 100×100 xc:#000000 /workspace/gihyo.jpg
                          [host側ディレクトリ（カレントディレクトリ）] [gihyo~リポジトリ名] [convert~から引数]
```
上記例の訳文としては、
「ImageMagickに.jpgという１００×１００の黒い画像ファイルを生成させる」という意味があり、convertから後ろがコンテナに渡すアプリケーションの引数を指している。

####Data VolumeとData Volume コンテナの違い
以下にData VolumeとData Volumeコンテナの違いを記す

|項目|Data Volume|Data Volume コンテナ|
|---|---|---|
|概要|コンテナ内のディレクトリをディスクに永続化する為の仕組みのこと|データだけを持つコンテナ|
|特徴|ホスト側の特定のディレクトリに依存する性質あり|管理領域であるホスト側の<br>/var/lib/docker/volumes/に配置される<br>Docker管理下のディレクトリのみに影響する<br>→コンテナに与える影響を最小限に抑えられる|
|共有方法|コンテナ間とホスト間で直接ディレクトリを共有する|コンテナ間でディレクトリを共有する|
|役割|コンテナ間とホスト間でやりとりする|Docker Volumeへの仲介役も担うので、必ずしもホスト側のディレクトリを知らなくてもよい|

####データを他のDockerホストとも共有したい！
他のDockerホストでも共有したいとなった場合、求められる順として以下のようになる

>①Data Volumeコンテナからエクスポートしたいデータをファイルとしてホストに取り出す
　→コマンドとしてはファイルを取り出すと同時に圧縮する
②取り出したデータを展開し、Data Volumeコンテナを作成する
　→新規で作成したコンテナを指定してマウントすると、ホストにアーカイブ（圧縮）されたデータを取り出すことが可能となる

**注意**
**「docker image save」は、Dockerイメージファイルをアーカイブする機能の為、Data Volumeには適用されない**

##コンテナ配置戦略
今まで1つのホストに配置することを考えてきたが、それでは多くのリクエストをさばく必要のある実用的なシステムには向かない
そこで、どのように配置するのが望ましいのか、この章で説明していた。

###Docker Swarm
Docker Swarmは、一言で言うと、*複数のDockerホストを束ねてクラスタ化する為のツール*と言える。
・コンテナオーケストレーションシステムの1つ

また、コンテナオーケストレーションに関係する単語がいくつかあるので、以下に記す。

*Dockerコンテナオーケストレーションに関わる単語*

|名称|役割|対応コマンド|
|---|---|---|
|Compose|複数のコンテナを使うDockerアプリケーションの管理（主にシングルホスト）|docker-compose|
|Swarm|クラスタの構築や管理を担う（主にマルチホスト）|docker swarm|
|Service|Swarm前提、クラスタ内のService（1つ以上のコンテナの集まり）を管理する|docker service|
|Stack|Swarm前提、複数のServiceをまとめたアプリケーション全体の管理|docker stack|

####Docker swarmの使い方
正直、本に記載されている内容よりも、qiitaに記載されている内容を元に学習した方が渉ったので、こちらを紹介
[Docker Swarm 入門ハンズオン](https://qiita.com/TsutomuNakamura/items/6124ab7d32a58bc93ac7)

###Docker Service
Serviceの特徴は以下の通り
>・レプリカ数（コンテナ数）を制御することで、容易にコンテナを複製できる
・複数のノードに配置出来る為、スケールアウトしやすい
・Serviceによって管理される複数レプリカは、Service名で名前解決出来、かつServiceへのトラフィックはレプリカへ分散される

サービスの使い方は以下サイトの方がわかりやすかったので、紹介
[Dockerの全体像を理解する-後編-](https://qiita.com/etaroid/items/40106f13d47bfcbc2572)

###Docker Stack
Docker Stackの特徴は以下の通り
>・Docker Serviceをグルーピングできる
・複数のServiceで形成されるアプリケーションのデプロイに役立つ


以上が大まかな3章の流れでした。
次は4章についてまとめていこうと思う。