Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make docker image(s) multi-platform and include linux/arm64 #4038

Closed
trentm opened this issue May 24, 2024 · 4 comments · Fixed by #4058
Closed

make docker image(s) multi-platform and include linux/arm64 #4038

trentm opened this issue May 24, 2024 · 4 comments · Fixed by #4058
Assignees

Comments

@trentm
Copy link
Member

trentm commented May 24, 2024

Motivating discussion issue: https://discuss.elastic.co/t/arm-64-apm-attacher-images/359952

To use the APM attacher for Kubernetes (https://www.elastic.co/guide/en/apm/attacher/current/apm-attacher.html) on a k8s deployment on linux/arm64 -- which I'm guessing is an option on the managed k8s services (who wouldn't want to use Graviton, for example?) -- requires that the involved images support the linux/arm64 platform. As well the linux/amd64 platform support should remain.

This means multi-platform Docker images: https://docs.docker.com/build/building/multi-platform/
Which is straightforward in GH actions if already using the docker/build-push-action action, see https://docs.docker.com/build/ci/github-actions/multi-platform/

At the least we need this for the published docker.elastic.co/observability/apm-agent-nodejs image.
Likely we'll need it for the attacher image, docker.elastic.co/observability/apm-attacher, as well. I'm still following up on that.

@trentm trentm self-assigned this May 24, 2024
@trentm
Copy link
Member Author

trentm commented May 24, 2024

nomenclature

A "multi-platform image" is actually a separate Docker image for each platform (each with its own SHA identifier and manifest), and a "manifest list" that is metadata about the included images. This manifest list is the thing that is tagged for reference.

For example, look at the current alpine:latest image:

% docker buildx imagetools inspect alpine:latest
 Name:      docker.io/library/alpine:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:77726ef6b57ddf65bb551896826ec38bc3e53f75cdde31354fbffb4f25238ebd

Manifests:
  Name:      docker.io/library/alpine:latest@sha256:216266c86fc4dcef5619930bd394245824c2af52fd21ba7c6fa0e618657d4c3b
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      docker.io/library/alpine:latest@sha256:4a6ffef76277d8c1d912ad489e0c09ddc09fdf7aefae51750a33dc47478c0cc0
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v6

  Name:      docker.io/library/alpine:latest@sha256:1c3b93ed450e26eac89b471d6d140e2f99488f489739b8b8ea5e8202dd086f82
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64/v8
...

building a multi-platform image locally

(Here are some notes on creating a multi-platform image for apm-agent-nodejs locally on macOS. This is for educational purposes. The real answer will be to make the GH workflow changes to release.yml.)

tl;dr:

./dev-utils/make-distribution.sh   # script that creates "./build/dist/nodejs/"
docker buildx create --name builder --driver=docker-container
docker login
docker buildx build --builder builder --build-arg AGENT_DIR=/build/dist/nodejs --platform linux/amd64,linux/arm64 --push -t $IMAGE_NAME:$IMAGE_TAG .

The Docker docs article https://docs.docker.com/build/building/multi-platform/ shows how to use docker buildx build ... to create multi-platform images. In my case I'm using Docker Desktop which defaults to a "docker" builder that does not support building multi-platform. There are options for other builds. I'm using the docker-container builder option, because that appears to be the option suggested to be used with the docker/build-push-action GH action that we'll eventually be using in CI.

First you need to create a builder. I named it "builder":

docker buildx create --name builder --driver=docker-container

Then use it with the --builder BUILDER-NAME option.
The --platform PLATFORMS option specifies the platforms to include.

docker login   # cat ~/.docker/config.json
docker buildx build --builder builder --build-arg AGENT_DIR=/build/dist/nodejs --platform linux/amd64,linux/arm64 --push -t trentm/enode:5 .

Note that to use the multi-platform image, it needs to be published to a registry. You cannot just have it in your local Docker (e.g. the list of docker images). For my local testing I published to trentm/enode:5 for playing. You can see it at: https://hub.docker.com/repository/docker/trentm/enode/tags

Screenshot 2024-05-24 at 2 10 15 PM

using in GH Actions

My understanding, from https://docs.docker.com/build/ci/github-actions/multi-platform/, is that we will just need:

      # add this step to create the "builder"
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64   # <--- add this
          push: true
          tags: user/app:latest

@trentm
Copy link
Member Author

trentm commented May 24, 2024

note to self: enode10

@heisGarvit
Copy link

@trentm any tentative date? when this will go live?

@trentm
Copy link
Member Author

trentm commented Jun 4, 2024

@heisGarvit Sorry for the delay. I hope to have a fix for this and then a release later this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants