10

Portainer 使用 TLS 加密连接远端节点上的 Docker

 3 years ago
source link: http://i.lckiss.com/?p=7064
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Portainer 使用 TLS 加密连接远端节点上的 Docker

2021-06-26

其实这东西本身不是一件麻烦事,但是 MacOS 硬是给搞成了麻烦事。

Docker 环境分布:Mac 上一个 Docker,树莓派上一个 Docker。

需求:将树莓派上的 Docker 以 Endpoint 的形式添加到 Mac 端的 Portainer 中进行统一管理。

此方法适用于局域网内部,或者仅个人使用的网络环境中。主要步骤就是在需要被管理的主机中将启动命令追加上一个端口暴露,拿我自己举例。

1. 登录树莓派,编辑 Docker 启动命令:

vi /usr/lib/systemd/system/docker.service

2. 找到 ExecStart 字段:

#默认
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

改为(追加 -H tcp://0.0.0.0:2376 ):

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock

3. 重启 docker :

systemctl daemon-reload && systemctl restart docker

至此树莓派的修改结束.

随后在 MacOS 上登录 Portainer ,并找到 Endpoints 选项,点击 Add endpoint

然后给命个名,这个 host 和 ip 选一个填了就行,我这里是内网,host 和 ip 在路由做了关联,为了方便我是两者都填了,如果这个 Portainer 和 远端的 docker 在同一个网段 则点击连接即可,很可惜我不是,所以需要特殊处理,后面【使用 extra_hosts 字段配置网络】部分再说。

TLS 连接

对于内网,其实可以随意暴露不必管连接是否加密,但对于外网,不加密的连接就等于将主机送给别人。但 Docker 的 TLS 及其繁琐。需要一系列的证书、私钥生成,在 Mac 上或者 Linux 上生成都可,Windows 默认应该是不行(我没试过)。

服务器证书

  • 新建一个目录,因为生成的文件太多了
mkdir tls
  • 生成根证书 RSA 私钥,过程中需要设置密码,待会儿需要用到,不要忘记。
openssl genrsa -aes256 -out ca-key.pem 4096
  • 生成 ca 证书(这里指定证书有效期365天,授权的 HOST 指定为 * ,以自己的根证书私钥签发的证书,也就是自己给自己签发证书)ca 证书主要作用之一就是做 host 认证,如果是外网环境,需要填好 HOST。
 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem 
  • 生成服务器私钥
openssl genrsa -out server-key.pem 4096

此时目录结构为:

openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
  • 生成服务器证书
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
out:
 Signature ok
 subject=/CN=*
 Getting CA Private Key
 Enter pass phrase for ca-key.pem: 

服务器的证书告一段落,依次为根证书私钥、ca 证书、服务器证书私钥、服务器证书

客户端证书

  • 生成客户端根证书私钥
openssl genrsa -out key.pem 4096
  • 生成客户端证书请求(默认 host 为 client )
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
  • 使用最开始的 ca 证书来生成客户端证书(需要配置密码)
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem
  • 删除无用文件
rm -v client.csr server.csr

密钥生成完了,主要是生成了这两个文件:

2021062615581920.png

Docker TLS 证书配置

将下列文件上传 docker 主机(我这里指树莓派)的 root 目录

2021062615201776.png

1. 配置 docker 启动文件,附带上 TLS 相关证书配置

vi /usr/lib/systemd/system/docker.service

2. 找到 ExecStart 字段:

#默认
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/root/tls/ca.pem --tlscert=/root/tls/server-cert.pem --tlskey=/root/tls/server-key.pem -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock

也就是追加了这部分:

--tlsverify --tlscacert=/root/tls/ca.pem --tlscert=/root/tls/server-cert.pem --tlskey=/root/tls/server-key.pem -H tcp://0.0.0.0:2376

3. 重启 docker :

systemctl daemon-reload && systemctl restart docker

随后在 MacOS 上登录 Portainer ,并找到 Endpoints 选项,点击 Add endpoint。与普通连接不同的是,需要开启 TLS,然后添加即可。

至于这里我为什么不选择 TLS with server and client verification 的原因是: ca 证书签署的 HOST 写的 * ,和我 Mac 的 HOST 是不同的,我也没对这台 Mac 做 DNS 路由配置,所以就只选了 client 验证,客户端证书是 ca 证书签署的,所以连接是正常的,当然这里指 Portainer 和 远端的 docker 在同一个网段,如果不是,往下看。

2021062615355023-1024x713.png

使用 extra_hosts 字段配置网络

上面两种方式都是到添加 Endpoint 就点到为止。但实际过程中,不会这么一帆风顺,因为一般情况下不会有谁的容器和另一台主机的 docker 是在同一网段的。像我:

2021062615480797.png
2021062615482377.png

要解决这个问题,一般粗暴一点的做法是,将 Portainer 的容器网络配置为 host 模式,或者 macvlan 模式来让其直接暴露在主机网络。但说到这里就很气愤,对于 Mac 上的 network 配置几乎是摆设,不论是 host 还是 macvlan 都无法访问,host 模式的问题原因我没找到,macvlan 模式参考 https://github.com/docker/for-mac/issues/3926,总之就是目前没解。

在没找到解决方案的情况下,我去翻了下官方文档,找到了一个字段 extra_hosts ,官方文档:https://docs.docker.com/compose/compose-file/compose-file-v3/#extra_hosts

最后将 Portainer 加上了这个字段,再进行连接便可以连接成功,也不需要修改原有网络模式。

2021062615502417.png

最后上图:

2021062616214787.png

整个过程非常的繁琐,因为 TLS 本身就是一件很繁琐的事,想了解的可以去看看 阮一峰 – SSL/TLS协议运行机制的概述

官方文档:

https://docs.docker.com/engine/security/protect-access/

https://documentation.portainer.io/v2.0/endpoints/docker/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK