远程连接docker daemon,Docker Remote API
Posted wangmo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了远程连接docker daemon,Docker Remote API相关的知识,希望对你有一定的参考价值。
https://deepzz.com/post/dockerd-and-docker-remote-api.html
不知道大家有没有遇到这样一种情形:每次构建好了镜像,push
到私有仓库后。你还要ssh
到服务器,进行pull
,每次登录服务器的过程非常的痛苦。如果服务器ip
没有映射域名,那记录ip
也是一个痛苦的过程。博主,开始关注到docker remote api
,它可以让你在本地就可以完成docker
的所有操作,于是博主开发了基于etcd
配置的docker
管理工具,还蛮好用的。下面是我docker
部分配置的一些经历,分享给大家,希望对大家有帮助。
更新列表:
- 2017/04/27:添加
/etc/docker/daemon.json
文件配置过程(version 在 1.12 之后可用),文档地址。
服务端搭建
首先,我们需要通过系统的包管理器安装docker
:
- Ubuntu:https://docs.docker.com/engine/installation/linux/ubuntu/
- CentOS:https://docs.docker.com/engine/installation/linux/centos/
- 更多,请至官网:https://docs.docker.com/engine/installation/
当我们的docker
安装好之后,运行sudo docker ps
查看是否运行成功。
$ sudo groupadd docker # 创建docker组
$ sudo usermod -aG docker whoami # 将当前用户添加到docker组
重启docker服务,注销登录,再次登录,这样就可以免去每次输入sudo的烦恼了。
ok,我们安装好之后,docker
宿主程序默认是通过非网络的Unix套接字运行,是只能够进行本地通信(/var/run/docker.sock
),是不能够直接远程连接docker
的。需要修改其配置:
测试环境
ubuntu: 有host1,ubuntu系统,其配置文件路径在/etc/default/docker
。
$ sudo vi /etc/default/docker
DOCKER_OPTS="-H tcp://0.0.0.0:2375"
$ sudo service docker restart
# ubuntu docker的其它操作方式
$ sudo service docker start
$ sudo service docker stop
这里监听了tcp
的2375
端口,现在我们就可以通过别的主机host2访问到这台主机的docker
了(但是host1现在不能本地访问了)。推荐DOCKER_OPTS
写成:
DOCKER_OPTS="-H unix:///var/run/docker.sock -H 0.0.0.0:2375"
当然了这是不安全的,任何人都能够访问该端口,推荐测试用。
centos: 有host1,centos系统,其配置文件路径在/etc/sysconfig/docker
。
$ sudo vi /etc/sysconfig/docker
other_args="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"
$ sudo service docker restart
# centos docker的其它操作方式
$ sudo service docker start
$ sudo service docker stop
$ /bin/systemctl start docker.service
注:同样这里也是不安全的。
daemon.json:1.12版本后, 用户可以自行创建配置文件 /etc/docker/daemon.json
,该文件不区分系统,是通用的,推荐使用。具体参考:官方文档。不知道版本的可以通过 $ dockerd version
查看。
首先,你需要创建 /etc/docker/daemon.json
文件,文件内容如下:
{
"hosts": [
"tcp://0.0.0.0:2375",
"unix:///var/run/docker.sock"
]
}
然后,通过 dockerd
启动守护进程:
$ dockerd
WARN[0000] [!] DON‘T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON‘T KNOW WHAT YOU‘RE DOING [!]
INFO[0000] libcontainerd: new containerd process, pid: 3952
WARN[0000] containerd: low RLIMIT_NOFILE changing to max current=1024 max=4096
INFO[0001] [graphdriver] using prior storage driver "aufs"
INFO[0001] Graph migration to content-addressability took 0.00 seconds
WARN[0001] Your kernel does not support cgroup blkio weight
WARN[0001] Your kernel does not support cgroup blkio weight_device
INFO[0001] Loading containers: start.
......................INFO[0001] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address
INFO[0001] Loading containers: done.
INFO[0001] Daemon has completed initialization
INFO[0001] Docker daemon commit=7392c3b graphdriver=aufs version=1.12.5
INFO[0001] API listen on /var/run/docker.sock
INFO[0001] API listen on [::]:2375
这里你可以看到警告 WARN[0000]
,在不使用 tlsverify
验证的情况下,一定要注意 IP 的绑定!!!
更多 dockerd
命令的使用方法请参考:https://docs.docker.com/engine/reference/commandline/dockerd/。
可以看到,上面所说的均没有采取任何验证方式。仅供测试使用或内部使用。千万不要暴露到公网。
线上环境,安全环境
这里介绍,通过自签名证书安全认证构建HTTPS encypted socket
。上面测试环境用的2375
端口,docker
推荐2376
作为安全端口。当然我们可以随意设置端口,哈哈。
证书的生成: 详细信息,移步官网:Protect the Docker daemon socket。其原理是通过指定tlsverify
标志并将Docker的tlscacert
标志指向受信任的CA
证书来启用TLS
。在守护进程模式下,它只允许来自由该CA
签名的证书认证的客户端的连接。 在客户端模式下,它将只连接到具有由该CA
签名的证书的服务器。
警告:使用TLS和管理CA是一个高深的主题。在生产环境中使用OpenSSL,x509和TLS之前,请熟悉OpenSSL,x509和TLS。
警告:这些TLS命令将只在Linux上生成一组有效的证书。 macOS附带的OpenSSL版本与Docker所需的证书不兼容。
首先,生成CA
公钥和私钥:
$ openssl genrsa -aes256 -out ca-key.pem 4096 # 生成CA私钥
Generating RSA private key, 4096 bit long modulus
............................................................................................................................................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem #生成CA公钥,也就是证书
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.‘, the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
现在我们有了CA
,就可以创建服务器私钥和证书请求文件了,请确保Common Name
(i.e., server FQDN or YOUR name)匹配你将要连接的docker
主机。
注意,使用你
docker
宿主机的DNS name替换下面的$HOST
$ openssl genrsa -out server-key.pem 4096 # 生成服务器私钥
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr # 用私钥生成证书请求文件
现在,我们可以用CA
来签署证书了。这里我们可以填写IP
地址或则DNS name
,如,我们需要允许10.10.10.20
和127.0.0.1
连接:
$ echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
# 将Docker守护程序密钥的扩展使用属性设置为仅用于服务器身份验证:
$ echo extendedKeyUsage = serverAuth >> extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
客户端证书:
$ openssl genrsa -out key.pem 4096 # 客户端私钥
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
$ openssl req -subj ‘/CN=client‘ -new -key key.pem -out client.csr # 客户端证书请求文件
用CA
为客户端签署证书文件:
# 要使密钥适配客户端身份验证,请创建扩展配置文件:
$ echo extendedKeyUsage = clientAuth >> extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
删除证书请求文件:
$ rm -v client.csr server.csr
默认的私钥权限太开放了,为了更加的安全,我们需要更改证书的权限,删除写入权限,限制阅读权限(只有你能查看):
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
证书文件删除其写入权限:
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
证书的部署:
# ubuntu
$ sudo vi /etc/default/docker
如:DOCKER_OPTS="-D --tlsverify=true --tlscert=/var/docker/server-cert.pem --tlskey=/var/docker/server-key.pem --tlscacert=/var/docker/ca.pem
-H tcp://0.0.0.0:2376"
$ sudo service docker restart
# centos
$ sudo vi /etc/sysconfig/docker
如:OPTIONS=‘--selinux-enabled --log-driver=journald --tlsverify=true‘
DOCKER_CERT_PATH=/etc/docker
$ sudo service docker restart
# daemon.json
$ sudo vi /etc/docker/daemon.json
{
"tlsverify": true,
"tlscert": "/var/docker/server-cert.pem",
"tlskey": "/var/docker/server-key.pem",
"tlscacert": "/var/docker/ca.pem",
"hosts": [
"tcp://0.0.0.0:2376",
"unix:///var/run/docker.sock"
]
}
$ dockerd
INFO[0000] libcontainerd: new containerd process, pid: 4823
WARN[0000] containerd: low RLIMIT_NOFILE changing to max current=1024 max=4096
INFO[0001] [graphdriver] using prior storage driver "aufs"
INFO[0001] Graph migration to content-addressability took 0.00 seconds
WARN[0001] Your kernel does not support cgroup blkio weight
WARN[0001] Your kernel does not support cgroup blkio weight_device
INFO[0001] Loading containers: start.
......................INFO[0001] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address
INFO[0001] Loading containers: done.
INFO[0001] Daemon has completed initialization
INFO[0001] Docker daemon commit=7392c3b graphdriver=aufs version=1.12.5
INFO[0001] API listen on /var/run/docker.sock
INFO[0001] API listen on [::]:2376
ok,可以看到没有警告 WARN
。
警告:这些证书的保存非常重要,关系着你的服务器的安全,请妥善保管。
客户端连接
普通连接:
$ docker -H tcp://127.0.0.1:2375 ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ed7b8f338ad mongo:3.2 "/entrypoint.sh mo..." 11 days ago Up 3 hours 0.0.0.0:27017->27017/tcp eidb
TLS连接:
$ docker --tlsverify --tlscacert=~/docker/ca.pem --tlscert=~/docker/cert.pem --tlskey=~/docker/key.pem -H=192.168.99.100:2376 version
Client:
Version: 1.13.0-rc1
API version: 1.25
Go version: go1.7.3
Git commit: 75fd88b
Built: Fri Nov 11 22:32:34 2016
OS/Arch: darwin/amd64
Server:
Version: 1.13.0-rc1
API version: 1.25
Minimum API version: 1.12
Go version: go1.7.3
Git commit: 75fd88b
Built: Fri Nov 11 22:32:34 2016
OS/Arch: linux/amd64
Experimental: false
# curl 连接测试
$ curl https://192.168.99.100:2376/images/json --cert ~/.docker/cert.pem --key ~/.docker/key.pem --cacert ~/.docker/ca.pem
为了不每次都指定证书,我们可以指定默认连接:
$ mkdir -pv ~/.docker
$ cp -v ~/{ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://192.168.99.100:2376 DOCKER_TLS_VERIFY=1 # 这里只是临时指定,永久请写入*profile里面
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ed7b8f338ad mongo:3.2 "/entrypoint.sh mo..." 11 days ago Up 3 hours 0.0.0.0:27017->27017/tcp eidb
当然也可以指定证书文件路径:
$ export DOCKER_CERT_PATH="~/docker"
我的mac下的~/.bash_profile
如下:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_API_VERSION=""
export DOCKER_CERT_PATH="/Users/chen/.docker/machine/machines/default"
特别说明以下,DOCKER_API_VERSION
可以不设置,默认是docker/client/client.go
中的const DefaultVersion string
版本。
其它模式
如果你不想有完全的双向认证,你可以通过混合标志来运行各种其他模式的Docker。
宿主机 模式:
tlsverify
,tlscacert
,tlscert
,tlskey
set: Authenticate clientstls
,tlscert
,tlskey
: Do not authenticate clients
客户度 模式:
tls
: Authenticate server based on public/default CA pooltlsverify
,tlscacert
: Authenticate server based on given CAtls
,tlscert
,tlskey
: Authenticate with client certificate, do not authenticate server based on given CAtlsverify
,tlscacert
,tlscert
,tlskey
: Authenticate with client certificate and authenticate server based on given CA
附上:
docker remote api
:https://github.com/docker/docker/tree/master/client
etcd clientv3
:https://github.com/coreos/etcd/tree/master/clientv3
本文链接:https://deepzz.com/post/dockerd-and-docker-remote-api.html,参与评论 »
--EOF--
以上是关于远程连接docker daemon,Docker Remote API的主要内容,如果未能解决你的问题,请参考以下文章
本地docker不能登录远程harbor服务器,error response from daemon,error parsing http 403 response body
本地docker不能登录远程harbor服务器,error response from daemon,error parsing http 403 response body
markdown Docker远程API,通过daemon.json进行客户端验证
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?(代码