作者:Mr_维力_811 | 来源:互联网 | 2022-12-10 12:33
我正在尝试根据在postgres
Raspbian和Mac OS X/Debian 上运行的官方图像制作自定义图像.
当我做的时候
from postgres:10.4
并且构建了Dockerfile,似乎docker隐式选择了postgres的x64版本,然后只根据该架构构建了一个新的图像.
因此,当我将图像推送到我的GitLab注册表并再次下载时,它不起作用.它抛出一个standard_init_linux.go:190: exec user process caused "exec format error"
,我认为这是另一种说错建筑的方式.
我可以通过https://blog.docker.com/2017/09/docker-official-images-now-multi-platform/收集,在一个图像中支持多个架构,使其成为"多拱".然而,尽管资源很多,但对于我如何构建自己的多拱形图像以及需求是什么并不明显.
理想情况下,我希望能够无缝地构建和推送armv7和x64版本 - 来自Raspberry Pi/Raspbian主机和Mac/Debian主机.
我发现了这个问题:交叉编译多拱容器
其中一个答案表明了一个过程.但是,该进程不支持使用该RUN
命令的dockerfiles ,这是我的项目的要求.
1> BMitch..:
您将需要为特定体系结构构建每个映像,然后生成清单,其中是每个映像的列表。第二部分的命令目前处于试验阶段。该文件显示了这个例子(尽管多数人倾向于把建筑的标签名称,例如myrepo/myapp:arm-linux-v1
):
$ docker manifest create 45.55.81.106:5000/coolapp:v1 \
45.55.81.106:5000/coolapp-ppc64le-linux:v1 \
45.55.81.106:5000/coolapp-arm-linux:v1 \
45.55.81.106:5000/coolapp-amd64-linux:v1 \
45.55.81.106:5000/coolapp-amd64-windows:v1
Created manifest list 45.55.81.106:5000/coolapp:v1
$ docker manifest annotate 45.55.81.106:5000/coolapp:v1 45.55.81.106:5000/coolapp-arm-linux --arch arm
$ docker manifest push 45.55.81.106:5000/coolapp:v1
Pushed manifest 45.55.81.106:5000/coolapp@sha256:9701edc932223a66e49dd6c894a11db8c2cf4eccd1414f1ec105a623bf16b426 with digest: sha256:f67dcc5fc786f04f0743abfe0ee5dae9bd8caf8efa6c8144f7f2a43889dc513b
Pushed manifest 45.55.81.106:5000/coolapp@sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f with digest: sha256:b64ca0b60356a30971f098c92200b1271257f100a55b351e6bbe985638352f3a
Pushed manifest 45.55.81.106:5000/coolapp@sha256:39dc41c658cf25f33681a41310372f02728925a54aac3598310bfb1770615fc9 with digest: sha256:df436846483aff62bad830b730a0d3b77731bcf98ba5e470a8bbb8e9e346e4e8
Pushed manifest 45.55.81.106:5000/coolapp@sha256:f91b1145cd4ac800b28122313ae9e88ac340bb3f1e3a4cd3e59a3648650f3275 with digest: sha256:5bb8e50aa2edd408bdf3ddf61efb7338ff34a07b762992c9432f1c02fc0e5e62
sha256:050b213d49d7673ba35014f21454c573dcbec75254a08f4a7c34f66a47c06aba
要为Docker客户端配置实验功能,可以在本地设置以下内容$HOME/.docker/config.json
:
{
"auths": { ... },
"experimental": "enabled"
}
请注意,在上文中,如果您执行了docker登录,则auths部分可能已经配置。除了在右括号后添加逗号外,您应保持该部分不变。如果没有auths部分,则从文件中排除该行。
但是,该过程将不支持使用RUN命令使用dockerfiles,这是我的项目的要求。
您可以下载用于不同体系结构的映像,但无法从错误的体系结构运行这些映像。该RUN
命令在构建过程中产生一个临时容器以运行所请求的命令,而该命令将根本无法工作。我知道为另一个体系结构提取映像的唯一原因是将该映像中继到可以使用它们的另一个位置(专用注册表或export + scp),或用于构建多体系结构清单,如您在上面看到的。
这里的重点是在单个主机上构建多个体系结构。我已经看到了使用QEMU实现此目的的博客文章,但是对于每种体系结构,它们都使用不同的基本图像。当基本映像已经是多体系结构映像时,尚不清楚如何执行此操作。
如果您可以不使用任何RUN
步骤构建映像,对映像之外的任何二进制文件使用交叉编译器并且仅执行COPY
将文件添加到新映像中的步骤,则可以在单个主机上创建所有内容。当上游映像是多体系结构时,您需要更深入地挖掘并找到特定于平台的标签以用于上游映像。有几种选择。困难的选择是检查多体系结构标记的清单以查看特定摘要:
$ docker manifest inspect busybox
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 527,
"digest": "sha256:bbb143159af9eabdf45511fd5aab4fd2475d4c0e7fd4a5e154b98e838488e510",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 527,
"digest": "sha256:3d1b11fb001ece2e99556690ce064b07851649582b1f0907649c21e65ba4298f",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v5"
}
},
...
然后,您可以使用特定的摘要标签,例如busybox@sha256:3d1b11fb001ece2e99556690ce064b07851649582b1f0907649c21e65ba4298f
。要以编程方式进行更多操作,可以使用以下命令解析输出jq
:
docker manifest inspect busybox | \
jq '.manifests | .[] | select(.platform.architecture == "arm64") | .digest'
但是,大多数多体系结构映像都包含用于单个体系结构的标签。因此,您将选择该特定标签而不是多体系结构标签。对于官方映像,docker当前在其官方映像repo中记录了特定于体系结构的存储库。