使用证书验证仓库客户端
在 使用 HTTPS 运行 Docker 中,你了解到 Docker 默认通过非网络化的 Unix Socket 运行,必须启用 TLS 才能让 Docker 客户端和守护进程通过 HTTPS 安全地通信。TLS 确保仓库端点的真实性,并对进出仓库的流量进行加密。
本文演示了如何使用基于证书的客户端-服务器身份验证来确保 Docker 仓库服务器与 Docker 守护进程(即仓库服务器的客户端)之间的流量经过加密并得到适当验证。
我们将向你展示如何安装仓库的证书颁发机构 (CA) 根证书,以及如何设置客户端 TLS 证书进行验证。
理解配置
自定义证书的配置方式是在 /etc/docker/certs.d
目录下创建一个与仓库主机名相同的目录,例如 localhost
。所有 *.crt
文件都被添加到此目录中作为 CA 根证书。
注意
在 Linux 上,任何根证书颁发机构都会与系统默认设置合并,包括主机的根 CA 集。如果你在 Windows Server 上运行 Docker,或在 Docker Desktop for Windows 上使用 Windows 容器,系统默认证书仅在未配置自定义根证书时使用。
存在一个或多个 <filename>.key/cert
对表明 Docker 访问所需仓库需要自定义证书。
注意
如果存在多个证书,Docker 将按字母顺序逐个尝试。如果出现 4xx 或 5xx 级别的身份验证错误,Docker 会继续尝试下一个证书。
下图展示了使用自定义证书的配置
/etc/docker/certs.d/ <-- Certificate directory
└── localhost:5000 <-- Hostname:port
├── client.cert <-- Client certificate
├── client.key <-- Client key
└── ca.crt <-- Root CA that signed
the registry certificate, in PEM
上述示例是操作系统特定的,仅用于说明目的。你应该查阅操作系统文档,了解如何创建由操作系统提供的捆绑证书链。
创建客户端证书
使用 OpenSSL 的 genrsa
和 req
命令首先生成 RSA 密钥,然后使用该密钥创建证书。
$ openssl genrsa -out client.key 4096
$ openssl req -new -x509 -text -key client.key -out client.cert
注意
这些 TLS 命令仅在 Linux 上生成有效的证书集。macOS 中的 OpenSSL 版本与 Docker 所需的证书类型不兼容。
故障排除技巧
Docker 守护进程将 .crt
文件解释为 CA 证书,将 .cert
文件解释为客户端证书。如果 CA 证书被误赋予 .cert
扩展名而不是正确的 .crt
扩展名,Docker 守护进程将记录以下错误消息:
Missing key KEY_NAME for client certificate CERT_NAME. CA certificates should use the extension .crt.
如果访问 Docker 仓库时不带端口号,请勿将端口添加到目录名称中。以下示例显示了默认端口 443 上的仓库配置,该仓库可通过 docker login my-https.registry.example.com
访问:
/etc/docker/certs.d/
└── my-https.registry.example.com <-- Hostname without port
├── client.cert
├── client.key
└── ca.crt