Building a Platform-Agnostic Container Image

Building a Platform-Agnostic Container Image

Process

In general, the process to build a platform-agnostic container image follows the flow depicted on the following figure.

The commands needed to implement the flow are described, using an example, in the next section.



Example using a Python Micro-Service

Main steps

The following diagram captures the main steps we need to take to enable platform-agnostic containers:

(1) and (2) Build and push container images for each platform.

(3)  Create and push a manifest list for the images above

(4) Pull and run the exact same image/tag  on different platforms.

Manifest List and Image Layers

Digging a little bit deeper into step (4), the following diagram shows the relationship between a manifest list and image manifests for our platform-agnostic image (tag).









The following sections describe the commands needed to create a multi-cpu architecture container image. Let's call the image onap/py-app.

Note that this flow could be used by ONAP developers during the development-test-debug process.

For the release process, the flow will implemented using CI/CD pipelines as shown in the next section.

Source code

Code structure

. ├── app │ ├── main.py │ └── requirements.txt └── Dockerfile



Python App

from flask import Flask import platform app = Flask(__name__) @app.route("/") def hello(): return "Hello ONAP. I am a Python service running on " + platform.machine() if __name__ == "__main__": app.run(host='0.0.0.0', debug=True, port=5000)

Requirements

Flask==0.10.1



Dockerfile

FROM python:2.7-alpine LABEL maintainer="adolfo@orangemonk.net" # Keep it simple COPY ./app /app WORKDIR /app RUN pip install -r requirements.txt ENTRYPOINT ["python"] CMD ["main.py"]



Build arm image (A)

Log into an arm server, copy the code into the structure depicted above.

cd to the root of the code tree above,  then execute

docker build -t onap/py-app-arm64 .

Push arm image to the registry

Once the image has been successfully built, push it to the repository.

Note that if you are using a private repository, you might need to "docker tag" the image before executing the next command.

docker push onap/py-app-arm64v8:latest

Build Intel image (B)

Log into an intel server, setup the code structure as before.

Let's now repeat the process for the intel layers of the multi-cpu container image.

docker build -t onap/py-app-amd64 .

Push Intel image to the registry

docker push onap/py-app-amd64:latest

Create a manifest list for image A and image B

Now that we have built and pushed layers for each cpu architecture, we can create the manifest list to put the final container image together with

docker manifest create onap/py-app \ onap/py-app-arm64v8 \ onap/py-app-amd64



Verify that the manifest describes a platform-agnostic container image.



docker manifest inspect --verbose onap/py-app