Docker Engineを立ててクライアントからいじる


Dockerってサーバクライアントモデルなんですよ。
いわゆるDockerをPCにインストールした！っていうのはクライアントとサーバをローカルにインストールして、ローカルからローカルに通信しているんですよね。

DockerではクライアントのことをDocker Client、サーバのことをDocker EngineとかDocker Daemonっていいます。
今回はDocker EngineをサーバにインストールしてクライアントからリモートでDockerをいぢれるようにしてみます。
※サーバ、クライアントともにDockerがインストールされている必要があります。

サーバは社内にある個人用kvmインスタンスを利用します。

# TL;DR

証明書を作ってサーバーとクライアントの設定をします。コンテナはサーバ側で動作します。

# 証明書の作成と配置

http://docs.docker.jp/engine/security/https.html

こちらの手順では既存のDocker Engineとクライアントの通信を構築する方法が記載されています。httpsでの通信なので証明書などの設定が主ですね。
この通りに証明書を作っていきます。sslの証明書を作る時と同じですね。

※CN(COMMON NAME)にホスト名を入れるようになっていますが、今ではSAN(Subject Alt Name)にホスト名を入れる必要がありそうです。
e.g `echo subjectAltName = DNS:$HOSTNAME,IP:127.0.0.1 > extfile.cnf`

`/etc/docker/`の中身がこんなになり〼。

```
[murata@localhost docker]$ ll
total 44
-r-------- 1 root root 3326 Jul  5 19:58 ca-key.pem
-r--r--r-- 1 root root 2000 Jul  5 19:58 ca.pem
-rw-r--r-- 1 root root   17 Jul  5 20:01 ca.srl
-r--r--r-- 1 root root 1814 Jul  5 20:01 cert.pem
-rw-r--r-- 1 root root 1582 Jul  5 20:01 client.csr
-rw-r--r-- 1 root root   30 Jul  5 20:01 extfile.cnf
-rw------- 1 root root  244 Mar 12 18:37 key.json
-r-------- 1 root root 3243 Jul  5 20:01 key.pem
-r--r--r-- 1 root root 1842 Jul  5 20:00 server-cert.pem
-rw-r--r-- 1 root root 1606 Jul  5 19:59 server.csr
-r-------- 1 root root 3243 Jul  5 19:59 server-key.pem
```

# Docker Engineを起動

とりあえずサーバー側のsystemdのdockerをoffにします。

```
# systemctl stop docker.service
# systemctl disable docker.service
```

とか。


## 手動で起動

```
[root@localhost docker]# dockerd-ce --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H=0.0.0.0:2376
INFO[2019-07-05T20:04:18.381531783+09:00] parsed scheme: "unix"                         module=grpc
INFO[2019-07-05T20:04:18.381859433+09:00] scheme "unix" not registered, fallback to default scheme  module=grpc
INFO[2019-07-05T20:04:18.382109267+09:00] parsed scheme: "unix"                         module=grpc
INFO[2019-07-05T20:04:18.382276187+09:00] scheme "unix" not registered, fallback to default scheme  module=grpc
INFO[2019-07-05T20:04:18.382314578+09:00] ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0  <nil>}]  module=grpc
INFO[2019-07-05T20:04:18.382581290+09:00] ClientConn switching balancer to "pick_first"  module=grpc
```

systemdで運用する際には、`/etc/systemd/system/multi-user.target.wants/docker.service` のExecStartに↑のオプションを追記すればよさそうです。
rpmで入れている場合、闇抱えるけど。。。

# クライアント側からいぢる

自分のクライアントの ~/.docker/ に ca.pem, cert.pem, key.pem をコピーします。

クライアント側からinfoを見てみます。
※172.16.11.154はサーバのIPアドレスです。

```
murata:~/.docker $ DOCKER_TLS_VERIFY=1 DOCKER_HOST=tcp://172.16.11.154:2376 docker info
Containers: 4
 Running: 1
 Paused: 0
 Stopped: 3
Images: 33
Server Version: 18.09.7
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc version: 425e105d5a03fabd737a126ad93d62a9eeede87f
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-957.21.3.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.607GiB
Name: localhost.localdomain
ID: USBJ:LDES:EZJN:J6AA:XNCG:DXYZ:FNNH:26Z3:K4TE:T266:YBNU:4GRM
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
```

`DOCKER_TLS_VERIFY=1 DOCKER_HOST=tcp://172.16.11.154:2376` の部分は自身の.bash_profileなどに書いておくと便利ですね。


試しにクライアントで`docker run -it ubuntu bash`してみます。

```
murata:~ $ DOCKER_TLS_VERIFY=1 DOCKER_HOST=tcp://172.16.11.154:2376 docker run -it ubuntu bash
root@9ac925cbd3a2:/#
root@9ac925cbd3a2:/# uname -a
Linux 9ac925cbd3a2 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
```

起動しました。

サーバ側で起動しているか確認します。サーバ側では鍵ファイルを~/.dockerに置いていないので指定する必要があります。（お好みでどうぞ）

```
[murata@localhost docker]$ sudo docker  --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem -H=172.16.11.154:2376 container ls
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
9ac925cbd3a2        ubuntu              "bash"              About a minute ago   Up About a minute                       objective_hofstadter
```

# まとめ

これで自身のPC内での開発からおさらばできます。カフェでドヤ開発はできなくなりますが。

複数人でDocker Engineを共有することでうまくDocker Engineを使うことができるんじゃないでしょうか。
ただし、リポジトリ名が被ると困るので名前とかを入れておくといいかもですね。その辺のデフォルト値を設定できたりしないんだろうか。。。
もちろん使う人に証明書を配る必要があります。

ローカルで運用する方法をよく見かけますが、オペレーションするPCとサーバは別にしておきたいですよね。ということで今回まとめました。