正文
docker 使用了客户端 -- 服务端模型。服务端对外提供 rest api。
默认安装方式,客户端和服务端在同一台主机上,通过本地安全 pic socket 进行通信,例如 linux 中 /var/run/docker.sock。我们还可以配置它们通过网络进行通信。它们默认网络配置使用不安全的 http socket,端口为 2375。
在生产环境这是不能接受的。通过 tls 的方式连接解决这个问题。生产环境中推荐这种配置,即使在可信内网中,也建议使用该方式!
docker 为 tls 提供两种模式
- daemon 模式:docker daemon 只接收认证客户端的请求。
- 客户端模式:docker 客户端只接收认证的 daemon 发起的请求。
同时使用它们,能提供最高的安全等级。
下面开始介绍如何完成 tls 的配置,总体步骤如下。
- 创建 ca 。
- 为 daemon 创建密钥对。
- 为客户端创建密钥对。
- 分发密钥
- docker 配置 tls 模式

创建 ca
在 node2 运行下面的命令。
- 为 ca 创建私钥(过程中需要设置密码)
$ openssl genrsa -aes256 -out ca-key.pem 4096
当前目录新增一个 ca-key.pem 文件,这是 ca 私钥。
- 用 ca 私钥生成公钥(过程需要输入之前的密码)
$ openssl req -new -x509 -days 730 -key ca-key.pem -sha256 -out ca.pem
当前目录新增一个 ca.pem 文件,这是 ca 公钥,也叫”证书“。
为 daemon 创建密钥对
在 node3 运行下面的命令。
- 为 daemon 创建私钥。
$ openssl genrsa -out daemon-key.pem 4096
当前目录新增一个 daemon-key.pem 文件,这是 daemon 节点的私钥。
- 创建证书签名请求并发送到 ca。
$ openssl req -subj "/cn=daemon" \ -sha256 -new -key daemon-key.pem -out daemon.csr
当前目录新增一个 daemon.csr 文件,这是 csr。
为证书添加属性。 创建文件,名为 extfile.cnf。示例中使用了 daemon 节点的 dns 名称和 ip。每个人的环境中可能值不同。
$ subjectaltname = dns:daemon,ip:192.168.57.3 extendedkeyusage = serverauth
- 生成证书 使用 csr 文件、ca 密钥、extfile.cnf 文件完成签名和 daemon 证书配置。
$ openssl x509 -req -days 730 -sha256 \ -in daemon.csr -ca ca.pem -cakey ca-key.pem \ -cacreateserial -out daemon-cert.pem -extfile extfile.cnf
此时,已经拥有一个可用 ca ,同时 daemon 的 node3 节点也有了自己的密钥。
继续下面内容前,删除 csr 和 extfile.cnf。
$ rm daemon.csr extfile.cnf
为客户端创建密钥对
在 node3 运行下面的命令。
为客户端创建密钥
$ openssl genrsa -out client-key.pem 4096
当前目录新增一个 client-key.pem 文件。
创建 csr。
$ openssl req -subj '/cn=client' -new -key client-key.pem -out client.csr
当前目录新增一个 client.csr 文件。
创建 extfile.cnf 文件 将证书设置为客户端认证可用。文件内容如下。
extendedkeyusage = clientauth
生成证书 使用 csr 文件、ca 密钥、extfile.cnf 文件完成签名和客户端证书配置。
$ openssl x509 -req -days 730 -sha256 \ -in client.csr -ca ca.pem -cakey ca-key.pem \ -cacreateserial -out client-cert.pem -extfile extfile.cnf
删除 csr 和 extfile.cnf ,因为不会用到它们了。 $ rm client.csr extfile.cnf
此时,在工作目录下应该有如下 7 个文件。
ca-key.pem ca.pem ca.srl client-cert.pem client-key.pem daemon-cert.pem daemon-key.pem
分发密钥
- 从 ca (刚才证书生成的 node) 复制 ca.pem、daemon-cert.pem、daemon-key.pem 到 node3(daemon 节点)。
- 从 ca (刚才证书生成的 node) 复制 ca.pem、client-cert.pem、client-key.pem 到 node1(客户端节点)。
这里用 scp 完成复制操作。在 scp 的过程中对部分文件进行了重命名。重命名非常重要,因为 docker 对文件命名有规范。
// daemon files $ scp ./ca.pem ubuntu@daemon:/home/ubuntu/.docker/ca.pem $ scp ./daemon-cert.pem ubuntu@daemon:/home/ubuntu/.docker/cert.pem $ scp ./daemon-key.pem ubuntu@daemon:/home/ubuntu/.docker/key.pem // client files $ scp ./ca.pem ubuntu@client:/home/ubuntu/.docker/ca.pem $ scp ./client-cert.pem ubuntu@client:/home/ubuntu/.docker/cert.pem $ scp ./client-key.pem ubuntu@client:/home/ubuntu/.docker/key.pem
docker 配置 tls 模式
进入 node3(daemon 节点)完成下面的配置。
找到 daemon.json 配置文件。在 linux 上位于 /etc/docker,编辑 daemon.json 文件,添加如下行。
"tls": true, "tlsverify": true, "tlscacert": "/home/ubuntu/.docker/ca.pem", "tlscert": "/home/ubuntu/.docker/cert.pem", "tlskey": "/home/ubuntu/.docker/key.pem", "hosts": ["tcp://你的 daemon 的ip:2376"]
这些 daemon.json 中的参数意义如下。
- tlsverify :开启 tls 认证。
- tlscacert :指定daemon可信任的 ca。
- tlscert :向 docker 指定 daemon 证书的位置。
- tlskey :向 docker 指定daemon私钥的位置。
- hosts :向 docker 指定需要绑定 daemon 的具体 socket。
警告:部分版本的 linux 系统运行 systemd 的,不允许在 daemon.json 中使用“hosts”选项。替换方案是在 systemd 配置文件中进行重写。创建名为 /etc/systemd/system/docker.service.d/override.conf 的新文件。在其中加入下列 3 行内容,然后保存。
[service] execstart= execstart=/usr/bin/dockerd -h tcp://你的 daemon 的ip:2376”
重启 daemon 。
$ systemctl daemon-reload $ systemctl restart docker.service
如果重启失败且错误为
docker.service: main process exited, code=exited, status=1/failure
为了让它工作,编辑 /lib/systemd/system/docker.service,修改如下内容之后再次尝试重启。
# 修改前: execstart=/usr/bin/dockerd -h fd:// --containerd=/run/containerd/containerd.sock # 修改后: execstart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock
理论上,/etc/systemd/system/docker.service.d/override.conf 与 /etc/docker/daemon.json 可以同时修改,但是并不建议这么做,如果仅修改 /etc/docker/daemon.json 没有出现任何问题,那就太棒了。
进入 docker 客户端节点,配置临时环境变量。
$ export docker_host=tcp://你的 daemon ip 地址:2376
尝试运行 $ docker version,会出现错误,类似无法连接 daemon。接着设置另一个环境变量。
$ export docker_tls_verify=1
它是告知 docker 客户端使用证书对全部命令进行签名,此时再试试 $ docker version!
🎉 恭喜。你成功完成了客户端与 daemon 完成安全的通信。
以上就是docker开启远程连接并实现安全通信详解的详细内容,更多关于docker远程连接安全通信的资料请关注代码网其它相关文章!
发表评论