推送大型Docker镜像至私有仓库反复重试无法完成问题求助
私有Docker Registry推送大镜像中断问题排查与解决
问题现象
推送3.905GB的Docker镜像至私有Registry时,进度推进到约2.3GB时必中断,随后持续重试无法完成推送。推送日志如下:
b09ec9b220b5: Pushing [=======================> ] 1.871GB/3.905GB // always interrupted when reached around 2.3GB/3.905GB 935138875f7e: Layer already exists 844a98711e4c: Layer already exists f11fbff78593: Layer already exists cfe955540946: Layer already exists 0e9af88280bb: Layer already exists 08de5656e13a: Layer already exists 5f70bf18a086: Layer already exists 03825ee9b44a: Layer already exists 407fdf993b55: Layer already exists 315572e6ad81: Layer already exists 44dda8402940: Layer already exists 25972ffba58c: Layer already exists dc6462f7bb8b: Layer already exists a4db1a405763: Layer already exists 9f4f964da727: Layer already exists 49b333f7bad4: Layer already exists a463dbda4664: Layer already exists a9099c3159f5: Layer already exists
不同环境表现有差异:
- 本地MacOS环境推送:无限重试,无法完成
- Registry同服务器的Jenkins推送:重试约5次后出现500错误
Registry容器日志无任何报错信息。
环境配置
Traefik docker.yml配置
version: '3.6' services: traefik: image: traefik:2.9.6 command: # - '--log.level=DEBUG' - '--api=true' - '--api.dashboard=true' - '--providers.docker.endpoint=unix:///var/run/docker.sock' - '--providers.docker.swarmMode=true' - '--providers.docker.exposedbydefault=false' - '--providers.docker.network=traefik-proxy' - '--entrypoints.web.address=:80' - '--entrypoints.websecure.address=:443' - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true' - '--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web' - '--certificatesresolvers.letsencryptresolver.acme.email=developer@domain.com' - '--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json' ports: - "80:80" - "443:443" volumes: - acme-certs:/letsencrypt - /var/run/docker.sock:/var/run/docker.sock:ro networks: - traefik-proxy deploy: placement: constraints: - node.role == manager labels: - 'traefik.enable=true' # HTTP Catchall for redirecting HTTP -> HTTPS - 'traefik.http.routers.http-catchall.rule=PathPrefix(`/`)' - 'traefik.http.routers.http-catchall.entrypoints=web' - 'traefik.http.routers.http-catchall.middlewares=redirect-to-https' - 'traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https' # Traefik dashboard - 'traefik.http.routers.traefik.rule=Host(`traefik.domain.com`)' - 'traefik.http.routers.traefik.entrypoints=websecure' - 'traefik.http.routers.traefik.tls.certresolver=letsencryptresolver' - 'traefik.http.routers.traefik.service=api@internal' - 'traefik.http.services.api@internal.loadbalancer.server.port=8080' - 'traefik.http.routers.traefik.middlewares=traefik-auth' - 'traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$2y$$10$$OwPg6oWN2iJk5Syde7yIt.tKebbZwtQkaPQ.0AaaaFjNIb1h8bJ6a' resources: limits: memory: "512M" volumes: acme-certs: networks: traefik-proxy: external: true
Registry docker.yml配置
version: '3.4' services: registry: image: registry:2.8.1 ports: - "5000:5000" environment: - REGISTRY_AUTH=htpasswd - REGISTRY_STORAGE_DELETE_ENABLED=true - REGISTRY_AUTH_HTPASSWD_PATH=/httpasswd_storage/htpasswd - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm volumes: - ./htpasswd_backup:/httpasswd_storage - registry-data:/var/lib/registry networks: - traefik-proxy - registry-ui-net deploy: labels: - 'traefik.enable=true' - 'traefik.docker.network=traefik-proxy' - "traefik.http.routers.registry.rule=Host(`registry1.domain.com`)" - 'traefik.http.routers.registry.entrypoints=websecure' - 'traefik.http.routers.registry.tls.certresolver=letsencryptresolver' - 'traefik.http.services.registry.loadbalancer.server.port=5000' networks: traefik-proxy: external: true registry-ui-net: volumes: registry-data:
排查与解决方法
1. 调整Traefik超时设置
Traefik默认请求超时不足以支撑大文件推送,需在Traefik的command中添加超时参数:
- '--entrypoints.websecure.http.timeout.requestTimeout=300s' - '--entrypoints.websecure.http.timeout.idleTimeout=300s' - '--entrypoints.websecure.http.timeout.dialTimeout=300s'
将超时时间延长至5分钟,适配大镜像推送的耗时需求。
2. 检查Registry存储状态
确认Registry存储目录权限正常,且所在磁盘剩余空间至少为镜像大小的2倍(用于临时文件处理),执行以下命令检查:
docker exec -it <registry-container-id> df -h /var/lib/registry
3. 启用Traefik Debug日志
取消Traefik配置中# - '--log.level=DEBUG'的注释,重新部署后查看日志定位异常:
docker service logs -f traefik_traefik
重点关注推送中断时的连接重置、超时类日志信息。
4. 绕过Traefik直接推送测试
在Jenkins服务器上直接通过Registry的5000端口推送镜像,排除Traefik的影响:
docker push localhost:5000/<your-image>:<tag>
若直接推送成功,问题出在Traefik配置或网络转发;若仍失败,需排查Registry本身或服务器资源限制。
5. 检查Docker Swarm网络MTU
确认traefik-proxy overlay网络的MTU设置合理,避免大数据包分片丢失:
docker network inspect traefik-proxy
若MTU过小,重新创建网络时指定适配服务器的MTU值:
docker network create --driver overlay --opt com.docker.network.driver.mtu=1450 traefik-proxy
6. 调整Registry HTTP超时
在Registry的环境变量中添加超时配置,延长请求处理时间:
environment: # 原有配置... - REGISTRY_HTTP_TIMEOUT_READ=300s - REGISTRY_HTTP_TIMEOUT_WRITE=300s - REGISTRY_HTTP_TIMEOUT_IDLE=300s
内容的提问来源于stack exchange,提问作者VadOS
相关产品推荐
相关产品推荐

