Docker Registry配置Let's Encrypt报错:无法确定求解器,求解决方案
这个错误我之前帮几个用户排查过,核心原因是Acme客户端没法确定用哪种域名验证方式(solver)来完成Let's Encrypt的证书签发流程。结合你用RancherOS+DigitalOcean的环境,给你几个针对性的解决步骤:
RancherOS上的Docker Registry通常通过/etc/docker/registry/config.yml配置,出现Could not determine solvers报错,大概率是你的acme段没明确指定验证方式。
正确的配置应该包含solvers字段,比如用HTTP-01挑战(最常用的方式),配置示例如下:
version: 0.1 log: fields: service: registry storage: delete: enabled: true cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry http: addr: :443 tls: certificate: /var/lib/registry/certs/fullchain.pem key: /var/lib/registry/certs/privkey.pem acme: email: your-email@example.com # 替换成你的邮箱,用于证书到期提醒 storage: /var/lib/registry/acme.json keytype: rsa4096 solvers: - http-01: http: port: 80 # HTTP-01挑战需要占用80端口
HTTP-01挑战需要Let's Encrypt的服务器能访问http://docker.example.com/.well-known/acme-challenge/路径,所以必须满足:
- 容器端口映射:运行Registry容器时,要把容器的80端口映射到主机的80端口,比如启动命令里加
-p 80:80 -p 443:443 - RancherOS主机防火墙:开放80和443端口,执行以下命令:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT - DigitalOcean云防火墙:在DO控制台的防火墙规则里,添加TCP 80和443的入站允许规则,否则外部无法访问。
如果你的服务器80端口被其他服务占用,或者不想暴露80端口,DNS-01挑战是更好的选择——毕竟你的域名是用DO的DNS解析的,可以直接用DO的API自动完成TXT记录验证。
修改Registry的acme配置为:
acme: email: your-email@example.com storage: /var/lib/registry/acme.json keytype: rsa4096 solvers: - dns-01: digitalocean: token: "your-digitalocean-api-token" # 替换成你的DO API令牌,需要有DNS编辑权限
注意:API令牌要妥善保管,不要泄露。启动容器时确保容器能访问外部网络(RancherOS默认是允许的)。
如果Registry自带的Acme客户端一直出问题,不如直接用Certbot手动申请证书,再挂载到容器里:
用Docker运行Certbot申请证书(RancherOS本身是轻量系统,直接用容器更方便):
docker run -it --rm \ -v "/etc/letsencrypt:/etc/letsencrypt" \ -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ certbot/certbot certonly --standalone -d docker.example.com执行时会临时占用80端口,所以要先停止占用80的服务。
修改Registry配置,直接指定SSL证书路径:
http: addr: :443 tls: certificate: /etc/letsencrypt/live/docker.example.com/fullchain.pem key: /etc/letsencrypt/live/docker.example.com/privkey.pem启动Registry容器时挂载证书目录:
docker run -d -p 443:443 \ -v /etc/docker/registry/config.yml:/etc/docker/registry/config.yml \ -v /etc/letsencrypt:/etc/letsencrypt \ -v /var/lib/registry:/var/lib/registry \ registry:latest设置自动续签:在RancherOS上添加crontab定时任务,每天凌晨续签证书并重启Registry:
# 编辑crontab sudo crontab -e # 添加以下内容 0 2 * * * docker run -it --rm -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot renew --quiet && docker restart registry
不管用哪种方式,配置完成后重启Registry容器,然后查看日志确认是否成功:
docker logs registry
如果日志里出现acme: Obtained new certificate之类的信息,就说明证书申请成功了,此时可以用curl https://docker.example.com/v2/测试是否能正常访问。
内容的提问来源于stack exchange,提问作者Steve

