使用证书验证仓库客户端

通过 HTTPS 运行 Docker中,您了解到默认情况下, Docker 通过非网络化的 Unix 套接字运行,必须启用 TLS 才能使 Docker 客户端和守护进程通过 HTTPS 安全通信。TLS 确保注册表端点的真实性,并对往返于注册表的流量进行加密。

本文演示了如何使用基于证书的客户机-服务器身份验证,确保 Docker 注册表服务器与 Docker 守护进程(注册表服务器的客户机)之间的流量经过加密并得到正确认证。

我们将指导您如何为注册表安装证书颁发机构 (CA) 根证书,以及如何设置客户端 TLS 证书以进行验证。

了解配置

自定义证书通过在使用与注册表主机名相同的名称(例如 localhost)在 /etc/docker/certs.d下创建目录来配置。所有 *.crt 文件均作为 CA 根证书添加到该目录中。

注意

在 Linux 上,任何根证书颁发机构都会与系统默认设置合并,包括主机的根 CA 集。如果您在 Windows Server 上运行 Docker,或者在带有 Windows 容器的 Docker Desktop for Windows 上运行,则仅在未配置自定义根证书时才使用系统默认证书。

存在一个或多个 <filename>.key/cert 对表示 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 的 genrsareq 命令首先生成 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