아키텍처 간 Docker 컨테이너의 에뮬레이션이 중지됩니다.

아키텍처 간 Docker 컨테이너의 에뮬레이션이 중지됩니다.

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/

시뮬레이션을 계속하려면 어떻게 해야 합니까?

관련 정보