有人可以用简单的术语解释一下什么是
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
Run Code Online (Sandbox Code Playgroud)
docker build在从 Dockerfile执行容器之前调用时执行什么操作?
我的想法是允许将其他架构的容器使用到 X86 架构中,但我不确定我是否完全理解我在某些网站上找到的解释。
上述指令( )的存在是否docker run意味着构建阶段的Dockerfile是针对另一种架构的?
cri*_*ret 16
我最近也有这个问题,我没有完整的答案,但这是我所知道的,或者至少相信:
设置的魔力 - 每次重新启动系统都需要一次,就是这样:
# start root's docker (not via any `-rootless` scripts, obviously)
sudo systemctl start docker
# setup QEMU static executables formats
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# test
docker run --rm -t arm64v8/ubuntu uname -m
# shoudl expect:
# >> aarch64
# optional: shutdown root's docker
sudo systemctl stop docker
Run Code Online (Sandbox Code Playgroud)
请注意,测试示例假设您正在运行您自己的个人“rootless-” docker,因此作为您自己,而不是作为root(也不是via sudo),并且它工作得很好。
...如果您想了解其工作方式/原因,这很重要。
此信息的主要来源:
buildx构建多/跨架构图像)qemu-user-static)实现这项工作的基本技巧是将新的“神奇”字符串安装到内核进程空间中,以便当(ARM)可执行文件在 docker 映像内运行时,它可以识别 bin-fmt 并使用 QEMU 解释器(来自multiarch/*docker image) 来执行它。在我们设置 bin 格式之前,内容如下所示:
root@odysseus # mount | grep binfmt_misc
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=45170)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
root@odysseus # ls /proc/sys/fs/binfmt_misc/
jar llvm-6.0-runtime.binfmt python2.7 python3.6 python3.7 python3.8 register sbcl status
Run Code Online (Sandbox Code Playgroud)
在我们启动(root)dockerd并设置格式后:
root@odysseus # systemctl start docker
root@odysseus # docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
Setting /usr/bin/qemu-alpha-static as binfmt interpreter for alpha
Setting /usr/bin/qemu-arm-static as binfmt interpreter for arm
[...]
root@odysseus # ls /proc/sys/fs/binfmt_misc/
jar python3.8 qemu-armeb qemu-microblazeel qemu-mipsn32 qemu-ppc64le qemu-sh4eb qemu-xtensaeb
llvm-6.0-runtime.binfmt qemu-aarch64 qemu-hexagon qemu-mips qemu-mipsn32el qemu-riscv32 qemu-sparc register
python2.7 qemu-aarch64_be qemu-hppa qemu-mips64 qemu-or1k qemu-riscv64 qemu-sparc32plus sbcl
python3.6 qemu-alpha qemu-m68k qemu-mips64el qemu-ppc qemu-s390x qemu-sparc64 status
python3.7 qemu-arm qemu-microblaze qemu-mipsel qemu-ppc64 qemu-sh4 qemu-xtensa
Run Code Online (Sandbox Code Playgroud)
现在我们可以运行 ARM 版本的 ubuntu:
root@odysseus # docker run --rm -t arm64v8/ubuntu uname -m
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested
aarch64
Run Code Online (Sandbox Code Playgroud)
该警告是预料之中的,因为主机 CPU 是 AMD,并且可以通过为 docker 指定平台来消除该警告:
root@odysseus # docker run --rm --platform linux/arm64 -t arm64v8/ubuntu uname -m
aarch64
Run Code Online (Sandbox Code Playgroud)
其基础是 QEMU 能够插入 DBM(动态二进制修改)解释器,将一个系统的指令集转换为底层平台的指令集。
我们要做的唯一技巧是告诉底层系统在哪里可以找到这些解释器。这就是qemu-user-static图像在注册二进制格式魔术字符串/解释器时所做的事情。那么,那些里面有什么binfmt?
root@odysseus # cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64-static
flags: F
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
Run Code Online (Sandbox Code Playgroud)
嗯 - 这很有趣,特别是因为在主机系统上没有, /usr/bin/qemu-aarch64-static而且它也不在目标映像中,那么这个东西位于哪里?它位于qemu-user-static图像本身中,具有以下形式的适当标记:<HOST-ARCH>-<GUEST-ARCH>,如 中所示multiarch/qemu-user-static:x86_64-aarch64。
root@odysseus # mount | grep binfmt_misc
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=45170)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
root@odysseus # ls /proc/sys/fs/binfmt_misc/
jar llvm-6.0-runtime.binfmt python2.7 python3.6 python3.7 python3.8 register sbcl status
Run Code Online (Sandbox Code Playgroud)
这就是我还不太明白的真正魔法。我相信,不知何故docker,使用该映像来启动 QEMU 解释器,然后从您想要运行的实际映像/容器中向其提供代码,如uname前面的示例所示。一些网络搜索让我对如何实现这种魔法感到不满意,但我猜如果我继续关注这里的链接,我可能会找到这种小手的真正来源。
| 归档时间: |
|
| 查看次数: |
7411 次 |
| 最近记录: |