有时候需要将镜像从Docker Hub中下载,再转存到私服的镜像仓库中。为完成上述任务,设计了如下的Python
脚本,只要按需修改高亮部分即可:
import os import subprocess import requests import json # 定义变量 public_image = "redis" # 公共镜像名称 arch = "linux/amd64" # 架构 tag = "8.0.2" private_registry = "192.168.*.*:*" # 私有 Registry 地址(HTTP) # 允许不安全的 registry 连接 os.environ['DOCKER_CONTENT_TRUST'] = '0' public_image_with_tag = f"{public_image}:{tag}" private_image = f"{private_registry}/{public_image_with_tag}" # 私有镜像名称 # 获取临时目录 - 兼容Windows和Linux temp_dir = os.getenv("TEMP") or os.getenv("TMPDIR") or "/tmp" tar_file_path = os.path.join(temp_dir, public_image_with_tag.replace(":", "_") + ".tar") # 临时 tar 文件路径 tar_file_path = tar_file_path.replace("\\", "_").replace("/", "_") # 统一处理路径分隔符 def run_command(cmd, error_msg): """运行命令并检查返回码""" result = subprocess.run(cmd, shell=True) if result.returncode != 0: print(f"错误: {error_msg}") exit(1) # 拉取公共镜像 print(f"正在拉取公共镜像: {public_image_with_tag}") if arch is None: run_command(f"docker pull {public_image_with_tag}", f"拉取镜像失败: {public_image_with_tag}") else: print(f"拉取架构为: {arch}") run_command(f"docker pull {public_image_with_tag} --platform {arch}", f"拉取镜像失败: {public_image_with_tag}") # 保存镜像为 tar 文件 print(f"正在保存镜像为 tar 文件: {tar_file_path}") run_command(f"docker save -o {tar_file_path} {public_image_with_tag}", f"保存镜像失败: {public_image_with_tag}") # 加载 tar 文件到 Docker print(f"正在加载 tar 文件到 Docker: {tar_file_path}") run_command(f"docker load -i {tar_file_path}", f"加载镜像失败: {tar_file_path}") # 重新打标签(推送到私有 Registry 需要) print(f"正在重新打标签为: {private_image}") run_command(f"docker tag {public_image_with_tag} {private_image}", f"重新打标签失败: {public_image} -> {private_image}") # 推送到私有 Registry print(f"正在推送到私有 Registry: {private_image}") run_command(f"docker push {private_image}", f"推送镜像失败: {private_image}") # 验证镜像是否成功推送到私有 Registry print("验证镜像是否成功推送到私有 Registry...") registry_url = f"http://{private_registry}/v2/{public_image}/tags/list" print(registry_url) try: response = requests.get(registry_url) response.raise_for_status() result_obj = response.json() if public_image not in result_obj.get("name", ""): print(f"镜像推送验证失败, {result_obj}") exit(1) if tag in result_obj.get("tags", []): print(f"镜像已成功推送到私有 Registry: {private_image}") else: print(f"镜像推送验证失败: {private_image}") exit(1) except requests.exceptions.RequestException as e: print(f"验证请求失败: {e}") exit(1) # # 清理临时文件和本地镜像 print("清理临时文件和本地镜像...") try: os.remove(tar_file_path) except OSError as e: print(f"删除临时文件失败: {e}") run_command(f"docker rmi {public_image_with_tag}", f"删除本地镜像失败: {public_image_with_tag}") run_command(f"docker rmi {private_image}", f"删除本地镜像失败: {private_image}") print("镜像转存完成!")