크로스아치 Docker 컨테이너가 에뮬레이션을 중지합니다.

크로스아치 Docker 컨테이너가 에뮬레이션을 중지합니다.

QEMU를 사용하여 휴대용 크로스아키 Docker 컨테이너를 구축하려고 합니다. 그러나 호스트 시스템과 호스트에 설치된 프로그램에 따라 컨테이너는 다르게 동작합니다.

Windows에서 컨테이너를 실행하면 에뮬레이션이 제대로 작동합니다. Ubuntu 16.04에서도 잘 작동합니다.언제qemu-user-static이 설치되었습니다. 그러나 그렇지 않은 경우 에뮬레이션이 중지됩니다.

에뮬레이션은 호스트 커널(Linux의 Docker) 또는 VM 커널(Windows의 Docker)에서 binfmt 지원이 활성화되어 있고 컨테이너 파일 시스템에서 필요한 바이너리를 사용할 수 있는 한 작동합니다.

내 목표는 고객이 Host-OS 자체 또는 커널에 대한 수정을 금지하기 때문에 qemu를 커널의 인터프리터로 등록할 필요 없이 컨테이너를 이식 가능하고 실행 가능하게 만드는 것입니다. 그러나 현재는 컨테이너를 실행한 결과입니다.

$ 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(..)를 사용하여 다른 실행 파일을 호출합니다.
  • 리눅스 호스트:
    • 호스트 또는 컨테이너(Linux에서는 호스트와 Docker 게스트가 커널을 공유함)에 의해 binfmt_misc가 활성화된 경우 qemu는 arm64 실행 파일에 대한 인터프리터로 동적으로 할당됩니다.
    • 그렇지 않으면 실행이 실패하고 "Exec 형식 오류"가 발생합니다.
  • Windows 호스트:
    • Windows와 Linux는 서로 다른 커널을 가지고 있으므로 syscall을 호스트 커널에 전달하여 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"]

qemu-aarch64-static은 /usr/bin/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/

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

관련 정보