10

我对如何从 docker 运行或回滚到特定版本的(二进制)图像特别感兴趣,并试图澄清这个问题。

Docker FAQ它说:

Docker 包括类似 git 的功能,用于跟踪容器的连续版本、检查版本之间的差异、提交新版本、回滚等。历史还包括容器是如何组装的以及由谁组装,因此您可以从生产服务器获得完全的可追溯性一路回到上游开发者。

尽我所能谷歌,我找不到“回滚”到早期容器、检查差异等的例子。(显然我可以为版本管理的 Dockerfile 做这些事情,但二进制 Docker 映像/容器即使在Dockerfile 没有,由于更新了软件源,我正在寻找一种方法来查看和回滚这些更改)。

举个基本的例子:想象我跑

docker build -t myimage .

在仅更新基本 ubuntu 的 Dockerfile 上:

FROM ubuntu:14:04
RUN apt-get update -q && apt-get upgrade -y

如果几天后我构建了相同的映像,我如何区分这些映像以查看哪些软件包已升级?稍后重新运行相同的构建命令后,如何回滚到早期版本的映像?

4

2 回答 2

12

从技术上讲,我们只是回滚 AUFS 层,不一定回滚历史。如果我们的工作流程包括交互式地修改我们的容器并使用 提交更改docker commit,那么这确实会回滚历史,因为它会删除我们在后续层中应用的任何包更新,而将版本安装在较早的层中。如果我们从 Dockerfile 重建镜像,情况就大不相同了。那么这里没有什么能让我们回到我们构建的以前的版本,我们只能从 Dockerfile 中删除步骤(层)。换句话说,我们只能将docker commits 的历史回滚为图像。

回滚到早期版本的 docker 镜像的关键似乎只是将 docker 标签指向早期的哈希值。

例如,考虑检查history标准ubuntu:latest图像的:

docker history ubuntu:latest

显示:

IMAGE               CREATED             CREATED BY                                      SIZE
ba5877dc9bec        3 weeks ago         /bin/sh -c #(nop) CMD [/bin/bash]               0 B
2318d26665ef        3 weeks ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.903 kB
ebc34468f71d        3 weeks ago         /bin/sh -c rm -rf /var/lib/apt/lists/*          8 B
25f11f5fb0cb        3 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
9bad880da3d2        3 weeks ago         /bin/sh -c #(nop) ADD file:de2b0b2e36953c018c   192.5 MB
511136ea3c5a        14 months ago    

                                               0 B

想象一下,我们想回到 hash 指示的图像25f

docker tag 25f ubuntu:latest
docker history ubuntu:latest

我们看到:

IMAGE               CREATED             CREATED BY                                      SIZE
25f11f5fb0cb        3 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
9bad880da3d2        3 weeks ago         /bin/sh -c #(nop) ADD file:de2b0b2e36953c018c   192.5 MB
511136ea3c5a        14 months ago                                                       0 B

当然,我们可能永远不想以这种方式回滚,因为它ubuntu:latest实际上并不是我们本地库中最新的 ubuntu。请注意,我们可以使用我们想要的任何标签,例如

docker tag 25f ubuntu:notlatest

或者简单地通过哈希启动旧图像:

docker run -it 25f /bin/bash

如此简单又如此整洁。请注意,我们可以将docker inspect其与 Docker 常见问题解答所引用的每个图像的元数据结合起来获得更多详细信息。

另请注意,docker diffanddocker commit与此过程相当不相关,因为它们指的是容器(例如正在运行的图像),而不是直接指图像。也就是说,如果我们以交互方式运行图像,然后在图像上添加或更改文件,我们可以通过 using 看到更改(容器之间)并使用docker diff <Container-id>.com 提交更改docker commit <Container id>

于 2014-08-18T19:36:27.993 回答
0

我不确定您是否真的可以将哈希用作标签。哈希 IIRC 是对图像本身的引用,而标签更多是图像上的元数据字段。

恕我直言,标签功能的文档记录非常糟糕,但您应该使用它的方式可能是使用各种语义版本控制来组织您的标签和图像。我们正在将一个复杂的(12 个微服务)系统迁移到使用 Docker,并且从依赖latest我很快结束了一些事情,比如语义版本控制和 Git Repo 中的更改日志来跟踪更改。

如果您说有一个docker分支自动接受更改并触发 DockerHub 上的构建,这也可能很好 - 您可以更新更改日志并知道哪个哈希/时间戳与什么相匹配。

就个人而言,由于 DockerHub 构建触发器目前很慢,我更喜欢手动为每个图像声明一个标签并保留一个变更日志,但 YMMV 和我怀疑这些工具会为此变得更好。

于 2014-08-16T11:28:18.863 回答