Keep Coding ;¬) Home home
  • Projects build
  • Creating a native Arm builder for Docker buildx Part 2

    Creating a native Arm builder for Docker buildx Part 2

    After getting the USB gadget configured in the previous post, its time to install docker-ce on the device. Because we have an active network connection and docker-ce is an officially supported platform, this is a simple process of following the official installation documentation.

    curl -fsSL https://test.docker.com -o test-docker.sh
    sh test-docker.sh
    

    Docker should now be installed and running, but you won’t be able to contact the docker daemon. This is covered in this post.

    # Add your user to the 'docker' group
    sudo usermod -aG docker $USER
    # You now need to log out and log back in again for this to take effect
    

    Enabling remote access to the docker daemon

    Next you need to allow remote access to the docker daemon. This will depend on the distro you are using, but mine is systemd based, so I follow the instructions in the section configure where the docker daemon listens for connections. I add the endpoint -H tcp://0.0.0.0:2375. This will allow connection from any configured network interface on port 2375.

    So my ExecStart line now looks like

    ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
    

    That should be it for the device configuration. I will loop back in a later post to try and make all of this configuration automatic, because at the moment the USB gadget network interface won’t come online automatically. But we are still very much in the proof-of-concept phase!

    Configuring buildx on the laptop

    You need to be using the latest edge release of docker. In this post, I am using Docker-ce version 19.03.0-rc2, with the buildx version I created in my previous post Docker Buildx from scratch.

    There are many good resources on the web for getting started with buildx, I would recommend reviewing some of them. Or if you are that way inclined, I would recommend reading the documentation at the buildx github.

    We need to create a builder instance for buildx to use when targeting our USB gadget.

    # Create the buildx context
    docker context create --docker "host=tcp://192.168.0.2:2375" armbuilder
    # select the newly created context
    docker context use usbgadget
    # Check everything is working by inspecting the builder context
    docker buildx inspect
    

    The output for me looks like this

    Name:   default
    Driver: docker
    
    Nodes:
    Name:      default
    Endpoint:  armbuilder
    Status:    running
    Platforms: linux/arm64, linux/arm/v7, linux/arm/v6
    

    Now I can re-run the example code I put up in Docker Buildx from scratch. But for now, I only have arm builders configured in this context, so I issue the command

    docker buildx build --platform linux/arm64 -t m5p3nc3r/hello .
    

    And the build will take place on the USB gadget :¬). We can check that the build worked, assuming you have qemu configured correctly on your host PC by running

    docker run m5p3nc3r/hello
    Hello, my architecture is Linux buildkitsandbox 3.14.79-116 #1 SMP PREEMPT Tue Sep 26 01:19:06 BRT 2017 aarch64 Linux
    

    Using the buildkit container for building images

    This setup is not currently using the buildkit container to execute the builds in, this means that we are missing some core functionality like the ability to be able to build the multi-architecture manifest file and push multiple images to hub.docker.com. I have some issues to resolve getting this working..

    To try using the buildkit container, we setup the build context like this

    # Create the buildkit builder referencing our USB gadget
    docker buildx create --name armbuildkit --driver docker-container tcp://192.168.0.2:2375
    # Select the buildx context
    docker  buildx use armbuildkit
    # Inspect the buildx context (note --bootstrap to ensure the remote context is running)
    docker buildx inspect --bootstrap
    

    Where I now see the output

    Name:   armbuildkit
    Driver: docker-container
    
    Nodes:
    Name:      armbuildkit0
    Endpoint:  tcp://192.168.0.2:2375
    Status:    running
    Platforms: linux/arm64, linux/arm/v7, linux/arm/v6
    

    But now when I try the build, I get the following error

     => [internal] load build context                                                                                  1.8s
     => => transferring context: 227B                                                                                 0.0s
     => ERROR [builder 2/5] RUN apk add build-base                                                                    1.0s
     => [stage-1 2/3] WORKDIR /home                                                                                   1.1s
    ------
    > [builder 2/5] RUN apk add build-base:
    #6 0.409 nsenter: could not ensure we are a cloned binary: Operation not supported
    #6 0.976 container_linux.go:345: starting container process caused "process_linux.go:299: copying bootstrap data to pipe caused \"write init-p: broken pipe\""
    ------
    failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c apk add build-base]: exit code: 1
    

    But I am going to leave solving this for another day. The buildkit integration is in beta at the moment, so this may not be a problem with my setup but the code. I’ll file a bug report and see if I can get help getting this resolved.

    Conclusion

    Almost there! A successful first build of an arm image on an arm host :¬).

    As for the next steps, I am going to spend the next session making the setup more robust and easier to work with. Also need to look into what the issue with buildkit is so that we can get the docker-container driver working properly.

    Written on June 21, 2019