微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

可以从中提取用于 Docker 映像的构建参数吗?

如何解决可以从中提取用于 Docker 映像的构建参数吗?

有人声称可以在拉取映像后提取 Docker 映像的构建参数 (example)。

我已经使用以下 Dockerfile 对此进行了测试:

FROM scratch

ARG SECRET

ADD Dockerfile .

当我构建图像时:

$ docker build -t build-args-test --build-arg SECRET=12345 .

并按照文章中的说明进行检查:

$ docker image history --no-trunc build-args-test
IMAGE                   CREATED          CREATED BY                    SIZE      COMMENT
sha256:(hash omitted)   17 minutes ago   ADD Dockerfile . # buildkit   43B       buildkit.dockerfile.v0
<missing>               17 minutes ago   ARG SECRET                    0B        buildkit.dockerfile.v0

我看不到实际的构建参数 (12345)。

有没有办法从图像中提取构建参数?

如果映像不是在我的机器上构建而是从存储库中提取的,答案是否会有所不同?

我知道 Docker build secret 功能。不过,我是专门询问 ARG

解决方法

这取决于。

如果您使用机密,它将显示在使用该机密的图像层中。由于 ADD 步骤没有使用 ARG,您没有看到它,但是每个 RUN 步骤都将 ARG 值作为环境变量注入,您会得到如下结果:

$ cat df.secret-arg 
FROM alpine:latest

ARG SECRET
RUN echo doing something with a secret

$ DOCKER_BUILDKIT=0 docker build -t test-secret-arg --build-arg SECRET=password123 -f df.secret-arg .
Sending build context to Docker daemon  22.02kB
Step 1/3 : FROM alpine:latest
 ---> 49f356fa4513
Step 2/3 : ARG SECRET
 ---> Using cache
 ---> 7181367a28e6
Step 3/3 : RUN echo doing something with a secret
 ---> Running in a46ee00e682a
doing something with a secret
Removing intermediate container a46ee00e682a
 ---> e3eeea5f5d6d
Successfully built e3eeea5f5d6d
Successfully tagged test-secret-arg:latest

$ docker history test-secret-arg
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
e3eeea5f5d6d   6 seconds ago    |1 SECRET=password123 /bin/sh -c echo doing …   0B
7181367a28e6   33 seconds ago   /bin/sh -c #(nop)  ARG SECRET                   0B
49f356fa4513   3 months ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      3 months ago     /bin/sh -c #(nop) ADD file:7119167b56ff1228b…   5.61MB

在那里您可以使用 echo 命令在顶层看到 SECRET=password123。我在“使用该秘密的图像层”条件中掩盖了很多内容,因为有诸如多阶段构建之类的东西。但风险是如果你弄错了,秘密就会泄露。

将图像推送到注册表也无济于事:

$ docker tag test-secret-arg localhost:5000/test:secret-arg

$ docker push localhost:5000/test:secret-arg
The push refers to repository [localhost:5000/test]
8ea3b23f387b: Mounted from test/layer-bot
secret-arg: digest: sha256:969350bede26545fd35b53abed429ca0ecf2fc8717435a2edd842b4c9572b5bc size: 528

$ regctl image config localhost:5000/test:secret-arg
{
  "created": "2021-06-30T01:06:04.766667999Z","architecture": "amd64","os": "linux","config": {
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],"Cmd": [
      "/bin/sh"
    ]
  },"rootfs": {
    "type": "layers","diff_ids": [
      "sha256:8ea3b23f387bedc5e3cee574742d748941443c328a75f511eb37b0d8b6164130"
    ]
  },"history": [
    {
      "created": "2021-03-31T20:10:06.686359124Z","created_by": "/bin/sh -c #(nop) ADD file:7119167b56ff1228b2fb639c768955ce9db7a999cd947179240b216dfa5ccbb9 in / "
    },{
      "created": "2021-03-31T20:10:06.934368604Z","created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]","empty_layer": true
    },{
      "created": "2021-06-30T01:05:37.908964654Z","created_by": "/bin/sh -c #(nop)  ARG SECRET",{
      "created": "2021-06-30T01:06:04.766667999Z","created_by": "|1 SECRET=password123 /bin/sh -c echo doing something with a secret","empty_layer": true
    }
  ]
}

(注意,regctl 可从 my repo here 获得,但这只是进行注册表 API 调用。拉取映像并在另一台机器上检查仍会显示构建参数。)

一般来说,不要在 docker 镜像构建中使用秘密,这是一种代码异味。通常,CI 系统应该检查带有机密的代码,并且映像中应该包含二进制文件和库,而不是您想要保密的数据或配置。数据属于一个volume,配置以多种方式注入容器(配置文件mount、secret、环境变量等,但在容器中,不在镜像中)。有关使用机密的更多方法,请参阅 this answerWhat is the best way to pass AWS credentials to a Docker container?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?