16.4.도커 Buildx를 사용해 다중 아키텍처 이미지 빌드하기

  • 도커 빌드팜을 훨씬 쉽고 효율적으로 운영하는 방법 Buildx를 사용하는 것이다.
  • Buildx는 docker build 명령의 확장판이라고 생각 하면 되는데, 최적화된 빌드 엔진이 적용돼 빌드 성능이 뛰어나다.
  • Dockerfile 스크립트를 입력받아 이미지를 생성하는 것은 이전과 동일하기 때문에 docker build 명령을 그대로 대체할 수 있다.
  • 크로스 플랫폼 빌드를 지원하며 도커 컨텍스트와 통합돼 있기 때문에 한 번의 명령으로 여러 대의 서버에서 빌드를 진행할 수 있다.
  • Buildx는 아직 윈도 컨테이너를 지원하지 않으며 단일 파일로 된 Dockerfile 스크립트만 지원한다.
  • 이 때문에 아직 모든 빌드 상황에서 docker build 명령을 대체할 수는 없다
  • 하지만 리눅스 이미지의 아키텍처별 변종 이미지를 만들려는 경우에 매우 유용하다.
  • 그리고 이미지 빌드뿐만 아니라 빌드팜을 생성하고 관리하는 용도로도 Buildx를 사용한다.

실습 Play with Docker 웹 사이트에서 새 세션을 시작한다. https://labs.play-with-docker.com에 접근해 새로운 세션에서 두 개의 인스턴스를 추가하라. 모든 명령은 node1을 사용해 내린다. node2의 IP 주소를 저장하고 SSH 접속 가능 여부를 확인한다. 그다음에는 node1과 node2를 대상으로 하는 컨텍스트를 생성한다.

  • Play with Docker에서 실제 분산 빌드팜을 구성
  • 가장 먼저 빌드팜의 각 노드를 가리키는 도커 컨텍스트를 만들어야 한다.
  • 컨텍스트를 미리 만들어 두면 Buildx 설정을 쉽게 할 수 있다.
001) # [node1] (local) root@192.168.0.13
002) # node2의 IP 주소를 지정한다
003) $ node2ip="192.168.0.12"
004) 
005) # SSH 접속 가능 여부를 확인한다
006) $ ssh $node2ip
007) 
008) ###############################################################
009) #                          WARNING!!!!                        #
010) # This is a sandbox environment. Using personal credentials   #
011) # is HIGHLY! discouraged. Any consequences of doing so are    #
012) # completely the user's responsibilites.                      #
013) #                                                             #
014) # The PWD team.                                               #
015) ###############################################################
016) #[node2] (local) root@192.168.0.12
017) # 그 다음에는 exit로 SSH 접속을 종료하고 node1으로 돌아온다
018) $ exit
019) logout
020) Connection to 192.168.0.12 closed.
021) 
022) # [node1] (local) root@192.168.0.13
023) # 로컬 소켓을 통해 node1을 가리키는 컨텍스트를 생성한다
024) $ docker context create node1 --docker "host=unix:///var/run/docker.sock"
025) node1
026) Successfully created context "node1"
027) 
028) # SSH를 통해 node2를 가리키는 컨텍스트를 생성한다
029) $ docker context create node2 --docker "host=ssh://root@$node2ip"
030) node2
031) Successfully created context "node2"
032) 
033) # 컨텍스트 목록에서 컨텍스트가 잘 생성됐는지 확인한다
034) $ docker context ls
035) NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
036) default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock   
037) node1                                                 unix:///var/run/docker.sock   
038) node2                                                 ssh://root@192.168.0.12       
  1. 003~006: Play with Docker에서 생성한 노드는 모두 SSH로 접속 가능하도록 설정된 상태다. 여기서 접속 가능 여부를 확인한다.
  2. 034~038: Buildx에서 이 컨텍스트를 사용해 두 가지 빌드 작업을 동시에 시작할 수 있다.

  3. 빌드팜을 구성하는 과정의 첫 단계는 컨텍스트 생성이다.

  4. 원하는 대상 아키텍처별로 노드를 최소 하나씩 배치하고 각 노드를 가리키는 도커 컨텍스트를 만든다.

실습 Buldx는 도커 명령행 도구의 플러그인이다. 그러므로 Buildx를 사용하려면 플러그인 파일을 내려받아 명령행 도구의 plugin 디렉터리에 복사해야 한다.

