【问题标题】:How do I use the "git-like" capabilities of Docker?如何使用 Docker 的“类 git”功能?
【发布时间】:2014-08-15 23:24:30
【问题描述】:

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

Docker FAQ 上面写着:

Docker 包含类似 git 的功能,用于跟踪容器的连续版本、检查版本之间的差异、提交新版本、回滚等。历史还包括容器的组装方式和组装者,因此您可以从生产服务器一直回到上游开发者。

我可能在 Google 上找不到“回滚”到早期容器、检查差异等的示例。(显然,我可以对版本管理的 Dockerfile 执行此类操作,但二进制 Docker 映像/容器可以更改即使 Dockerfile 没有,由于更新的软件源,我正在寻找一种方法来查看和回滚这些更改)。

举个基本的例子:假设我在运行

docker build -t myimage .

在只更新基础 ubuntu 的 Dockerfile 上:

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

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

【问题讨论】:

    标签: docker dockerhub


    【解决方案1】:

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

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

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

    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
    

    假设我们想回到哈希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 diffdocker commit 与此过程相当不相关,因为它们指的是容器(例如正在运行的图像),而不是直接指图像。也就是说,如果我们以交互方式运行图像,然后在图像上添加或更改文件,我们可以使用docker diff <Container-id> 看到更改(容器之间)并使用docker commit <Container id> 提交更改。

    【讨论】:

      【解决方案2】:

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

      imho 标签功能的文档记录非常糟糕,但您应该使用它的方式可能是使用semantic versioning 来组织您的标签和图像。我们正在将一个复杂的(12 个微服务)系统迁移到使用 Docker,并且不再依赖 latest,我很快就完成了一些类似语义版本控制和 Git Repo 中的更改日志的操作,以跟踪更改。

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

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

      【讨论】:

      • 感谢您的回复。我试图澄清我的问题,以便更清楚地说明我在 docker 文档中所指的功能。如果图像存储库是一个 git 存储库,那么如何按照我最初提出的方式“回滚”就很清楚了。常见问题解答表明这是可能的,但我无法弄清楚。感谢您的帮助。
      • 是的,我也无法解决这个问题 - 因此使用手动 semver 标记,这使我可以还原等。当您转到 Hub 帐户中的“标签”选项卡时您可以删除不需要的标签,这意味着以后可以从构建框中删除它们。此外,正如我所说,还有 GitHub 构建触发器,这意味着您的代码是受版本控制的,您可以或多或少地使用 latest 标签。这似乎 should 是可能的,但我怀疑图像哈希不是有效标签。
      • 我还应该补充一点,使用 GitHub 命名法的 Docker 存储库也非常无用,因为它不是 GH 意义上的存储库,而是“对特定图像当前和过去状态的粗略概念”而不是具有依赖关系的完整状态日志。通过“回滚”,我认为它们的字面意思是“使用较早的容器”,因为其他地方的类似 Git 的功能是提交图像、标记图像和推/拉图像。如果您使用自动构建和历史记录,您可以找到时间戳和用户等,但我不确定其中有多少是 GitHub 元数据与他们的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 2013-07-18
      • 1970-01-01
      • 2012-05-23
      • 2016-01-25
      • 1970-01-01
      • 2022-07-03
      相关资源
      最近更新 更多