【ふくだ学習録】Docker入門 part3【22日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )

### 今読んでいる本

[Docker入門](https://www.amazon.co.jp/dp/480071091X/ref=cm_sw_r_tw_dp_U_x_xVlmEbN8ZTHZK)

# Docker入門

### コンテナ
ホストOSと同じLinuxカーネル上を共有するが、ホストOSとは隔離されたプログラム実行環境を「コンテナ」と呼ぶ。

### プロセス
プログラムの実行状態を「プロセス」と呼ぶ。コンテナ内で稼働するプロセスは、ホストOSのファイルシステムや各種リソースにアクセスできない。

### コンテナIDとは？
６４バイト長の１６進数で表される、コンテナを一意に識別するためのID。
長すぎるため、コンテナが一意に決まる場合には、先頭の１２バイトをコンテナIDとして指定することでもdockerコマンドを使用することもできる。
またコンテナ作成時に、テキストベースの名前が自動的に割り振られるため、それを使って管理することもできる。

### dockerコマンドのモード
２種類の動作モードが存在する。
Dockerサーバとして動作する「サーバーモード（デーモンモード）」と、Dockerクライアントとして動作する「クライアントモード」。

### サーバーモード（デーモンモード）での実行
イメージやコンテナを管理したり、レジストリと通信したりというDockerの機能を提供するのがDockerサーバーの役割。`deamon`サブコマンドを指定してdockerコマンドを実行すると、dockerコマンドはサーバーモードで動作する。
サーバーモードのdockerコマンドは、ホスト環境の各種リソースを管理する関係上、管理者権限(`sudo`)で実行する必要がある。

```console
$ sudo docker deamon
```
※通常は勝手に立ち上がっていることが多いので、実際に入力したりすることはほとんどない。

### クライアントモードでの実行
Dockerサーバーにイメージやコンテナを操作するための指示を出すのが、クライアントモードで動作するdockerコマンドの役割。Linux環境以外のWindowsやOS Xでインストールされたdockerコマンドは、サーバーモードでは動作せずに、クライアントモードでのみ動作する。

### UNIXドメインソケットとは？
同一ホスト内のプロセス間通信に使われるプロトコル。一般的に通常のTCP接続よりもパフォーマンスがいいとされている。
dockerに関しては、Dockerサーバーとの通信に使用する際に使われていることが多い。（ただしWindowsやOS Xでへインストールしている場合は、TCPで通右心していることが多い。）

[Unixドメインソケットの確認](https://qiita.com/nk_yohn3301/items/7aec184e290940052ed2)

### 管理者権限を用いずにdockerコマンドを使用する方法
UNIXドメインソケットを使用する場合は、管理者権限が必要になる。（`sudo`コマンドが必要になる）
しかしUNIXドメインソケットを使用する場合でも、「docker」というグループに所属させていれば、sudoコマンドを使用せずに　dockerコマンドを実行できるようになる。（なるへそ）

```console
$ sudo groupadd docker
$ sudo gpasswd -a ユーザー名 docker
```
でdockerグループにユーザー追加できる。

セキリュティ的には、あまり管理者権限を使用しないほうがいい為、最初にこの設定をしておくほうが良い。
（TCP/IPで通信している場合は、一般ユーザー権限で元々dockerコマンドが使用できる。）

### 8つのサブコマンド
よく使用するコマンドは下記8つ。

**commit**
**images**
**ps**
**run**
**rm**
**rmi**
**search**
**stop**

イメージ管理に使用するのが、**commit,images,run,rmi,search**の5つで、コンテナ管理に用いるのが、**ps,run,rm,stop**の4つ。

#### runサブコマンド
ローカル環境に取得済みのイメージを基に新たなコンテナを作成して、それを実行する働きをする。
指定したイメージが取得済みでない場合は、Docker Hubからイメージを取得する作業も実施する。

コンテナに特定の名前をつけたい時は、

```console
$ docker run --name="コンテナ名" イメージ名
```
といった形で指定できる。

-dオプション：プロセスをバックグラウンドで稼働させる。

-pオプション:ホストの待ち受け通信ポートとコンテナの待ち受け通信ポートを結びつけためのもの。「-p ホストの通信ポート:コンテナの通信ポート」の形式で指定する。

#### psサブコマンド
稼働中のコンテナの情報を一覧表示するサブコマンド。
-aオプションを指定することで、停止中のコンテナの情報も表示できるようになる。

#### startサブコマンド
停止したコンテナを再実行する際のコマンド。

```console
$ docker start コンテナ名
```

コンテナの標準出力や標準エラーを仮想コンソールに出力したい場合は、-aオプションを指定する。

```console
$ docker start -a コンテナ名
```
#### rmサブコマンド
コンテナを削除する際に使用するコマンド。

```console
$ docker rm コンテナ名
```

もし全てのコンテナを削除したい場合には。下記コマンドを入力する。

```console
$ docker rm $(docker ps -qa)
```

#### imagesサブコマンド
取得したイメージを表示するコマンド

```console
$ docker images
```

#### rmiサブコマンド
ローカル環境に取得しているイメージを削除するコマンド。削除するイメージは、イメージIDかイメージ名で指定する。

イメージ名は「**リボジトリ名[:タグ名]**」といった構成になっている。リポジトリとはイメージを格納するためのデータベースのことで、タグ名とはリポジトリ内のイメージを識別するための名前。タグ名を省略した場合は、最新を意味する「latest」というタグ名が付けられたイメージが暗黙のうちに指定される。

```console
$ docker rmi イメージ名
```
削除するイメージに基づくコンテナが存在している場合は、-fオプションを指定しないと削除できない。
（-fオプションを付けてイメージを削除しても、自動的にコンテナが削除されるわけではない。）

#### searchサブコマンド
Docker Hub内のリポジトリを検索するためのサブコマンド。リポジトリは最大２５個表示される。

```console
$ docker search リポジトリ名
```
 検索結果で出てきたリポジトリ名には、単一の文字列のものと「/」で区切られた2つの文字列で構成されるものの２種類がある。前者はDocker社公式のもの。後者は非公式のもので「ユーザー名/ユーザーが設定したリポジトリ名」という構成になっている。

リポジトリ内にどういうタグ名のイメージが存在するかどうかは、下記コマンドで確認できる。

```console
公式イメージの場合
$ curl -s https://registry.hub.docker.com/v2/repositories/library/リボジトリ名/tags/ | grep -Po '"name":.*?[^\\],'

非公式イメージの場合
$ curl -s https://registry.hub.docker.com/v2/repositories/ユーザー名/リボジトリ名/tags/ | grep -Po '"name":.*?[^\\],'
```

#### stopサブコマンド
コンテナの停止をするためのサブコマンド。

```console
$ docker stop コンテナ名
```

#### commitサブコマンド
コンテナからイメージを作成する際に使用するサブコマンド。
基本的な書式は下記。

```console
$ docker commit [オプション] コンテナ [リポジトリ[:タグ]]
```
稼働中のコンテナに対して、commitサブコマンドを実行することもできるが、ファイルシステムの変更処理が不完全に行われてしまう場合などがあり、問題のあるイメージになる可能性が出てくるため、基本的にはstopしてから行う。

-cオプション：イメージの設定調整を行うオプション。
「EXPOSE 22」はTCP接続を22版ポートで待ち受ける設定、「CMD /usr/sbin/sshd -D」はコンテナ実行時に規定コマンドを実行する設定。（例えば記載しているのはSSHサーバーを起動するコマンド）。


### 自動的に割り当てられるコンテナ名
ユーザーが特に指定しない場合、Dockerは「形容詞_人名」の構成でコンテナ名を作成する。組み合わせは63×135の8504通り（１通り使われないパターンがある）あり、ランダムで決定される。もしランダムで作成した名前が、すでに使用されている場合は、最大5回まで再生成していく。（その際に末尾に0〜9の数字がランダムにつく）
おもろい仕組み。

### マウントする方法
「マウント」とは、ホスト側（コンテナの外）にあるディレクトリ・ファイルを、コンテナの中から利用できるようにする機能。(正確には、そういったマウント手法を「バインドマウント」と呼ぶ)

```console
docker run -v [ホストディレクトリの絶対パス]:[コンテナの絶対パス] [イメージ名] [コマンド]
```

[【Docker】Dockerでホストのディレクトリをマウントする](https://qiita.com/Yarimizu14/items/52f4859027165a805630)
[【Docker】第5回　マウントについて（bind）](https://www.public.ne.jp/2019/02/08/docker-5/)

### ホストの同じ待ち受けポートを使うコンテナが存在する場合
runコマンドを実行するとエラーになってしまう。その場合は、stopコマンドでその競合しているコンテナを停止する必要がある。

### SElinuxが原因でディレクトリにアクセスできなかった場合
ホストのセキュリティ機能であるSELInuxという機能があるが、それの影響でホストのディレクトリにアクセスできない場合がある。具体的にはDockerサーバーを「--selinux-enabled」というオプション付きで実行している場合。
そういったときには、次のようなコマンドを実行することで、問題が解消される場合がある。

```console
$ sudo chcon -Rt svirt_sandbox_file_t /home/www
```
※上記コマンドは、SELinuxで使用するラベルをホストの/home/wwwディレクトリとその内部ファイルに一括設定するコマンド。

SELinuxに関することは、下記サイトがわかりやすかった。
[理由がわかれば怖くない！SELinux とのつきあい方](https://blog.fenrir-inc.com/jp/2016/09/selinux.html)


### Docker用のオリジナルイメージを作成する方法。
主な方法は2つある。
1つは、コンテナ内のファイルをカスタマイズし、そのコンテナからイメージを作成する方法。
もう1つは「Dockerfile」という設定ファイルを作成して、そこからイメージを作成する方法。

# 今日の一言
全然勉強進まんかった！！家探し早く終わりたい！エライザかわい！