최근 들어 임베디드 보드에서 실행시킬 컨테이너를 만들 필요성이 생겼습니다


현재 주로 사용하는 보드는 rk3399 인데요


도커 이미지를 생성하려면 타겟 보드에서 실행을 해야 하는데 


귀찮은 점이 아주 많았습니다


배포시에도 x86용 arm 용 별도로 빌드를 해야 하는 불편함도 있었구요


그래서 찾아보니 buildx 라는 명령어를 지원하고 있었습니다


크로스빌드 라는 건 쉽게 추측할수 있습니다


사용법은 기존 도커 이미지 빌드와 동일하지만 다른 아키텍쳐의 빌드를 할수 있다는 점이 틀립니다


실행해 보면 


[docker boggle70$ docker buildx ls

NAME/NODE             DRIVER/ENDPOINT             STATUS  PLATFORMS

multi-arch-builder *  docker-container                    

  multi-arch-builder0 unix:///var/run/docker.sock running linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

default               docker                              

  default             default                     running linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6


사용할수 있는 플랫폼이 arm64, armv7, armv6 등...   arm용 32,64 아키텍쳐 모두 지원되네요
이전보다 실행 오류도 깔끔하게 볼수 있고 좋아 진것 같습니다

실행 샘플을 보면 
docker buildx build --platform linux/arm64 -t boggle70/ondevice-ml:4.0 --push .

buildx build
==>> buildx 로 빌드
--platform linux/arm64
==>> 타겟 플랫폼은 arm64 만 선택, 다른 아키텍쳐도 빌드하려면 나열
-t   :   택그 설정
--push  :  빌드후에 repo 에 push 

기존 도커 빌드 하신 분들은 매우 이해하기 쉽고 편리합니다 

타겟 보드에서 실행하면 잘 수행됩니다

falinux@falinux:~$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED        SIZE
boggle70/ondevice-ml-openmp   4.0       d5511aef938a   22 hours ago   3.53GB
boggle70/ondevice-ml-openmp   latest    d5511aef938a   22 hours ago   3.53GB
boggle70/ondevice-ml          4.0       9c8816ab0860   22 hours ago   3.53GB
boggle70/ondevice-ml          latest    9c8816ab0860   22 hours ago   3.53GB
ubuntu                        16.04     d0b7126e0b8c   13 days ago    119MB
ubuntu                        18.04     92177440d3d1   13 days ago    56.6MB


누구나 갖는 궁금함... 그럼 다른 아키텍쳐에서 실행하면 어떻게 되지?
네 그래서 맥북 터미널에서 실행을 해 보았습니다

[docker boggle70$ docker images
REPOSITORY                    TAG               IMAGE ID       CREATED        SIZE
boggle70/ondevice-ml-openmp   latest            1f0167153729   22 hours ago   3.53GB
moby/buildkit                 buildx-stable-1   cf14c5e88c0e   5 weeks ago    123MB

이미지는 다운로드 받을수 있습니다
실행시켜 봅니다

[docker boggle70$ docker run --rm -it --volume="$PWD:/CitiusSynapse" boggle70/ondevice-ml-openmp /bin/bash
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested
root@b8e68c4c4103:/ondevice# 

콘솔이 떨어지고 연결이 됩니다
저는 실행시 /bin/bash 를 실행 시켰는데 해당 실행파일은
root@b8e68c4c4103:/ondevice# file /bin/bash
/bin/bash: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=6ae6024b6f61598e790549e47323f1a3fd67a291, stripped

와 같이 arm 용 실행파일입니다
하지만 실행이 됩니다
이 부분이 이해가 되지 않습니다만...
elf 파일 형식이 같지 않을텐데 어떻게 실행이 되는지 잘 이해가 안되는군요
컨테이너에서 호출된 실행파일의 호출은 라이브러리의 호출 번호에 의해서
호스트의 api가 호출되는 구조라고 한다면 abi 규격이 같은 호출은 실행 될 수도 있겠다
정도만 추측이 됩니다
어쨋든 웬만한 명령어는 실행되는 것을 보면 컨테이너 이미지 안에서 실행되는 구조는
컨테이너의 라이브러리와 호스트의 라이브러리가 동일한 호출 번호를 갖고 있다면 실행될수 있다
정도를 추측할수 있을 것 같습니다
마치 qemu 가상 머신과 같은 상황이라고 보면 비슷할 것 같습니다

당연히 아래 명령이 실행된 결과를 보면 아아... 하실수도 있을 것 같네요
[root@b8e68c4c4103:~# cat /proc/cpuinfo 
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
stepping : 13
cpu MHz : 2300.000
cache size : 16384 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht pbe syscall nx pdpe1gb lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid pni pclmulqdq dtes64 ds_cpl ssse3 sdbg fma cx16 xtpr pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase bmi1 avx2 bmi2 erms xsaveopt arat
bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds
bogomips : 4599.93
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:

cpu 정보를 가져오는 proc 의 경우 호스트 머신으로 전해져서
위와 같이 정보를 전해 줍니다

어쨋든 buildx 를 이용하면 임베디드에서도 다양한 것을 할수 있을 것 같습니다