You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拉取镜像时远程Docker Engine的TLS验证异常求助

问题:Docker TLS配置下拉取私有镜像失败,报错未收到客户端证书

在Ubuntu虚拟机搭建了启用TLS的私有Docker Engine,证书配置完成后,通过openssl命令和带客户端证书的Docker CLI能正常连接、列出镜像、创建镜像,但拉取镜像时失败,Docker Engine日志报错“tls: client didn't provide a certificate”,该问题在Ubuntu虚拟机和Windows机器上均出现。

Docker Engine运行状态

ubuntu@worker-docker-node:~$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/docker.service.d
             └─override.conf
     Active: active (running) since Tue 2024-03-05 08:20:49 SAST; 1 day 3h ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 24598 (dockerd)
      Tasks: 9
     Memory: 238.2M
        CPU: 12.925s
     CGroup: /system.slice/docker.service
             └─24598 /usr/bin/dockerd -D -H unix:///var/run/docker.sock --tlsverify --tlscert=/home/ubuntu/.docker/server-cert.pem --tlscacert=/home/ubuntu/.docker/ca.pem --tlskey=/home/ubuntu/.docker/server-key.pem -H tcp://0.0.0.0:2376

验证连接用的openssl命令

openssl s_client -connect worker-docker-node:2376 -cert cert.pem -key key.pem -CAfile ca.pem

拉取镜像后的Docker Engine日志

Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.541141069+02:00" level=debug msg="Calling HEAD /_ping"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.542081072+02:00" level=debug msg="Calling POST /v1.42/images/create?fromImage=worker-docker-node%3A2376%2Ftestimage&tag=2.4.0.1001"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.544068477+02:00" level=debug msg="Trying to pull worker-docker-node:2376/testimage from https://worker-docker-node:2376"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: 2024/03/06 11:53:23 http: TLS handshake error from 127.0.0.1:33794: tls: client didn't provide a certificate
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.546664284+02:00" level=warning msg="Error getting v2 registry: Get \"https://worker-docker-node:2376/v2/\": remote error: tls: bad certificate"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.546676984+02:00" level=info msg="Attempting next endpoint for pull after error: Get \"https://worker-docker-node:2376/v2/\": remote error: tls: bad certificate"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.546684584+02:00" level=debug msg="Trying to pull worker-docker-node:2376/testimage from http://worker-docker-node:2376"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.548224588+02:00" level=info msg="Attempting next endpoint for pull after error: read tcp 127.0.0.1:33818->127.0.1.1:2376: read: connection reset by peer"
Mar 06 11:53:23 worker-docker-node dockerd[24598]: time="2024-03-06T11:53:23.549488492+02:00" level=error msg="Handler for POST /v1.42/images/create returned error: read tcp 127.0.0.1:33818->127.0.1.1:2376: read: connection reset by peer"

拉取镜像命令

docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=worker-docker-node:2376 image pull worker-docker-node:2376/testimage:2.4.0.1001

已尝试的操作:

  • 将证书放入本地.docker目录,不通过CLI指定证书,可识别证书但问题依旧
  • 使用Java Docker Client SDK测试,能正常列出、创建镜像,但拉取镜像同样失败

推测Docker对不同API调用的TLS验证处理逻辑不同,求解决方法。


解决方案

问题根源

从日志能看到,拉取镜像时Docker Engine会自己作为客户端去访问本地的Registry服务(请求来自127.0.0.1),但这部分内部请求没有携带TLS客户端证书,导致握手失败。因为你的Docker Engine同时充当了Registry服务,而dockerd启动时配置了--tlsverify,要求所有连接都必须提供合法的客户端证书,包括它自己发起的内部请求。

修复步骤

  1. 修改Docker Engine启动参数,添加--insecure-registry worker-docker-node:2376,允许对本地Registry的内部请求跳过TLS验证(仅针对内部请求,外部连接仍保持强制TLS验证):
    • 编辑Docker的override配置文件:
      sudo nano /etc/systemd/system/docker.service.d/override.conf
      
    • 在ExecStart行末尾添加参数,修改后如下:
      ExecStart=/usr/bin/dockerd -D -H unix:///var/run/docker.sock --tlsverify --tlscert=/home/ubuntu/.docker/server-cert.pem --tlscacert=/home/ubuntu/.docker/ca.pem --tlskey=/home/ubuntu/.docker/server-key.pem -H tcp://0.0.0.0:2376 --insecure-registry worker-docker-node:2376
      
  2. 重新加载systemd配置并重启Docker服务:
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  3. 重新尝试拉取镜像:使用之前的拉取命令即可正常操作。

替代方案(更安全)

如果不想使用--insecure-registry,可以为Docker Engine的内部请求配置默认的客户端证书:

  • 创建/etc/docker/daemon.json文件(若不存在),添加以下内容:
    {
      "tls": true,
      "tlscacert": "/home/ubuntu/.docker/ca.pem",
      "tlscert": "/home/ubuntu/.docker/server-cert.pem",
      "tlskey": "/home/ubuntu/.docker/server-key.pem",
      "tlsverify": true
    }
    
  • 此配置会让Docker Engine作为客户端访问Registry时自动携带证书,同时保留外部连接的TLS验证要求。之后同样需要重启Docker服务。

内容的提问来源于stack exchange,提问作者Gene Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:24:58