Docker开启TLS远程连接
一、Docker远程连接
Docker是C/S架构,通过docker的客户端连接到docker daemon,然后由docker daemon在宿主机上执行构建镜像,运行容器等指令。
Docker支持多种方式将docker客户端连接到server。如果docker客户端和server都在同一台宿主机上,那么可以直接使用Unix域套接字文件/var/run/docker.sock
连接,我们直接使用docker命令时实际上就是采用这种方式进行连接的。
Docker也支持远程通过socket进行连接,可以选择开启或者不开启TLS,为了安全我们大多数时候还是采用开启TLS的方式进行远程连接。
二、启动远程连接的过程
首先需要保证宿主机上docker daemon已安装,安装过程可查看官网
制作证书
首先需要制作证书,包括服务端证书,和客户端证书。
在docker daemon的宿主机上按步骤执行下列命令:
-
创建根证书RSA私钥 命令输入后会提示输入密码,输入两次后会生成ca-key.pem文件。
$ openssl genrsa -aes256 -out ca-key.pem 4096
-
用这个RSA密钥创建CA证书
自己给自己签发证书,也可以交给第三方机构签发。这里我们自己签发。
-days
参数指定多少天后过期,这里设置1000天。这一步会生成ca.pem文件,就是CA证书。$ openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
-
创建服务端私钥
这一步生成的server-key.pem就是服务端私钥。
$ openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
-
生成服务端证书签名请求csr文件
csr(certificate signing request),里面包含公钥和服务端信息。这一步会生成server.csr文件,就是服务端证书。
$ openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
-
生成签名过的服务端证书
服务端证书需要签名,这一步生成的server-cert.pem文件就是签名过的服务端证书
$ openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
-
生成客户端私钥
接下来我们生成客户端的私钥key.pem
$ openssl genrsa -out key.pem 4096
-
生成客户端证书签名请求
生成的client.csr文件就是客户端签名请求
$ openssl req -subj "/CN=client" -new -key key.pem -out client.csr
-
生成exfile.cnf配置文件
$ echo extendedKeyUsage=clientAuth > extfile.cnf
-
生成签名过的客户端证书
期间要输入密码,生成的cert.pem就是签名过的客户端证书
$ openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
-
最后删除多余的中间文件
$ rm -rf ca.srl client.csr extfile.cnf server.csr
剩下的文件都是我们需要的:
- ca.pem:CA机构证书
- ca-key.pem:根证书RSA私钥
- cert.pem:客户端证书
- key.pem:客户端私钥
- server-cert.pem:服务端证书
- server-key.pem:服务端私钥
服务端设置
证书生成完成后,需要对docker daemon进行设置让它允许远程TLS访问。
-
首先打开打开
/lib/systemd/system/docker.service
文件,找到这行内容:ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
把这行替换为以下格式:
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/ca.pem --tlscert=/server-cert.pem --tlskey=/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
注意几个参数指定的文件的位置:
- –tlscacert:CA根证书
- –tlscert:服务端证书
- –tlskey:服务端私钥
-H
参数指定了访问方式,这里设置了开启远程连接,端口为2376,并且依然支持Unix域套接字连接(即本地直接连接) -
然后如果我们的机器没有放通2376端口,需要放通一下:
$ sudo iptables -I INPUT -p tcp --dport 2376-j ACCEPT
-
最后重启docker daemon让配置生效
$ systemctl daemon-reload && systemctl restart docker
没报错就说明配置成功了
客户端远程连接
完成上述的配置后,服务端的docker daemon就支持TLS远程连接了。客户端只需要在连接时指定一些参数就可以连接到远程的docker daemon上。
-
首先把在服务端创建的三个文件ca.pem,cert.pem和key.pem复制到客户端机器上。
-
然后我们给服务端ip设置个域名
在
/etc/hosts
文件中添加一行,前面的服务端ip,后面是它的域名。192.168.121.138 docker-daemon
-
然后就可以进行连接了。
指定客户端的三个文件(这里假设都在
/root/work/
目录下),通过-H指定服务端的地址$ docker --tlsverify --tlscacert=/root/work/ca.pem --tlscert=/root/work/cert.pem --tlskey=/root/work/key.pem -H tcp://docker-daemon:2376 version
可以看到客户端和服务端的版本,其他命令也都是可以的。
还可以把几个证书文件拷贝到
~/.docker/
目录下,这样在连接时就可以不指定–tlscacert、–tlscert和–tlskey这几个参数了,docker client会自动加载这几个文件的。$ docker --tlsverify -H=tcp://docker-daemon:2376 version