ド素人がDockerの本を読んでみた

##はじめに
少し前、原因は分からないが、Twitterのトレンドにて「Docker」がヒットしていた。
彼ら？は口々に「Dockerを知らん奴は人権がない〜」的な発言を見た、そして私は「ほう、それはどんなものなのか」と思った。
言う方も言うからにはきっとわかっているのだろう。すごい。尊敬する。私なんてど素人だよ！くじらってことぐらいしか知らんよ！
ということで、人権がないので人権を求め、読んでみることにした。

##これは？
初心者である自分の備忘録として記す。
勿論、どなたかの役に立てれば幸いである。

##読んだ本
以下本を読んでみた。
[Docker/Kubernetes 実践コンテナ開発入門](https://www.techbookrank.com/books/5c043e93f53e80000483916e)


##はじめまして、Docker
###Dockerとは、何なのか？
・コンテナ型仮想化技術を用いる
・アプリケーションをデプロイするのに特化した箱である。
・常駐アプリケーションとCLIから成り立つプロダクト

###Dockerの歴史
要点をまとめると以下のようになる
・元々、Dockerのコンテナ型仮想化技術はLXC（Linux Containers）が主流で作成されていた。
・従来はホストOSとゲストOSに分かれて、それぞれかどちらかにアプリケーションを載せていた
・従来のようにホストOSやゲストOSにアプリケーションを載せておくと、同じアプリを入れているのに挙動が違う！となった時に片方だけアップデートしなければならない、などの対処が必要だった
・Dockerは「コンテナ」という概念を持ち、ホストOSゲストOS区別せず、ホストOSよりのOSを管理し、他アプリケーションを作成したいとなった時でも、OSによる依存関係問題を気にせずデプロイ出来るようになった

###Docker Composeとは
一言で言うと、「yaml形式の設定ファイルで、実行するコンテナを定義したり、依存関係を定義して起動順を制御したりすること」と定義出来る。
役割としては、
>複数のコンテナから成るサービスを構築・実行する手順があった時、それらを自動的にして管理を用意にする機能のこと

とあった。

###Dockerコマンドの一覧
Dockerコマンドは色々ある。良くわからないものも多数あったので、helpコマンドを用いて意味を調べてみた。
作ったdocker環境内で以下コマンドを実施

```
# docker help
```

|command  |Englishの説明  |意味（個人的な解釈）  |
|---|---|---|
|attach  |Attach local standard input, output, and error streams to a running container |実行中のコンテナへアタッチする  |
|build  |Build an image from a Dockerfile  |Dockerfileからイメージをビルドする  |
|commit  |Create a new image from a container's changes  |コンテナ内の変更から新しいイメージを作る  |
|cp  |Copy files/folders between a container and the local filesystem  |ファイルやファイルディレクトリをコピーする  |
|create  |Create a new container  |新しくコンテナを作る  |
|diff  |Inspect changes to files or directories on a container's filesystem  |コンテナ内のファイルやディレクトリで変化がないか比べる  |
|events  |Get real time events from the server  |サーバからのイベントをリアルタイムで取得する  |
|exec  |Run a command in a running container  |動いているコンテナ内でコマンドを実行する  |
|export  |Export a container's filesystem as a tar archive  |tarアーカイブとしてコンテナのファイルに出力する  |
|history  |Show the history of an image  |イメージの履歴を参照する  |
|images  |List images  |イメージリストの表示  |
|import  |Import the contents from a tarball to create a filesystem image  |圧縮されたものからファイルイメージを作るコンテンツを入れる  |
|info  |Display system-wide information  | システム情報を参照する |
|inspect  |Return low-level information on Docker objects  |コンテナあるいはイメージかタスクの低レベル情報を表示  |
|kill  |Kill one or more running containers  |動いているコンテナを強制停止する  |
|load  |Load an image from a tar archive or STDIN  |tarアーカイブまたはSTDIN(標準入力)からイメージを読み込み、イメージIDを表示させる  |
|login  |Log in to a Docker registry  |Docker レジストリ・サーバへログインする  |
|logout  |Log out from a Docker registry  |Docker レジストリ・サーバからログアウトする  |
|logs  |Fetch the logs of a container  |コンテナのログを取得する  |
|pause  |Pause all processes within one or more containers  |1つまたは複数のコンテナで実行されているプロセスを停止する  |
|port  |List port mappings or a specific mapping for the container  |コンテナの為にポートを指定する  |
|ps  |List containers  |コンテナのリストを表示する  |
|pull  |Pull an image or a repository from a registry  |レジストリ・リポジトリからイメージを持ってくる  |
|push  |Push an image or a repository to a registry  |レジストり・リポジトリへイメージをpushする  |
|rename  |Rename a container  |コンテナ名を再度決める  |
|restart  |Restart one or more containers  |1つまたは複数のコンテナを再起動する  |
|rm  |Remove one or more containers  |1つまたは複数のコンテナを削除する  |
|rmi  |Remove one or more images  |1つまたは複数のイメージを削除する  |
|run  |Run a command in a new container  |新しいコンテナを実行する  |
|save  |Save one or more images to a tar archive (streamed to STDOUT by default)  |1つまたは複数のイメージをtarアーカイブに保存する  |
|search  |Search the Docker Hub for images  |Docker HUBのイメージを検索する  |
|start  |Start one or more stopped containers  |1つまたは複数コンテナを起動する  |
|stats  |Display a live stream of container(s) resource usage statistics  |1つまたは複数のコンテナの使用状況をライブで流し続ける  |
|stop  |Stop one or more running containers  |1つまたは複数コンテナを停止する  |
|tag  |Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE  |リポジトリ内のイメージにタグ付けする  |
|top  |Display the running processes of a container  |コンテナで実行中のプロセスを表示する  |
|unpause  |Unpause all processes within one or more containers  |コンテナ内の全てのプロセスに対し、一時停止を解除  |
|update  |Update configuration of one or more containers  |1つまたは複数のコンテナの設定を更新  |
|version  |Show the Docker version information  |Dockerバージョンを確認  |
|wait  |Block until one or more containers stop, then print their exit codes  |コンテナが停止するのを阻止し、終了コードを表示  |

####さらに詳しく見たい場合
Docker imageを作る時のコマンド詳細を見たい時は以下のように入力する

```
# docker image --help
```

##Dockerの操作
Dockerを操作するには2種類の方法がある

>①イメージに関する操作
②コンテナに関する操作

それぞれ詳しく見ていく

###イメージに関する操作
イメージを操作する場合、大きく分けて5つ操作がある
それは以下5つである。①〜④は割愛する。

####①docker search (イメージを探す)
####②docker image pull (イメージを持ってくる)
####③docker image ls (イメージ一覧を参照する)
####④docker image tag (イメージにタグ付けする)
####⑤docker image push (イメージを公開する)
イメージを公開する場合は「push」コマンドを使用する

```
#----- 構文 -----#
# docker image push option リポジトリ名:tag名
#----- 例 -----#
# docker image push example/echo:latest
```
ここまでがイメージに関する操作の説明で、以降はコンテナ操作に関する説明になる。



###コンテナに関する操作
「コンテナに関する操作」とはコンテナを動かす操作のこと
以下にコンテナでやりたいことを章立てでまとめてみる

####コンテナ一覧を見たい
大体使用コマンドは以下のようなコマンドを使ってコンテナ一覧を参照する

```
# docker container ls
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS       NAMES
XXXXXXXXXX   example/echo:latest   "go run /echo/main.go"   6 seconds ago   Up 5 seconds                 test-echo
```

####docker container lsで表示されるものの意味

|項目|内容|
|---|---|
|CONTAINER ID|コンテナに付与される一意のID|
|IMAGE|コンテナ作成に使用されたDockerイメージ|
|COMMAND|コンテナで実行されているアプリケーションのプロセス|
|CREATED|コンテナが作成されてから経過した時間|
|STATUS|Up(実行中)、Exited(終了)といったコンテナの実行状態|
|PORTS|ホストのポートとコンテナポートの紐付け（ポートフォワーディング）|
|NAMES|コンテナに付けられた名前|

この一覧に記載してあるコンテナIDやコンテナ名を元にコンテナの操作を行なっていく。
しかし、コンテナを動かす度に毎回lsするのはめんどい
そこで「名前付きコンテナ」という概念が生まれた（らしい）
「名前付きコンテナ」の作り方は以下のような構文を使う

```
#----- 構文 -----#
# docker container run --name [コンテナ名] [イメージ名]:[tag名]

#----- 例 -----#
# docker container run -t -d --name test-echo example/echo:latest
```

#####その他覚えておくと良い頻出オプション

|option名|説明|
|---|---|
|-i|docker起動後にコンテナ側の標準出力を繋ぎっぱなしにする。<br> よってshellに入ってコマンドを実行出来たりする|
|-t|擬似端末を有効にする <br> |
|--rm|コンテナ終了時にコンテナを破棄する|
|-v|ホストとコンテナ間のディレクトリ、ファイルを共有する時に使う|

####特定の条件に一致するものだけ探したい
沢山存在するコンテナの中から、特定の条件だけ探したい時、「--filter」機能を用いる

```
#----- 構文 -----#
# docker container ls --filter "filter名=値"
#----- 例 -----#
# docker container ls --filter "name=echo1"
```

####終了したコンテナだけ見たい
実行が終了しているコンテナ一覧を参照する時は「-a」を用いる

```
# docker container ls -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED             STATUS        PORTS                                         NAMES
XXXXXXXX   example/echo:latest       "go run /echo/main.go"   14 minutes ago      Up 14 minutes   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp     echo2
```

####コンテナを停止したい
コンテナを停止したい時はstopコマンドを用いる

```
#----- 構文 -----#
# docker container stop [コンテナIDまたはコンテナ名]
#----- 例 -----#
docker container stop 9i80876655yt8uj7
```

####コンテナを再起動したい
再起動したい場合は「restart」を用いる

```
#----- 構文 -----#
# docker container restart [コンテナIDまたはコンテナ名]
#----- 例 -----#
# docker container restart 9i80876655yt8uj7
```

####標準出力を取得したい
Dockerのログを標準出力で取得したい時は、「logs」コマンドで表示することが出来る

```
#----- 構文 -----#
# docker container logs options コンテナ名またはコンテナID
#----- 例 -----#
# docker container logs -f 1ed504XXXXX
 *-f 標準出力を取得し続けるオプション
```

####実行中のコンテナでコマンド実行したい
実行中のコンテナにコマンド実行したい場合は、「exec」コマンドを使用する
尚、今回使用しているオプションの「-it」は、コンテナをシェル経由で操作出来るようになるオプションのこと。
実行中に動かしたい時は無条件でこのオプションをつけると良いらしいです

```
#----- 構文 -----#
# docker container exec options コンテナIDまたはコンテナ名 コンテナ内で実行するコマンド
#----- 例 -----#
# docker container exec -it echo sh
# pwd
/go
# exit
```

####ファイルをコピーしたい
コンテナ間、コンテナ・ホスト間でファイルをコピーしたい場合は「cp」コマンドを使用する

```
#----- 構文 -----#
# docker container cp options コンテナIDまたはコンテナ名:コンテナ内のコピー元 ホストのコピー先
# docker container cp options ホストのコピー元 コンテナIDまたはコンテナ名:コンテナ内のコピー先
#----- 例 -----#
# docker container cp echo:/echo/main.go .
 * カレントディレクトリにmain.goをコピーする場合
```

##運用管理向け
運用する場合のコマンドが2つまとめられていた。

###①docker container prune (破棄)
pruneを使うと、不要なイメージやコンテナを一括削除できる
まずはコンテナを一括削除したい時の方法を紹介

```
#----- 構文 -----#
# docker container prune options
#----- 例 -----#
# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
XXXXXXXXXXXXX

Total reclaimed space: 20.64MB
```

次にイメージを一括削除する方法

```
#----- 構文 -----#
# docker image prune options
#----- 例 -----#
# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 20B
```
最後に利用されていないコンテナやイメージ、ボリューム、ネットワークといった全てのDockerリソースを一括で削除する方法

```
#----- 構文 -----#
# docker system prune 
```


###②docker container stat (利用状況の取得)
コンテナ単位でシステムリソースの利用状況を知るには、「container stat」を用いる

```
#----- 構文 -----#
# docker container stats options [表示するコンテナID...]
#----- 例 -----#
# docker container stats 
CONTAINER ID    NAME   CPU %    MEM USAGE  / LIMIT      MEM %    NET I/O    BLOCK I/O         PIDS
XXXXXX          echo   0.0%     26.23MiB   / 3.699GiB   0.69%    656B / 0B  197kb  / 7.78MB   14
```

##Docker Conposeでマルチコンテナを実行する
上の章でDocker Composeとは〜という概要は説明済みなので、実際にやってみた手順について説明する
①　所定のディレクトリ内にdocker-compose.ymlというymlファイルを作成する

```
# vi docker-compose.yml
version: "3"
services:
  echo:
  image: example/echo:latest
  ports:
   - 9000:8080
```
②　①で作成したファイルを元にコンテナ群を起動するコマンドを実行する

```
# docker-compose up -d
```
③ 起動していることを以下コマンドで確認

```
# docker container ls
```

④コンテナを一度停止させてみる

```
# docker-compose down
```

といった流れでハンズオン的に動作確認を実施。
本の中ではjenkinsを立ててみるという流れまで記載があったので、興味がある人は購入してやってみることをおすすめする


##備忘録
今回この記事では2章までしか読み切らなかった....
全部で10章まであるこの本を1日でやりきろうとすると、積む
（未経験からDockerを始めると、本を読みながら、（環境で）触りながら、まとめながら、を同時にやると結構時間食う）
次回は3章以降についてまとめていく

##参照資料
[Docker Compose ことはじめハンズオン](https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a)
[めもたんす　Docker container statsコマンドの使い方](https://www.memotansu.jp/docker/741/)
[公式：コマンドライン・リファレンス](https://docs.docker.jp/engine/reference/commandline/toc.html)