如何在不使用Docker Hub的情况下分享我的Docker镜像?

349
我想知道Docker镜像在我的本地计算机上存储在哪里。 我是否可以共享我的Docker镜像,而不使用Docker-Hub或Dockerfile,而是使用“真正的”Docker镜像?当我将Docker镜像“推送”到Docker-Hub时,会发生什么?

5
供日后参考:一篇很好的文章,介绍如何“移动Docker容器镜像” ,链接为 https://blog.giantswarm.io/moving-docker-container-images-around/。 - Mifeet
4个回答

315

Docker镜像被存储为文件系统层。每个Dockerfile中的命令都会创建一个层。您还可以使用命令行中的docker commit在进行一些更改后创建层(可能是通过docker run)。

这些层默认存储在/var/lib/docker下。虽然理论上你可以从那里选取文件并安装到不同的Docker服务器,但在玩弄Docker使用的内部表示时,这可能是一个坏主意。

当你推送镜像时,这些层会被发送到注册表(默认情况下是Docker Hub注册表,除非您使用其他注册表前缀标记镜像)并在那里存储。拉取时,层ID用于检查您是否已经在本地拥有该层或需要下载它。您可以使用docker history来查看使用了哪些层(其他镜像)以及在某种程度上哪些命令创建了该层。

至于分享镜像而不将其推送到Docker Hub注册表的选项,您最好的选择是:

  • docker save一个镜像或docker export一个容器。这将输出一个tar文件到标准输出,所以你会想要做一些类似于docker save 'dockerizeit/agent' > dk.agent.latest.tar的事情。然后你可以在不同的主机上使用docker loaddocker import

  • 托管您自己的私有注册表 - 已过时,请参见评论 请参阅docker注册表镜像。我们构建了一个支持S3的注册表,您可以根据需要启动和停止(所有状态都保留在您选择的S3存储桶中),这很容易设置。这也是观察将内容推送到注册表时发生的事情的有趣方式。

  • 可以使用其他的注册表,比如quay.io(我个人没有尝试过),不过你在docker hub上担心的问题可能也会出现在这里。


  • 6
    以备将来参考,Docker镜像仓库的链接已经过时。你现在应该使用Docker Registry 2.0以及github/docker/distribution上的代码。 - RoelAdriaans
    1
    我不确定Registry 2.0是否清楚地表明它是原始版本的可用替代品。它似乎缺少一些基本功能,例如搜索。https://dev59.com/cF0a5IYBdhLWcg3woJ55 - JoshRivers
    2
    关于 docker save 的问题:当我将一个派生自另一个镜像(比如 python:2.7)的镜像推送到注册表时,除非它发生了变化,否则父镜像不需要被上传多次。我能否保存部分镜像以实现类似的文件大小优化?我在跳跃这些障碍,因为我是一个拥有多个镜像的业余爱好者,我不想为私有注册表付费。 - Pieter
    5
    你能否仅从git存储库中拉取源代码文件,包括Dockerfile文件,并在主机上运行docker build命令? - toficofi
    1
    @Jishaxe 我的构建过程中需要执行 npm install... 但是我无法在我的主机上进行构建,因为它的内存非常小,这一步骤总是失败(参见:https://github.com/npm/npm/issues/5021)。 - Soft Bullets

    97

    根据这篇博客,可以通过执行以下命令来共享Docker镜像而不需要Docker Registry:

    docker save --output latestversion-1.0.0.tar dockerregistry/latestversion:1.0.0
    

    完成此命令后,可将图像复制到服务器并按以下方式导入:

    docker load --input latestversion-1.0.0.tar
    

    我猜这样做会失去缓存/重用未更改的层?因为即使只有小部分内容发生了变化,您也必须始终上传完整的图像? - Andrius
    在本地,您只需像从注册表中获取一样调用它:docker run [flags] foo.bar.com/<path/in/registry>/<container-name>:latest - RicHincapie

    57

    将 Docker 镜像发送到远程服务器可以通过以下 3 个简单步骤完成:

    1. 在本地,将 Docker 镜像保存为 .tar 文件:
    docker save -o <path for created tar file> <image name>
    
    1. 在本地,使用scp.tar文件传输到远程服务器

    2. 在远程服务器上,将镜像加载到docker中:

    docker load -i <path to docker image tar file>
    

    10

    [更新]

    最近,亚马逊AWS ECR(弹性容器注册表)提供了一个Docker镜像注册表,您可以通过AWS IAM访问管理服务控制对其的访问。当您推送镜像时,ECR还可以运行CVE(漏洞)检查。

    一旦创建了ECR并获取了“URL”,您就可以根据所创建的权限进行推送和拉取,因此可以将其设置为私有或公共。

    定价是按存储的数据量和数据传输成本计算的。

    https://aws.amazon.com/ecr/

    [原始答案]

    如果您不想使用Docker Hub本身,则可以在JFrog的Artifactory下托管自己的Docker存储库:

    https://www.jfrog.com/confluence/display/RTF/Docker+Repositories

    然后它将在您自己的服务器上运行。

    其他托管供应商也可用,例如CoreOS:

    http://www.theregister.co.uk/2014/10/30/coreos_enterprise_registry/

    它收购了quay.io。


    虽然我还没有尝试在组织外共享,但此功能也可在Google Cloud控制台上使用。 - sam

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接