×
Community Blog ARM Container Applications: Accelerating Development and Testing

ARM Container Applications: Accelerating Development and Testing

This article introduces some simple techniques to accelerate the development and testing processes of ARM container applications.

By Yili

1

With the era of 5G around the corner, highly reduced network latency, improved hardware computing capability of Artificial Intelligence (AI), and rapid growth of intelligent applications, the Internet of Everything is inevitable. Therefore, we must extend the intelligent decision-making capability and the real-time processing capability from the cloud to the edge and to the Internet of Things (IoT) devices.

Alibaba Cloud Container Service already provides edge containers to integrate the cloud, edge, and devices. However, there is a need to support Advanced RISC Machine (ARM) chips as well as x86 chips in IoT and edge computing scenarios. While the home-grown ARM CPUs are rapidly developing, ARM-based containers should also get ready.

This article introduces some simple techniques to speed up the development and testing processes of ARM container applications.

Build an ARM-based Docker Image in the x86 Environment

Recently, Docker and ARM announced their partnership program for optimizing Docker tools to improve developers' experience on the ARM platform. Docker developers build container images for ARM devices on the x86 desktop and deploy container applications onto the cloud, edge, and IoT devices. The entire container building process is very simple without cross-compilation steps.

Docker Desktop is a container development environment for macOS and Windows platforms. Docker uses the virtualization technologies in the host's operating system, such as Hyper-V on Windows or HyperKit on MacOS, to run the Docker development environment. To support ARM CPUs, the latest Docker version adds the QEMU simulator to the container-dedicated operating system, LinuxKit. Currently, applications based on the ARM/v6, ARM/v7, and ARM64 architectures are supported. The architectural diagram is as follows:

2

Now, let's take a look at the steps to build an ARM-based Docker Image in the x86 environment.

First, install the latest edge version of Docker Desktop. Note that the Docker Engine version must be later than version 19.03.

3

Enable the experimental features in Docker Desktop by choosing Preference... > Command-Line > Enable experimental features.

4

Add the docker buildx command to Docker as shown below.

$ docker buildx --help

Usage:  docker buildx COMMAND

Build with BuildKit

Management Commands:
  imagetools  Commands to work on images in registry

Commands:
  bake        Build from a file
  build       Start a build
  create      Create a new builder instance
  inspect     Inspect current builder instance
  ls          List builder instances
  rm          Remove a builder instance
  stop        Stop builder instance
  use         Set the current builder instance
  version     Show buildx version information

Run 'docker buildx COMMAND --help' for more information on a command.

The following snippet shows the current status of the builder.

$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker
  default default         running linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6

Create a mybuilder instance as the default builder, and activate the ARM building capability.

$ docker buildx create --name mybuilder
mybuilder
$ docker buildx use mybuilder
$ docker buildx inspect --bootstrap
[+] Building 20.2s (1/1) FINISHED
 => [internal] booting buildkit                                           20.2s
 => => pulling image moby/buildkit:master                                 19.6s
 => => creating container buildx_buildkit_mybuilder0                       0.6s
Name:   mybuilder
Driver: docker-container
Nodes:
Name:      mybuilder0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6

Obtain the test application from GitHub using the commands below.

$ git clone https://github.com/adamparco/helloworld
$ cd helloworld

Next, create a test repository in Docker Hub.

5

With the support of the new image mediaType manifest list, Docker implements the multi-architecture Docker imaging feature since Docker registry v2.3 and Docker 1.10. This feature allows one image to contain imaging layers in various CPU architectures.

Build a multi-CPU architecture image for the test application, including the support for x86, ARM64, and ARMv7, and then push it to Docker Hub.

$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t denverdino/multiarch --push .
  .
[+] Building 26.1s (31/31) FINISHED
...
 => [linux/arm64 internal] load metadata for docker.io/library/python:3.7-alpine                                                                                                                                                         2.9s
 => [linux/arm/v7 internal] load metadata for docker.io/library/python:3.7-alpine                                                                                                                                                        3.2s
 => [linux/amd64 internal] load metadata for docker.io/library/python:3.7-alpine                                                                                                                                                         2.9s
