解决 Docker 拉取镜像错误: “failed to register layer: exit status 22: unpigz: abort: zlib version less than 1.2.3”

在从远程仓库拉取 Docker 镜像时,通常会经历两个阶段:下载(Download)和解压(Extract)。了解这些阶段以及相关的工具可以帮助你排除类似 failed to register layer: exit status 22: unpigz: abort: zlib version less than 1.2.3 这样的错误。本文将详细解释这些过程,并提供解决该问题的方案。

1. 理解 Docker 拉取镜像的两个阶段:下载和解压

当你运行 docker pull <镜像名> 命令时,Docker 会执行以下两个主要步骤:

  • 下载阶段(Download):Docker 会从远程仓库(如 Docker Hub、Nexus 或私有仓库)拉取镜像层。这些镜像层通常是压缩文件(通常是 .tar.gz 格式)。
  • 解压阶段(Extract):一旦镜像层下载完毕,Docker 会在本地解压这些层,并准备好将镜像提供给用户使用。解压阶段涉及将下载的镜像层进行解压,并将文件写入本地文件系统。

2. 解压阶段使用本地的解压工具:gzip 和 unpigz

在解压阶段,Docker 需要解压已下载的镜像层。Docker 会使用本地的解压工具来处理这一过程,具体使用哪种工具取决于你的系统配置:

  • gzip:传统的解压工具,用于解压 .gz 文件。
  • unpigzpigz 的解压工具,它是 gzip 的并行实现,旨在提高多核系统上的解压效率。unpigz 通常在镜像使用 pigz 压缩时被使用。

关键点是,Docker 会根据系统中可用的解压工具自动选择使用 gzipunpigz

3. Docker 什么时候使用 unpigz,什么时候使用 gzip?

  • unpigz:如果系统安装了 pigz(一个并行版本的 gzip),Docker 会优先选择使用 unpigz 来解压镜像层。unpigz 能利用多个 CPU 核心,提升解压速度,尤其是在多核处理器系统中。
  • gzip:如果系统没有安装 pigz 或者 Docker 检测到使用 gzip 更合适时,会默认使用传统的 gzip 工具进行解压。

在大多数现代 Linux 系统中,如果安装了 pigz,Docker 会使用 unpigz 来充分利用并行解压的优势。

4. 如何解决 “failed to register layer: exit status 22: unpigz: abort: zlib version less than 1.2.3” 错误

错误 failed to register layer: exit status 22: unpigz: abort: zlib version less than 1.2.3 表明由于系统的 zlib 库版本过低,unpigz 解压工具无法正常工作。这个问题通常出现在 Docker 尝试使用 unpigz 解压镜像层时,系统中的 zlib 版本低于 1.2.3,导致不兼容的错误。

解决方案 1:卸载 pigz,使用 gzip 进行解压

一种解决方案是卸载 pigz,这样 Docker 就会默认使用 gzip 来解压镜像层,从而避免使用 unpigz 解压时遇到的问题。

卸载 pigz

sudo apt-get remove pigz  # Debian/Ubuntu
sudo yum remove pigz      # CentOS/RHEL

卸载 pigz 后,Docker 会不再使用 unpigz,而是回退到使用 gzip,从而避免了由于过时的 zlib 版本引发的问题。

解决方案 2:升级 pigz 到新版本

另外,你也可以通过升级 pigz 到一个兼容的版本来解决这个问题。下面是升级 pigz 的步骤:

  1. 下载最新版本的 pigz
cd /usr/local 
wget https://github.com/madler/pigz/archive/refs/tags/v2.8.tar.gz # 如果有更新,替换为最新版本 
tar -zxf v2.8.tar.gz cd pigz-2.8 make
  1. 备份现有的 pigz 和 unpigz 可执行文件: 在替换文件之前,最好先备份现有的文件,以防需要还原:
which pigz 
which unpigz 
mv /usr/bin/pigz /usr/bin/pigz.bak 
mv /usr/bin/unpigz /usr/bin/unpigz.bak
  1. 安装新的 pigz 版本
cd /usr/local/pigz-2.8 
cp pigz /usr/bin/ 
cp unpigz /usr/bin/
  1. 检查安装的 pigz 版本: 安装完成后,可以通过以下命令确认 pigz 的版本:
pigz -V # 应显示 pigz 2.8 或其他最新版本
  1. 测试 Docker 拉取镜像: 升级 pigz 并确保 zlib 版本符合要求后,再次尝试拉取 Docker 镜像:
docker pull <镜像名>

这样,你应该能够解决由于过时的 zlib 库引发的问题。

5. 总结

当你遇到 failed to register layer: exit status 22: unpigz: abort: zlib version less than 1.2.3 错误时,通常是因为 unpigz 在解压时依赖的 zlib 版本过低。你可以通过以下两种方法解决:

  • 卸载 pigz,强制 Docker 使用 gzip 进行解压;
  • 升级 pigz 到一个支持当前 zlib 版本的更新版本。

按照上述步骤操作后,应该能够成功解决问题,并顺利拉取 Docker 镜像。

Leave a Comment