Dockerのリモート接続について
Dockerはデフォルトではネットワークを通さないUnixソケットで操作できます。オプションでHTTPソケットを使っても操作できるのですが、ネットワーク上で安全に使う方法としてTLSを有効にして、証明書を使う方法が推奨されています。
今回は、証明書を使う方法ではなく、ssh tunnelを使ってリモートのDockerを操作できるようにします。
実現したいこと
ラズパイで動かしているDockerをmacからリモートで操作できるようにする。
環境
- Dockerホスト(Raspberry Pi 3 Model B)
$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux
$ grep -H "" /etc/*version ; grep -H "" /etc/*release
/etc/debian_version:9.8
/etc/os-release:PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
/etc/os-release:NAME="Raspbian GNU/Linux"
/etc/os-release:VERSION_ID="9"
/etc/os-release:VERSION="9 (stretch)"
/etc/os-release:ID=raspbian
/etc/os-release:ID_LIKE=debian
/etc/os-release:HOME_URL="http://www.raspbian.org/"
/etc/os-release:SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
/etc/os-release:BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:57:21 2018
OS/Arch: linux/arm
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:17:57 2018
OS/Arch: linux/arm
Experimental: false
- Dockerクライアント(macOS Mojave)
$ uname -a
Darwin xxx-MacBook-Pro.local 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
$ docker version
Client: Docker Engine - Community
Version: 18.09.1
API version: 1.39
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:33:12 2019
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.1
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:41:49 2019
OS/Arch: linux/amd64
Experimental: true
Dockerホスト(ラズパイ)側の準備
dockerデーモンの起動オプションでTCPソケット通信を使うようにすることができるのですが、今回はsocatを使います。さらにsocatはdockerコンテナ内で実行したいと思います。
FROM alpine:latest
RUN set -x && apk update && apk add \
socat \
&& rm -rf /var/cache/apk/*
ENTRYPOINT [ "socat" ]
CMD [ "-v", "tcp-listen:2375,reuseaddr,fork", "unix-connect:/var/run/docker.sock" ]
dockerイメージをビルドします。
$ docker build ./ -t socat:alpine
socatをdockerコンテナとして実行します。
$ docker run --rm -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 --name=socat socat:alpine
これでループバックアドレス(127.0.0.1)のポート2375に接続することでDockerのUnixソケットと通信できるようになります。
Dockerクライアント(mac)側の準備
ラズパイにssh接続する時にLocalForwardingで接続します。
$ ssh pi@raspberrypi.local -L 2375:127.0.0.1:2375
.ssh/config記載例
Host raspberrypi-docker
Hostname raspberrypi.local
User pi
LocalForward 2375 localhost:2375
Dockerクライアント(mac)側でdockerコマンドの実行
dockerコマンド実行時にオプションとして「-H 127.0.0.1」をつけて実行します。
$ docker -H 127.0.0.1 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55db512ab7fd socat:alpine "socat -v tcp-listen…" 9 minutes ago Up 9 minutes 127.0.0.1:2375->2375/tcp socat
$ docker -H 127.0.0.1 version
Client: Docker Engine - Community
Version: 18.09.1
API version: 1.39
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:33:12 2019
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:17:57 2018
OS/Arch: linux/arm
Experimental: false
ラズパイ上のdockerホストが応答しているのが、確認できると思います。
※ホームネットワーク内など安全が確保されているであろうネットワーク内であれば、わざわざssh tunnelせずともdockerホスト側でsocatを実行する時にループバックアドレス(127.0.0.1)指定ではなく、0.0.0.0を指定すれば、dockerコマンド実行時のオプションとして「-H raspberrypi.local」を付与すれば実行できるようにもなります。