Docker镜像中是否可以提取用于构建参数?

6

有人声称,在你拉取 Docker 镜像之后,可以提取出构建参数的构建参数列表(示例)。

我使用以下 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 构建机密信息功能。但是,我特别询问 ARG

1个回答

5

这要看情况而定。

如果您使用了密钥,它将显示在使用该密钥的图像层中。由于 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",
      "empty_layer": true
    },
    {
      "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可以从我的仓库中获取,但这只是进行注册表API调用。在另一台机器上拉取镜像并进行检查仍将显示构建参数。)
总的来说,不要在Docker镜像构建过程中使用机密信息,这是一个代码异味。通常CI系统应该使用带有机密信息的代码进行检出,镜像应该包含二进制文件和库,而不是您想要保持私密的数据或配置。数据应归属于卷,配置以各种方式注入到容器中(配置文件挂载、密码、环境变量等),但是在容器中而不是在镜像中。有关更多处理机密信息的方法,请参见此答案中的问题“传递AWS凭证到Docker容器的最佳方法是什么?”。)

BuildKit改变了答案吗?我刚刚使用了BuildKit进行测试,结果显示方式相同,但是我很好奇为什么你要禁用它。 - Koterpillar
啊,你想要 --progress plain - Koterpillar
“无论使用什么机制” - 包括 BuildKit secrets?@软件工程师 - Koterpillar
2
Buildkit的secrets应该是安全的。风险不在于秘密本身被图像元数据泄露,而在于使用秘密将受保护的数据从受保护的位置移动到图像中(人们经常意外记录秘密)。 - BMitch
@Koterpillar -- 我之前说错了;Buildkit 中确实有适用的方法,但据我所知它们并非标准方法,仅适用于 Docker 软件而非通用容器。使用 Buildkit secrets 应该更加安全,或者只需将秘密存储到文件中,并使用 tmpfs 进行挂载即可。 - Software Engineer
显示剩余6条评论

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