Docker machineを使ってみる


#Docker machineとは

AWSやGCP、さくらのクラウドなどに、Docker Engine をインストールするツールです。
Docker Engine は、Dockerホストを操作する為のコマンド等が含まれます。
docker-machine コマンドを使ってDockerホストを作成・管理します。

#環境

- MacBookPro
- Catalina
- Docker for Mac
- VirtualBox

#Dockerホストを作成する
docker-machine は仮想マシン上にDockerホストを作成します。
今回は明示的に仮想化ドライバーを指定していますが、特に操作対象を指定しなければVirtualBoxとなります。
--driver はインストール先の指定、default は作成するDockerホストに付ける名称です。

```
% docker-machine create --driver virtualbox default

~ 略
```

#Dockerホストの状態を確認する
docker-machine ls でDockerホストの状態を確認出来ます。
ドライバーがvirtualboxになっており、ステータスがRunningとなっています。

```
% docker-machine ls                                
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.12 
```

作成されたホストにはtinycorelinuxという軽量なOSがインストールされており、Docker Engineのインストールと起動が自動で行われます。

#Dockerホストに接続する①
docker-machine env を実行することで、対象ホストの設定用コマンドが表示されます。

環境変数を設定する export コマンドが列挙されています。

Run this command to configure your shell とある通り、記載の eval ~ からはじまるコマンドを実行するとまとめて環境変数の設定が出来ます。

```
% docker-machine env default
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/hogehoge/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
# Run this command to configure your shell: 
# eval $(docker-machine env default)

% eval $(docker-machine env default)

% echo $DOCKER_HOST
tcp://192.168.99.100:2376 
```

作成したホストがACTIVEになり、hello-worldコンテナが起動出来ました。

```
% docker-machine ls                 
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.12  
```

```
% docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete 
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

#Dockerホストに接続する②

sshで接続して仮想マシン上で実行されているのか確認します。
見た感じローカルで実行したような感覚になると思うので、作成したDockerホストにssh接続して確認します。

```
% docker-machine ssh default
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net
%
```

tinycorelinuxのアスキーアートが表示されました。
プロセス一覧を見てみます。

```
$ docker ps -a                                                 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
c8492503fce5        hello-world         "/hello"            35 minutes ago      Exited (0) 35 minutes ago                       inspiring_keldysh
```

Exitedとなって、先程起動したhello-worldコンテナが確認出来ます。

#NginxでWebページを公開してみる

今度はnginxのコンテナを起動して、Webページを公開してみます。

#Nginxのイメージの取得とコンテナの起動

-d はデタッチモードでバックグラウンドで起動します。
-p でホストとコンテナのポートをマッピングします。
その後に起動するイメージ名を指定します。

```
% docker run -d -p 8000:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
45b42c59be33: Pull complete 
8acc495f1d91: Pull complete 
ec3bd7de90d7: Pull complete 
19e2441aeeab: Pull complete 
f5a38c5f8d4e: Pull complete 
83500d851118: Pull complete 
Digest: sha256:f3693fe50d5b1df1ecd315d54813a77afd56b0245a404055a946574deb6b34fc
Status: Downloaded newer image for nginx:latest
bedf940d9670fab2e2d99a95d812ac6750aaf35772cc35c9048a82d9c0712c2a

```

IPアドレスは docker-machine env default を実行した際にも表示されていましたが、下記のコマンドで確認可能です。

```
% docker-machine ip                     
192.168.99.100
```

ブラウザで下記にアクセスしてみます。

```
192.168.99.100:8000
```

このような画面が出ればOKです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391107/575707d0-61b7-906f-6adb-df35c6774be6.png)


#Dockerホストを停止する

```
% docker-machine stop default
Stopping "default"...
Machine "default" was stopped.
```

STATEがStoppedになり、Nginxの画面も表示されなくなりました。

```
% docker-machine ls                     
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391107/a43e8576-301a-6493-c6a6-d6b6473a3b4e.png)



#Dockerホストを起動する

```
% docker-machine start default
Starting "default"...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
```

STATEがRunningになりました。

```
% docker-machine ls           
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER      ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.12   
```

#ActiveにしたDockerホストとの接続を解除する

docker-machine env に -u オプションを付けて実行すると、設定した環境変数を削除するためのコマンドが表示されます。

```
% docker-machine env -u
unset DOCKER_TLS_VERIFY
unset DOCKER_HOST
unset DOCKER_CERT_PATH
unset DOCKER_MACHINE_NAME
# Run this command to configure your shell: 
# eval $(docker-machine env -u)
```

これを実行します。

```
% eval $(docker-machine env -u)
```

ACTIVEから「*」が消えました。

```
% docker-machine ls            
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown   
```