侧边栏壁纸
博主头像
Ivan Zhang

所谓更牛,就是换个罪受

  • 累计撰写 48 篇文章
  • 累计创建 54 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

覆盖 docker pull 命令实现替换拉取镜像

Ivan Zhang
2025-03-05 / 0 评论 / 0 点赞 / 146 阅读 / 2,444 字
温馨提示:
本文最后更新于 ,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
有什么问题或观点欢迎评论留言,或者 交流。
如果觉得文章对您有所帮助,可以给博主打赏鼓励一下。

由于大家都知道的原因,我们在拉取一些镜像的时候,可以通过国内的代理镜像站拉取。在使用南京大学代理站拉取 gcr,ghcr 等源的时候,需要替换前缀,手动处理又比较麻烦。可以将镜像替换逻辑直接集成到 docker 命令中,通过覆盖 docker pull 的行为实现无缝替换。以下是实现方案,将其添加到 ~/.bashrc~/.zshrc 中:


1. 将镜像替换逻辑写入 Shell 配置文件

打开 ~/.bashrc(或 ~/.zshrc),在文件末尾添加以下代码:

# Docker 镜像前缀替换规则
declare -A DOCKER_REPLACE_RULES=(
  ["k8s.gcr.io/"]="gcr.nju.edu.cn/google-containers/"  # 优先处理带路径的规则
  ["gcr.io/"]="gcr.nju.edu.cn/"
  ["ghcr.io/"]="ghcr.nju.edu.cn/"
  ["nvcr.io/"]="ngc.nju.edu.cn/"
  ["quay.io/"]="quay.nju.edu.cn/"
)

# 覆盖 docker 命令,自动处理镜像名称替换
docker() {
  # 仅拦截 docker pull 命令
  if [ "$1" = "pull" ]; then
    local original_image="${*:2}"
    local target_image="$original_image"
    local has_replaced=false

    # 应用替换规则
    for source in "${!DOCKER_REPLACE_RULES[@]}"; do
      local target="${DOCKER_REPLACE_RULES[$source]}"
      if [[ "$original_image" == "$source"* ]]; then
        target_image="${target}${original_image#$source}"
        has_replaced=true
        break
      fi
    done

    if $has_replaced; then
      # 显示替换信息并拉取镜像
      echo -e "\033[33m镜像替换: $original_image => $target_image\033[0m"
      command docker pull "$target_image"

      # 重命名镜像并清理中间标签
      if [ $? -eq 0 ]; then
        command docker tag "$target_image" "$original_image"
        command docker rmi "$target_image" >/dev/null 2>&1
        echo -e "\033[32m镜像重命名完成: $original_image\033[0m"
        return 0
      else
        echo -e "\033[31m镜像拉取失败: $original_image\033[0m"
        return 1
      fi
    else
      # 无替换时直接拉取原镜像
      command docker pull "$original_image"
    fi

    return $?
  fi

  # 其他命令直接调用原生 docker
  command docker "$@"
}

2. 使配置生效

source ~/.bashrc  # 或 source ~/.zshrc

3. 使用示例

# 直接使用原始镜像名拉取,自动替换并重命名
docker pull k8s.gcr.io/pause:3.2
docker pull ghcr.io/open-webui/open-webui:main

# 其他命令不受影响
docker ps -a
docker build -t myapp .

功能特性

  1. 无缝集成

    • 直接使用 docker pull 命令,无需记忆脚本路径或镜像替换规则。
    • 自动处理多镜像拉取(如 docker pull image1 image2)。
  2. 智能重命名

    • 拉取后自动将镜像标签恢复为原始名称。
    • 自动清理中间镜像标签,避免冗余。
  3. 安全兼容

    • 仅拦截 docker pull 命令,其他命令(如 docker rundocker build)不受影响。
    • 保留原生 Docker 的所有功能。
  4. 彩色输出

    • 黄色显示镜像替换信息。
    • 绿色显示重命名完成提示,红色显示错误信息。

验证方法

# 查看镜像列表(应显示原始名称)
docker images

# 检查镜像标签对应关系
docker inspect k8s.gcr.io/pause:3.2 | grep -E 'RepoTags|RepoDigests'

扩展配置

(1) 临时禁用替换功能

若需临时使用原生 docker pull,可通过转义命令实现:

# 方法一:使用完整路径
/usr/bin/docker pull ghcr.io/open-webui/open-webui:main

# 方法二:调用 command 原生命令
command docker pull ghcr.io/open-webui/open-webui:main

(2) 自定义日志输出

修改 .bashrc 中的 echo 语句,或添加日志文件记录:

# 记录到日志文件
echo "$(date '+%Y-%m-%d %H:%M:%S') Pull $original_image => $target_image" >> ~/.docker_pull.log

总结

将此配置集成到 Shell 环境后,用户无需改变原有操作习惯即可享受镜像加速功能,是比独立脚本更优雅的解决方案。

0

评论区