Keep Coding ;¬) Home home
  • Projects build
  • Configuring Docker for buildx

    Configuring Docker for buildx

    Turns out the Yocto recipes were building docker version 18.09.3, but I need something greater that 19.03.0. I was just about to rework the recipes to update them, but it turns our that the good folks upstream had already done this for me (thanks Bruce for this patch). A quick git pull in the meta-virtualization directory solved all my woes!

    pushd <meta-virtualization directory>
    git pull
    popd
    bitbake core-image-minimal
    # Isn't Open Source Development Great!!!
    

    copy the resulting image onto the sd-card… and docker version now reports 19.03.0-rc3!

    Next we need to update the configuration to expose dockerd to the ethernet connection. This is done by adding the following

    cat << EOF > /etc/docker/daemon.json  
    {
            "hosts": [
                    "unix:///var/run/docker.sock",
                    "tcp://192.168.7.2:2376"
            ],
            "experimental": true
    }
    EOF
    

    It was at this point I noticed something wierd, /etc/docker is a symlink to /run/docker which is a transient directory created in ramfs. This means that each boot of the system resets the contents of /etc/docker so as it stands we can’t keep any static configuration there. The problem comes from this line, and I have a fix in the meta-usbbuilder project. I plan on having a chat with the upstream maintainer about this to see if what is currently upstream is the intended behaviour.

    Copy the resulting build onto the sd-card, reboot and you should now have the docker daemon listening for remote connections on the external TCP interface.

    Resizing the root filesystem

    By default, the image written to the sd-card is only just bigger than the size of the files it needs to place on it. This means that there is not much spare space left on the device. We therefore need to expand the root partition.

    There are two ways we can do this, firstly we could add some configuration to the projects local.conf to ask it to create a bigger image. The problem with this would be that the time to copy it to the sd-card would be increased, and it still wouldn’t necessarily make use of the whole space available.

    The second approach would be to use resize2fs on the live partition. If we mess this up, we risk corrupting the filsyste, but we can simply rewrite the root image to the sd-card to recover. I will look at creating a script to do this automatically at some point. This is the approach I will take here.

    First we need to increase the size of the partition.

    # Use fdisk to modify the partition tables
    fdisk /dev/mmcblk0
    
    # Print the current partiton list with the 'p' command
    Command (m for help): p
    Disk /dev/mmcblk0: 29.12 GiB, 31268536320 bytes, 61071360 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x97800000
    
    Device         Boot Start    End Sectors   Size Id Type
    /dev/mmcblk0p1       2048  34815   32768    16M  c W95 FAT32 (LBA)
    /dev/mmcblk0p2      40960 941813  900854 439.9M 83 Linux
    
    # The important number is the 'Start' of the second partion, mine is
    # 40960
    
    # Delete the second partition
    Command (m for help): d
    Partition number (1,2, default 2): 2
    
    Partition 2 has been deleted.
    
    # Recreate the second partition at the same point as the old once
    # Simply press 'return' when asked about the last sector, and keep
    # the partition signature as it currently is
    Command (m for help): n
    Partition type
       p   primary (1 primary, 0 extended, 3 free)
       e   extended (container for logical partitions)
    Select (default p): p
    Partition number (2-4, default 2): 2
    First sector (34816-61071359, default 34816): 40960
    Last sector, +/-sectors or +/-size{K,M,G,T,P} (40960-61071359, default 61071359):
    
    Created a new partition 2 of type 'Linux' and of size 29.1 GiB.
    Partition #2 contains a ext4 signature.
    
    Do you want to remove the signature? [Y]es/[N]o: n
    
    # Next we have to write out the new partition table
    Command (m for help): w
    
    The partition table has been altered.
    Syncing disks.
    

    That’s the scary bit over, now we simply have to resize the filesystem on the second partition and reboot.

    # Resize the root fileystem
    resize2fs /dev/mmcblk0p2
    resize2fs 1.44.5 (15-Dec-2018)
    Filesystem at /dev/mmcblk0p2 is mounted on /; on-line resizing required
    EXT4-fs (mmcblk0p2): resizing filesystem from 450424 to 30515200 blocks
    old_desc_blocks = 4, new_desc_blocks = 233
    EXT4-fs (mmcblk0p2): resized filesystem to 30515200
    The filesystem on /dev/mmcblk0p2 is now 30515200 (1k) blocks long.
    
    # Reboot
    reboot
    

    You can see from the above log that the root filesystem on /dev/mmcblk0p2 is now about 30G, which is much more healthy!

    Setting up the host buildx configuration

    The device is now function how I wanted it, we need to do some quick configuration of docker on the host machine now.

    # Create a build context called 'usb' and point it at our usb gadget
    docker buildx create --name usb --driver docker-container --platform linux/arm64 tcp://192.168.7.2:2376
    
    # Now tell docker to the newly created build context
    docker buildx use usb
    

    And that should be it… We can test it by using the test application we created in a previous post here.

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

    Conclusion

    From what I can see, it all seems to be working now. Boots on its own, configures itself and makes the docker daemon available for remote access by the host PC, all without human interaction.

    Next steps, which are also tracked here will be

    • Check the power consumption under load
    • Make the root filesystem read only
      • Will ensure the root FS doesn’t corrupt on power cycle
      • Can I use the host for storage?
    • Strip the gadget kernel down to its bare minimum
      • improve boot time
      • decrease power consumption

    But, I think the next task for me, which was suggested by Carl Perry from Packet after a conversation we had at the Arm Partner Meeting in Cambridge last week will be to try porting this to the new Raspberry PI 4 so I can make use of its faster, more efficient Arm Cortex A72 processors. A quick check, and it looks like meta-raspberrypi already has support for the Pi4, so how difficult can it be!

    Written on August 14, 2019