Dockerってサーバクライアントモデルなんですよ。
いわゆるDockerをPCにインストールした!っていうのはクライアントとサーバをローカルにインストールして、ローカルからローカルに通信しているんですよね。
DockerではクライアントのことをDocker Client、サーバのことをDocker EngineとかDocker Daemonっていいます。
今回はDocker EngineをサーバにインストールしてクライアントからリモートでDockerをいぢれるようにしてみます。
※サーバ、クライアントともにDockerがインストールされている必要があります。
サーバは社内にある個人用kvmインスタンスを利用します。
TL;DR
証明書を作ってサーバーとクライアントの設定をします。コンテナはサーバ側で動作します。
証明書の作成と配置
こちらの手順では既存の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とサーバは別にしておきたいですよね。ということで今回まとめました。