【Docker系列】push镜像报错问题&解决方案
1 问题描述
docker push 报这个错,unknown blob
详细报错内容:
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them The push refers to repository [192.******/*******/*************] 3b3341e9d039: Pushing [==================================================>] 12.97MB abbeacff5fa5: Pushing [==================================================>] 7.68kB 685c55d58372: Pushing [==================================================>] 4.096kB 6d451941e7b1: Pushing 2.56kB 0348644449af: Pushing [===========================> ] 15.8MB/28.67MB 4b56765b6b5e: Pushing [==================================================>] 7.168kB 65bc30a63225: Pushing [==================================================>] 5.12kB 6be1b85707bc: Pushing [==================================================>] 2.56kB 1eb3501d2fb4: Waiting 81d1bb17d85e: Waiting 5079ade1f5c9: Waiting 9386262d7a74: Waiting unknown blob
2 解决思路
2.1 定位问题
当 Docker push 时出现 "unknown blob" 错误时,这通常表示 Docker 镜像中缺少某些层或 blob。
有几种可能的解决方案:
- 修改daemon.json文件
- 检查 Docker 镜像是否存在
- 检查 Dockerfile 是否正确
- 清除 Docker 缓存
- 重新构建 Docker 镜像
- 检查 Docker 镜像层
2.2 方案一
如果是使用的域名推送,可以修改daemon.json文件,改为内网push,增加
insecure-registries
{
"insecure-registries": ["my.insecure.registry:5000"]
}
如果你需要连接到多个不安全的 Docker Registry,请将它们添加到 `insecure-registries` 列表中。
拓展
insecure-registries
是 Docker daemon 配置选项之一,允许 Docker daemon 在不使用 TLS 或其他安全协议的情况下连接到指定的 Docker Registry。默认情况下,Docker daemon 仅允许使用 TLS 或其他安全协议连接到 Docker Registry。
注意,使用
insecure-registries
可能会存在安全风险。建议仅在测试或开发环境中使用insecure-registries
选项,不要将其用于生产环境。
2.3 方案二
1. 检查 Docker 镜像是否存在
使用以下命令查看 Docker 镜像列表:
docker images
```
如果你的镜像不在列表中,请尝试重新构建镜像。
2.检查 Dockerfile 是否正确
确保 Dockerfile 中的每个指令都能成功运行,并且没有拼写错误或语法错误。
3.清除 Docker 缓存
可以尝试清除 Docker 缓存并重新构建 Docker 镜像。可以使用以下命令清除 Docker 缓存:
这将清除所有未使用的 Docker 镜像、容器和卷。
docker system prune --all --force --volume
4.重新构建 Docker 镜像
如果清除 Docker 缓存后问题仍然存在,可以尝试重新构建 Docker 镜像:
下面命令会将重新构建 Docker 镜像。
docker build -t <image_name> .
4.检查 Docker 镜像层
可以使用以下命令列出 Docker 镜像的所有层:
docker inspect <image_name>
如果尝试了上述解决方案后仍然无法解决问题,可能需要进一步检查 Docker 镜像及其层的状态。
可以使用以下命令列出 Docker 镜像的所有层和它们所对应的 blob 的摘要:
docker inspect <image_name> | grep -i sha256
其中
<image_name>
是要检查的 Docker 镜像的名称或 ID。输出将包含每个层的 SHA256 摘要,例如:
"RootFS": { "Type": "layers", "Layers": [ "sha256:0a8f4a1d34f9d295a0bcf9a7f8c11a4d9a4e5f5b2f2a6b8e6e6b8f8a496f16d5", "sha256:0b2c3e1e6f0e3e0d8b7f1c8db67de5a2a3fbc0e3c0d2bb8f1a7b1d2d9a7c4e01", "sha256:2b8c7e2fdee9f0d5e6b9a6f5b0c1dd3a309c3826c7c4a31b66c9956179c7f9e5", "sha256:9a32d4f6c0c8d1b3b0bca1d6b9e5f6c8e4f75d9b7d4bdc1e2f7f3d0c86c63cbe", "sha256:faa9aef3a5244a9a1a406f3df7d1b4a1b7979c0f8d86c533d5ed1e3c8b08c5e4" ] }
如果某个层或 blob 缺失,您将看不到其对应的 SHA256 摘要。如果确实缺少某些层或 blob,则可以尝试重新构建 Docker 镜像或从另一个来源获取缺少的层或 blob。
如果您使用的是 Docker Registry,可以尝试使用 Registry 的
garbage-collect
命令清除 Registry 中的孤立层和 blob。例如:docker exec <registry_container_id> bin/registry garbage-collect /etc/docker/registry/config.yml
其中
<registry_container_id>
是 Registry 容器的 ID。garbage-collect
命令将清除 Registry 中的孤立层和 blob,并重新构建索引。
如果有256
如果使用的是 Docker 19.03 或更高版本,则 Docker 会默认启用基于 SHA256 的镜像摘要算法。在这种情况下,您可以使用以下命令列出 Docker 镜像的所有层和它们所对应的 SHA256 摘要:
docker inspect <image_name> --format='{{json .RootFS.Layers}}' | jq -r '.[]'
其中
<image_name>
是您要检查的 Docker 镜像的名称或 ID。这将输出 Docker 镜像的所有层的 SHA256 摘要,例如:
sha256:0a8f4a1d34f9d295a0bcf9a7f8c11a4d9a4e5f5b2f2a6b8e6e6b8f8a496f16d5 sha256:0b2c3e1e6f0e3e0d8b7f1c8db67de5a2a3fbc0e3c0d2bb8f1a7b1d2d9a7c4e01 sha256:2b8c7e2fdee9f0d5e6b9a6f5b0c1dd3a309c3826c7c4a31b66c9956179c7f9e5 sha256:9a32d4f6c0c8d1b3b0bca1d6b9e5f6c8e4f75d9b7d4bdc1e2f7f3d0c86c63cbe sha256:faa9aef3a5244a9a1a406f3df7d1b4a1b7979c0f8d86c533d5ed1e3c8b08c5e4
如果某个层缺失,将看不到其对应的 SHA256 摘要。如果确实缺少某些层,则可以尝试重新构建 Docker 镜像或从另一个来源获取缺少的层。