使用证书验证仓库客户端

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

本文演示了如何确保Docker注册表服务器和Docker守护进程(注册表服务器的客户端)之间的流量是加密的,并使用基于证书的客户端-服务器身份验证进行适当的身份验证。

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

理解配置

通过在与注册表主机名相同的名称下创建目录来配置自定义证书,例如localhost。所有*.crt文件都作为CA根添加到该目录中。

注意

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

存在一个或多个.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