...
 => exporting to image                                                                                                                                                                                                                  22.8s
 => => exporting layers                                                                                                                                                                                                                  1.0s
 => => exporting manifest sha256:f8739d2eb9f1b043e5d44e962c79d353261a257ffa6c8332b762b5d811d54c1a                                                                                                                                        0.0s
 => => exporting config sha256:528fc30a95957bf3c6c1bb4ea77793a2a484c0c5b87f3efad6bbc9dbc2df6a90                                                                                                                                          0.0s
 => => exporting manifest sha256:b52df7ab39acbe3ebb8b5d9e6a8069b9c916f1811b81aa84dd3b9dd9b4304536                                                                                                                                        0.0s
 => => exporting config sha256:9712542f20d1dd16c7332f664432a1b37c6254fefe7d4cb7806b74997467da07                                                                                                                                          0.0s
 => => exporting manifest sha256:698969718e9a316003a7fb4c2fe26216c95672e3e92372d25b01a6db5295e9e7                                                                                                                                        0.0s
 => => exporting config sha256:f636eaa8cec74fa574f99318cddd01b37a9e7c21708f94e11ae6575b34ca18f7                                                                                                                                          0.0s
 => => exporting manifest list sha256:3da22eea857f889ade3c85a2d41ed17db727385f78096e3dcf74ae039f164281                                                                                                                                   0.0s
 => => pushing layers                                                                                                                                                                                                                   18.3s
 => => pushing manifest for docker.io/denverdino/multiarch:latest

The following snapshot of Docker Hub shows the image information.

6

Run the built image on a macOS machine as shown below.

$ docker run -p5000:5000 denverdino/multiarch
 * Serving Flask app "hello" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Visit http://0.0.0.0:5000/ to confirm that the current CPU architecture is x86_64.

7

Log on to a Raspberry Pi, which runs on ARMv7-based Raspbian, and execute the following command to run the same container image.

pi@raspberrypi:~ $ docker run -p5000:5000 denverdino/multiarch
* Serving Flask app "hello" (lazy loading)
* Environment: production
  WARNING: Do not use the development server in a production environment.
  Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Open a browser and visit Raspberrypi:5000 to see that the current CPU architecture is ARMv7l.

8

Run an ARM-based Docker Image in the x86 Environment

Begin with building an ARMv7 image as shown below.

docker buildx build --platform linux/arm/v7 -t denverdino/multiarch:armv7 --push .
[+] Building 67.9s (13/13) FINISHED
...
 => => pushing layers                                                                                                                                                                                                                    8.5s
 => => pushing manifest for docker.io/denverdino/multiarch:armv7

In the Linux kernel, register an "interpreter" using binfmt_misc. Call the custom interpreter when running an executable file. In Linux 4.8, the F flag is added to Binfmt_misc to allow the kernel to load the interpreter during configuration instead of during running. This feature is known as lazy load. This helps to register and run the interpreter for the ARM instruction set by using containers.

$ docker run --rm --privileged npmccallum/qemu-register

Run the following command on a macOS machine. An ARM image starts without making any modifications.

$ docker run -p5000:5000 denverdino/multiarch:armv7
 * Serving Flask app "hello" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Visit http://0.0.0.0:5000 to confirm that the current CPU architecture is ARMv7l.

9

Summary

The article concludes that the integration of containers, operating systems, and virtualization technologies simplifies the support for multi-CPU architecture-based applications. Such integration allows to easily build and test ARM applications on the x86 platform.

References

0 0 0
Share on

Alibaba Container Service

59 posts | 15 followers

You may also like

Comments

Alibaba Container Service

59 posts | 15 followers

Related Products

  • Container Registry

    A secure image hosting platform providing containerized image lifecycle management

    Learn More
  • Container Service

    A high-performance container manage service that provides containerized application lifecycle management

    Learn More
  • Container Service for Kubernetes

    Alibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.

    Learn More
  • ECI(Elastic Container Instance)

    Elastic Container Instance (ECI) is an agile and secure serverless container instance service. You can easily run containers without managing servers. Also you only pay for the resources that have been consumed by the containers. ECI helps you focus on your business applications instead of managing infrastructure.

    Learn More