001) # Builx 플러그인 파일 다운로드
002) $ mkdir ~/.docker/cli-plugins
003) $ wget -O ~/.docker/cli-plugins/docker-buildx https://github.com/docker/buildx/releases/download/v0.3.1/buildx-v0.3.1.linux-amd64
004) Connecting to github.com (140.82.114.3:443)
005) Connecting to objects.githubusercontent.com (185.199.108.133:443)
006) saving to '/root/.docker/cli-plugins/docker-buildx'
007) docker-buildx        100% |***************************************| 40.0M  0:00:00 ETA
008) '/root/.docker/cli-plugins/docker-buildx' saved
009) 
010) # 플러그인 파일을 실행 가능으로 설정한다
011) $ chmod a+x ~/.docker/cli-plugins/docker-buildx
012) 
013) # 플러그인 파일 준비가 끝났으니 node1로 빌더를 생성한다
014) $ docker buildx create --use --name ch16 --platform linux/amd64 node1
015) ch16
016) 
017) # node2로도 빌더를 생성한다
018) $ docker buildx create --append --name ch16 --platform linux/386 node2
019) ch16
020) 
021) # 빌더 목록을 확인한다
022) $ docker buildx ls
023) NAME/NODE DRIVER/ENDPOINT  STATUS   PLATFORMS
024) ch16 *    docker-container          
025)   ch160   node1            inactive linux/amd64
026)   ch161   node2            inactive linux/386
027) node1     docker                    
028)   node1   node1            running  linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
029) node2     docker                    
030)   node2   node2            running  linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
031) default   docker                    
032)   default default          running  linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
  1. 003: 도커 명령행 도구의 플러그인은 명령행에 새 명령을 추가하는 방식으로 동작한다. 새로 추가된 명령을 실행하면 cli-plugins 디렉터리에 들어 있는 플러그인 바이너리가 실행된다.
  2. 014: node1을 빌더 노드로 등록한다. 빌드 대상 플랫폼은 인텔 64비트 리눅스로 설정한다.
  3. 018: node2를 빌더 노드로 더 추가한다. 빌드 대상 플랫폼은 인텔 32비트 리눅스로 설정한다.
  4. 024~026: 새로 생성한 빌더가 기본으로 설정된다. 또 이 빌더 노드의 빌드 대상 플랫폼 정보도 표시된다. 나머지 빌더는 Buildx가 도커 컨텍스트를 통해 자동으로 인식한 것이다.

  5. node1 은 64 아키텍처 이미지만 빌드하고, node2는 386 아키텍처 이미지만 빌드한다.

  6. 두 아키텍처를 대상으로 하는 Dockerfile 스크립트만 있으면, 이 빌드팜으로 32비트 및 64비트 아키텍처의 리눅스 이미지를 포함하는 다중 아키텍처 이미지를 빌드할 수 있다.
  7. Buildx는 여러 노드에 한꺼번에 Dockerfile 스크립트와 빌드 컨텍스트 디렉터리(대개는 이 디렉터리에 소스 코드가 포함된다)를 보내 병렬로 빌드를 진행한다.

실습 예제 코드 저장소를 복제한 후 folder-list 애플리케이션의 다중 아키텍처 Dockerfile 스크립트가 있는 디렉터리로 이동한다. Buildx를 사용해 각 변종 이미지를 빌드하고 푸시하라.

001) $ git clone https://github.com/sixeyed/diamol.git
002) Cloning into 'diamol'...
003) 
004) $ cd diamol/ch16/exercises/folder-list-2
005) 
006) # 도커 허브 계정 이름을 저장하고 Buildx가 이미지를 푸시할 수 있도록 도커 허브에 로그인한다
007) $ dockerId="woogiereal"
008) 
009) $ docker login -u $dockerId
010) Password:
011) Login Succeeded
012) 
013) # node1과 node2를 모두 사용해 변종 이미지를 동시에 빌드하고 푸시한다
014) $ docker buildx build -t "$dockerId/ch16-folder-list-2" --platform linux/amd64,linux/386 --push .
015) [+] Building 11.3s (19/19) FINISHED                                                    
016)  => [internal] booting buildkit                                                   6.4s
017)  => => pulling image moby/buildkit:buildx-stable-1                                5.0s
018)  => => creating container buildx_buildkit_ch160                                   1.4s
019)  => [internal] booting buildkit                                                   6.9s
020)  => => pulling image moby/buildkit:buildx-stable-1                                5.4s
021)  => => creating container buildx_buildkit_ch161                                   1.5s
022)  ...
023)  => exporting to image                                                            1.4s
024)  => => exporting layers                                                           0.2s
025)  => => exporting manifest list sha256:23b726a8f64f86cd3d659528030d4bc86330d7523d  0.0s
026)  => => pushing manifest for docker.io/woogiereal/ch16-folder-list-2               0.4s
027)  => exporting to image                                                            1.7s
028)  => => exporting layers                                                           0.1s
029)  => => exporting manifest list sha256:c44cbedb672ad2f16e8feb8f92a6ce05d743e60bd0  0.0s
030)  => => pushing manifest for docker.io/woogiereal/ch16-folder-list-2               0.7s
031)  => merging manifest list woogiereal/ch16-folder-list-2                           0.5s

  • Buildx를 사용하면 간단하게 다중 아키텍처 이미지를 빌드할 수 있다.
  • 빌드 서버마다 원하는 대상 플랫폼을 지정해 두면, 이들 모두에 빌드를 지시할 수 있으므로 대상 아키텍처가 두 가지든 열 가지든 빌드 명령은 똑같다.
  • Buildx로 빌드한 후 도커 허브에 푸시한 다중 아키텍처 이미지는 다른 이미지와 한 가지 다른 점이 있는데, 변종 이미지가 자신만의 이미지 태그를 따로 갖지 않고 다중 아키텍처 이미지의 태그 하나만 부여된다는 것이다.
  • 앞 절에서 매니페스트 리스트를 따로 생성해 직접 푸시했던 다중 아키텍처 이미 지에서는 변종 이미지가 각각 이미지 태그를 따로 갖고 있었는데, 이런 경우 변종 이미지 가짓수가 많아지면 사용자가 이미지를 구별하기가 어려워진다.
  • 현재로서는 윈도 컨테이너를 꼭 지원할 필요가 없다면 다중 아키텍처 이미지 빌드에 Buildx를 사용하는 것이 가장 좋다.

links

social