15.3.7 常见镜像管理故障排查

常见镜像管理故障排查聚焦于镜像拉取、构建、保存、清理与仓库交互等环节。以下从原理草图、症状、原因与处理步骤进行归纳,辅以可执行示例、命令解释与练习。

原理草图:镜像流转与故障点#

文章图片

预备安装与排障工具#

目的:补齐网络、TLS、JSON 解析与压缩工具,便于定位问题。

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y curl openssl jq ca-certificates

# CentOS/Rocky
sudo yum install -y curl openssl jq ca-certificates

# 验证工具是否可用
curl --version
openssl version
jq --version

一、镜像拉取失败#

常见症状
- TLS handshake timeout
- x509: certificate signed by unknown authority
- manifest unknown / pull access denied

排查与处理(可执行示例)

# 1) 网络与 DNS 检查(预期:HTTP 200 或 401)
curl -I https://registry-1.docker.io/v2/

# 2) 验证 DNS 解析
getent hosts registry-1.docker.io

# 3) 代理配置检查(systemd 环境)
cat /etc/systemd/system/docker.service.d/http-proxy.conf
# 期望看到:
# [Service]
# Environment="HTTP_PROXY=http://proxy:3128"
# Environment="HTTPS_PROXY=http://proxy:3128"

# 4) 私有仓库证书导入
# 将 CA 证书放入以下目录,重启 Docker
sudo mkdir -p /etc/docker/certs.d/registry.example.com
sudo cp ca.crt /etc/docker/certs.d/registry.example.com/ca.crt
sudo systemctl restart docker

# 5) 验证镜像名与标签
docker manifest inspect nginx:1.25

# 6) 登录仓库并重试
docker login registry.example.com
docker pull registry.example.com/app/api:1.0.0

命令解释
- curl -I:只请求响应头,快速判断仓库是否可达。
- getent hosts:以系统解析配置为准验证 DNS。
- docker manifest inspect:确认标签在仓库真实存在。


二、镜像构建失败#

常见症状
- failed to solve with frontend dockerfile.v0
- no space left on device
- executor failed running

排查与处理(含 Dockerfile 示例)

# 1) 查看详细构建日志
docker build --no-cache --progress=plain -t demo:debug .

# 2) 使用 .dockerignore 缩小构建上下文
cat > .dockerignore <<'EOF'
.git
node_modules
*.log
EOF

# 3) 示例 Dockerfile(确保依赖可用)
cat > Dockerfile <<'EOF'
FROM alpine:3.19
RUN apk add --no-cache curl
CMD ["curl","-I","https://example.com"]
EOF

# 4) 检查磁盘空间
df -h /var/lib/docker

# 5) 清理无用资源(谨慎)
docker system prune -a --volumes

命令解释
- --progress=plain:输出构建每步的完整日志。
- .dockerignore:避免大量无关文件传入构建上下文。


三、镜像导入导出异常#

常见症状
- unexpected EOF
- invalid tar header
- 导入后镜像无标签

排查与处理(规范流程)

# 1) 正确导出镜像(保留标签)
docker save -o nginx_1.25.tar nginx:1.25

# 2) 校验文件完整性
sha256sum nginx_1.25.tar

# 3) 正确导入镜像
docker load -i nginx_1.25.tar

# 4) 反例:export/import 仅用于容器文件系统
docker run --name t1 -d nginx:1.25
docker export -o t1.tar t1
docker import t1.tar t1:fs-snapshot

命令解释
- save/load:镜像级别的备份与恢复(保留标签)。
- export/import:容器文件系统快照,不保留镜像元数据。


四、镜像删除失败或空间未释放#

常见症状
- image is being used by running container
- 删除后磁盘占用仍高

排查与处理

# 1) 查找引用该镜像的容器
docker ps -a --filter ancestor=nginx:1.25

# 2) 删除相关容器后再删镜像
docker rm -f <container_id>
docker rmi nginx:1.25

# 3) 查看多标签与 digest
docker images --digests | grep nginx

# 4) 清理未使用资源
docker system prune -a

命令解释
- --filter ancestor:列出基于该镜像创建的容器。
- system prune -a:移除所有未被使用的镜像与构建缓存。


五、镜像标签冲突与版本混乱#

常见症状
- latest 覆盖导致回滚失败
- 不同环境镜像内容不一致

处理建议与示例

# 使用语义化或提交哈希
docker tag app:build app:1.2.3
docker tag app:build app:git-9f3c2a1

# 在生产禁用 latest
# 仅允许拉取明确版本
docker pull registry.example.com/app:1.2.3

六、镜像仓库交互异常(push 失败/慢)#

常见症状
- denied: requested access to the resource is denied
- 推送卡住、速度极慢

排查与处理

# 1) 登录并验证权限
docker login registry.example.com

# 2) 观察推送分层过程
docker push registry.example.com/app:1.2.3

# 3) 配置加速器(/etc/docker/daemon.json)
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": ["https://mirror.example.com"],
  "insecure-registries": ["registry.example.com:5000"]
}
EOF
sudo systemctl restart docker

七、镜像安全扫描或策略阻断#

常见症状
- 推送被拒绝
- 安全扫描报告高危漏洞

处理示例(以 Trivy 为例)

# 安装 Trivy(示例)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin

# 扫描镜像
trivy image nginx:1.25

# 阈值控制示例(CI 中常用)
trivy image --exit-code 1 --severity HIGH,CRITICAL nginx:1.25

八、通用排查流程(最小化复现)#

# 1) 查看 Docker 服务日志
journalctl -u docker --since "1 hour ago"

# 2) 查看镜像与容器总体情况
docker info
docker images
docker ps -a

# 3) 复现最小命令
docker pull alpine:3.19
docker run --rm alpine:3.19 echo "ok"

练习#

  1. 拉取失败模拟:将 /etc/resolv.conf 临时改为错误 DNS,观察 docker pull 报错并恢复。
  2. 构建失败定位:在 Dockerfile 中故意写错包名,使用 --progress=plain 找到失败步骤。
  3. 导入导出验证:对 nginx:1.25 执行 save/load,验证标签是否保留。
  4. 清理验证:创建多个容器后删除,比较 docker system df 前后差异。

常见命令速查表#

docker pull <image:tag>         # 拉取镜像
docker build -t <name:tag> .    # 构建镜像
docker save -o file.tar <img>   # 导出镜像
docker load -i file.tar         # 导入镜像
docker rmi <img>                # 删除镜像
docker system prune -a          # 清理资源
docker manifest inspect <img>   # 校验标签存在性

以上步骤覆盖镜像管理中高频故障,结合示例与练习可快速建立定位与修复能力。