【问题标题】:How to push only whats changed with Docker push?如何仅推送 Docker 推送更改的内容?
【发布时间】:2017-02-11 06:37:06
【问题描述】:

一个。这是我创建图像的方式:

  1. 获得最新的 Ubuntu 镜像
  2. 作为容器运行并附加到它
  3. 从 docker 容器中的 git 克隆源代码
  4. 标记 docker 映像并将其推送到我的注册表

B。我从另一台机器上拉、改和推:

  1. Docker 从注册表中拉取
  2. 使用拉取的图像启动容器并附加到它
  3. 更改克隆的 git 目录中的某些内容
  4. 停止容器,标记并将其推送到注册表

现在我看到的问题是,每次 B 重复时,它都会尝试将 ~600MB(这是公共图像层)上传到注册表,这在我的情况下需要很长时间.

有什么办法可以避免上传整个 600MB 而是推送唯一改变的目录?

我做错了什么?你们如何使用 docker 进行频繁推送?

【问题讨论】:

标签: docker docker-registry


【解决方案1】:

Docker 只会推送更改的层,因此看起来您的工作流程中的某些内容不太正确。如果你使用Dockerfile 会更清楚,因为每条指令都会显式创建一个层,但即使使用docker commit,结果也应该是一样的。

示例 - 从 ubuntu 映像运行容器并运行 apt-get update,然后将容器提交到新映像。现在运行docker history,您将看到新图像在 bash 图像之上添加了一个层,该层具有运行 APT 更新的附加状态:

> docker history sixeyed/temp1

IMAGE               CREATED              CREATED BY SIZE                COMMENT
2d98a4114b7c        About a minute ago   /bin/bash                                       22.2 MB
14b59d36bae0        7 months ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
<missing>           7 months ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB
<missing>           7 months ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
<missing>           7 months ago         /bin/sh -c #(nop) ADD file:620b1d9842ebe18eaa   187.8 MB

在这种情况下,ubuntu 和我的temp1 图像之间的差异是 22MB 层 2d98

现在如果我从temp1 运行一个新容器,创建一个空文件并运行docker commit 来创建一个新图像,新层只有更改后的文件:

> docker history sixeyed/temp2
IMAGE               CREATED              CREATED BY SIZE                COMMENT
e9ea4b4963e4        45 seconds ago       /bin/bash                                       0 B
2d98a4114b7c        About a minute ago   /bin/bash                                       22.2 MB
14b59d36bae0        7 months ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
<missing>           7 months ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB
<missing>           7 months ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
<missing>           7 months ago         /bin/sh -c #(nop) ADD file:620b1d9842ebe18eaa   187.8 MB

当我push 第一个图像时,只有 22MB 的层会被上传 - 其他的从 ubuntu 安装,它已经在 Hub 中。如果我推送第二个图像,则只会推送更改的图层 - temp1 图层是从第一次推送中安装的:

> docker push sixeyed/temp2
The push refers to a repository [docker.io/sixeyed/temp2]
f741d3d3ee9e: Pushed
64f89772a568: Mounted from sixeyed/temp1
5f70bf18a086: Mounted from library/ubuntu
6f32b23ac95d: Mounted from library/ubuntu
14d918629d81: Mounted from library/ubuntu
fd0e26195ab2: Mounted from library/ubuntu                          

因此,如果您的推送上传了 600MB,那么您要么对映像进行了 600MB 的更改,要么您的工作流程阻止了 Docker 正确使用层。

【讨论】:

  • 谢谢。在 B.3 中。步骤我确实只更改了一个文件,但在我的情况下,我是否标记并推送,而在你的情况下,您只推送到集线器中的同一图像?
  • 不,我使用了两个图像,第二个是第一个的更改版本。我会在您的 A、B 和更改的 B 图像上运行 docker history,以查看哪些层正在被重用。
【解决方案2】:

Docker 已经只上传了更改的层。

这类似于 Docker build 仅重建缓存无效层的方式。当然,它必须与注册表通信哪些层可用(它报告为Already pushed)。如果你改变了 Dockerfile 中的操作顺序,它们绝对是新的层,显然它们都会重新上传。

FROM ubuntu

RUN echo "hello"

EXPOSE 80

FROM ubuntu

EXPOSE 80

RUN echo "hello"

即使行为最终结果相同,这两个图像也相距数英里。所以要小心这些事情。

【讨论】:

  • 我给出的场景中没有包含任何 Dockerfile,是这个问题吗?
  • 我想说的是,将指令序列从Dockerfile 的一个版本更改为另一个版本是一个可能的原因,因此请注意此类更改。否则,docker push 足够智能,只能推送新层。
  • 好吧,在我的情况下,不存在 Dockerfile,因此顺序会有所不同。场景就像问题中描述的那样 - 不多不少。
猜你喜欢
  • 2018-06-26
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
相关资源
最近更新 更多