
1. 为什么需要配置Harbor HTTPS最近在帮客户部署Harbor私有镜像仓库时遇到了一个典型问题当Harbor前面有Nginx反向代理时通过域名推送镜像总是失败。这个问题困扰了我整整两天最后发现是HTTPS配置的问题。今天我就把这个踩坑经历完整分享出来帮你少走弯路。先说说问题现象通过docker login登录时一切正常但执行docker push推送镜像时却提示没有权限。仔细排查后发现这是因为登录走的是80端口而推送镜像必须走443端口。更奇怪的是通过IP地址推送可以成功但通过域名就不行。这种一半成功一半失败的情况特别容易让人抓狂。其实核心原因很简单Harbor默认安装后只开启HTTP服务而Docker客户端在推送镜像时强制要求HTTPS安全连接除非你明确配置信任不安全仓库。当Nginx代理层和Harbor之间的HTTPS配置不完整时就会出现这种薛定谔的推送现象。2. 证书准备与Harbor配置2.1 获取SSL证书HTTPS配置的第一步当然是准备证书。你可以选择向正规CA机构购买证书使用Lets Encrypt免费证书自签名证书仅限测试环境我以自签名证书为例生产环境请务必使用可信证书用OpenSSL生成证书mkdir -p /srv/cert openssl req -newkey rsa:4096 -nodes -sha256 \ -keyout /srv/cert/harbor.example.com.key \ -x509 -days 3650 \ -out /srv/cert/harbor.example.com.crt \ -subj /CNharbor.example.com生成后记得检查证书信息openssl x509 -in /srv/cert/harbor.example.com.crt -noout -text2.2 修改Harbor配置文件关键配置都在harbor.yml中。找到https相关配置段修改如下# https相关配置 https: port: 443 certificate: /srv/cert/harbor.example.com.crt private_key: /srv/cert/harbor.example.com.key # 必须设置external_url为HTTPS地址 external_url: https://harbor.example.com这里有个大坑external_url必须与证书的CN名称完全一致。比如证书CN是harbor.example.comexternal_url就不能用IP或其他域名否则浏览器会报证书错误。3. Nginx代理配置技巧3.1 基础代理配置在Nginx配置文件中添加如下内容server { listen 443 ssl; server_name harbor.example.com; ssl_certificate /srv/cert/harbor.example.com.crt; ssl_certificate_key /srv/cert/harbor.example.com.key; location / { proxy_pass http://harbor-host:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }3.2 常见代理问题排查如果Nginx容器一直重启很可能是证书路径问题。检查方法docker inspect nginx | grep -A 5 Mounts如果发现证书目录为空可以用rsync同步证书rsync -avP /srv/cert/ userharbor-host:/srv/cert/另一个常见问题是HTTP/HTTPS混合访问导致的跨协议错误。解决方法是在Harbor的Nginx配置中添加重定向server { listen 80; server_name harbor.example.com; return 301 https://$host$request_uri; }4. Docker客户端配置4.1 信任自签名证书对于自签名证书需要在每台Docker主机上配置信任mkdir -p /etc/docker/certs.d/harbor.example.com scp /srv/cert/harbor.example.com.crt /etc/docker/certs.d/harbor.example.com/ca.crt systemctl restart docker4.2 配置daemon.json如果还是无法推送可能需要修改/etc/docker/daemon.json{ insecure-registries: [harbor.example.com], registry-mirrors: [] }注意生产环境不建议使用insecure-registries正确的做法是配置完整的证书信任链。5. 完整部署流程验证5.1 重新部署Harbor配置修改后需要重新部署# 重新生成配置 ./prepare --with-clair --with-chartmuseum # 重启服务 docker-compose down docker-compose up -d5.2 端到端测试验证步骤登录测试docker login harbor.example.com推送测试docker pull alpine docker tag alpine harbor.example.com/library/alpine docker push harbor.example.com/library/alpine拉取测试docker rmi harbor.example.com/library/alpine docker pull harbor.example.com/library/alpine如果以上步骤都能成功说明HTTPS配置完全正确。我在实际项目中发现有时候即使配置正确浏览器缓存或Docker客户端缓存也可能导致问题。这时候可以尝试清除缓存或重启相关服务。