QEMU를 사용하여 이식 가능한 크로스 아키텍처 Docker 컨테이너를 구축하려고 합니다. 그러나 컨테이너는 호스트 시스템과 호스트에 설치된 프로그램에 따라 다르게 동작합니다.
Windows에서 컨테이너를 실행하면 시뮬레이션이 제대로 작동합니다. 우분투 16.04에서도 잘 돌아갑니다언제qemu-user-static이 설치되었습니다. 하지만 그렇지 않은 경우 시뮬레이션이 중지됩니다.
호스트 커널(Linux의 Docker) 또는 가상 머신 커널(Windows의 Docker)에서 binfmt 지원이 활성화되어 있고 필요한 바이너리가 컨테이너 파일 시스템에서 사용 가능한 한 시뮬레이션은 작동합니다.
내 목표는 qemu를 커널의 인터프리터로 등록하지 않고도 컨테이너를 이식 가능하고 실행 가능하게 만드는 것입니다. 고객은 호스트 OS 자체 또는 커널에 대한 수정을 금지하기 때문입니다. 그러나 현재 컨테이너를 실행한 결과는 다음과 같습니다.
$ sudo docker run -ti qemu:xenial_arm64
qemu-aarch64-static: /usr/bin/groups: cannot execute binary file: Exec format error
/usr/bin/lesspipe: line 28: /usr/bin/basename: cannot execute binary file: Exec format error
/usr/bin/lesspipe: line 282: /usr/bin/dirname: cannot execute binary file: Exec format error
/usr/bin/lesspipe: line 295: [: =: unary operator expected
qemu-aarch64-static: /usr/bin/dircolors: cannot execute binary file: Exec format error
root@41f2795e2569:/# uname -m
qemu-aarch64-static: /bin/uname: cannot execute binary file: Exec format error
그러나 qemu-user-static을 설치하면(qemu를 설치하면 binfmt_misc에서도 활성화됩니다):
$ sudo apt-get -yqq install qemu-user-static
Selecting previously unselected package qemu-user-static.
(Reading database ... 245713 files and directories currently installed.)
Preparing to unpack .../qemu-user-static_1%3a2.5+dfsg-5ubuntu10.42_amd64.deb ...
Unpacking qemu-user-static (1:2.5+dfsg-5ubuntu10.42) ...
Processing triggers for man-db (2.7.5-1) ...
Setting up qemu-user-static (1:2.5+dfsg-5ubuntu10.42) ...
$ sudo docker run -ti qemu:xenial_arm64
root@7903b45a3c1e:/# uname -m
aarch64
이에 대한 나의 설명은 다음과 같습니다.
- qemu-aarch64-static이 /bin/bash 시뮬레이션을 시작합니다.
- /bin/bash는 execve(..)를 사용하여 다른 실행 파일을 호출합니다.
- 리눅스 호스트:
- 호스트 또는 컨테이너에 binfmt_misc가 활성화된 경우(Linux에서는 호스트와 Docker 게스트가 커널을 공유함) qemu가 arm64 실행 파일에 대한 인터프리터로 동적으로 할당됩니다.
- 그렇지 않으면 "Exec 형식 오류"로 인해 실행이 실패합니다.
- Windows 호스트:
- Windows와 Linux는 커널이 다르기 때문에 호스트 커널에 시스템 호출을 전달하여 Linux 게스트를 실행할 수 없습니다.
- 따라서 Windows에서는 컨테이너가 별도의 커널을 사용하여 VM 내에서 실행되고 해당 커널이 컨테이너와 공유됩니다.
- binfmt-support가 포함된 qemu-user-static이 컨테이너에 설치되고 활성화되면 여전히 해당 목적을 수행할 수 있으며 qemu를 다른 아키텍처의 실행 파일에 대한 인터프리터로 동적으로 할당할 수 있습니다.
Linux와 Windows에서 실행하면 동일한 결과가 나타납니다.
가능한 해결 방법은 --privileged 플래그를 사용하여 컨테이너를 시작하는 것입니다. 그런 다음 binfmt_misc를 마운트하고 qemu-user-static을 컨테이너 내의 인터프리터로 등록할 수 있습니다. 그러나 당사 고객은 이 로고를 사용하는 것이 금지되어 있습니다.
설명된 방법을 테스트했습니다.여기qemu-user의 경우 -0 플래그입니다. 둘 다 작동하지 않습니다.
도커파일:
FROM scratch
ADD xenial-arm64-rootfs /
ADD qemu-aarch64-static /usr/bin/qemu-aarch64-static
RUN chmod +x /usr/bin/qemu-aarch64-static
ENTRYPOINT ["/usr/bin/qemu-aarch64-static", "-0", "/usr/bin/qemu-aarch64-static"]
CMD ["/bin/bash"]
/usr/bin/qemu-aarch64-static에서 가져온 qemu-aarch64-static(qemu-user-static으로 설치) xenial-arm64-rootfs 생성:
qemu-debootstrap --arch=arm64 --components=main,universe,multiverse,restricted --variant=buildd --foreign xenial xenial-arm64-rootfs http://ports.ubuntu.com/ubuntu-ports/
시뮬레이션을 계속하려면 어떻게 해야 합니까?