-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add support for building multi-arch docker images with paketo #491
Comments
We do have ARM64 support. It is new and not totally complete across all buildpacks at this point in time. You're using Java buildpacks and those are all updated, so you should be OK. The trick at this point is that you need to use a specific builder. Not all of the Paketo builders support ARM64. The builder you want to use is The other point to note is that this is a "buildpackless" builder, so there are no buildpacks installed on the builder by default. This is intentional, but it means you need to supply a list of buildpacks you want to use when you perform your build. With With the Spring Boot build tools, check out the previous two links above for steps to set buildpacks too. To confirm it's building arm64, watch the build output and look at the JVM it's installing. You should see it install an ARM64 compatible-JVM. For what it's worth, there is no cross-compilation support with either pack or Spring Boot build tools. So if you want an ARM64 image, you need to build on a Mac m-series machine, an ARM64 VM or some other ARM64 system. Hope that helps! |
Hi @dmikusa Thanks for getting back. After making changes as mentioned, seeing following errors
build config
bootbuildImage logs
Can you please take a look? problem is my cicd runners are on both ARM64 & AMD64 machines (same about my deployment servers). so if there is no cross-compilation support i.e. not generate multi-arch builds, it will surely fail on releases. Can you please provide workarounds for this? many thanks |
First thing, you've got some layers that were cached. Usually, caching is good and makes things faster. But in this case, it's not updating those cached layers with ARM64 binaries. I'll open a bug for that, cause it should consider the architecture in that caching decision, but for now, just delete your existing app images and the build cache.
or you can change the image name, that will trigger a fresh build too. I suspect that's going to fix your issue here. It'll give you a build that's consistently all arm64. To your other question, what you can do is to build twice. Once for each architecture. Push those images to a registry as separate images. Then you can use the I'm hoping that in the future we'll have some support for that in |
Thanks for checking and providing insights @dmikusa . I saw something related to this here buildpacks/pack#1570 and hopping this can be adopted |
Any update on this? I'd like to switch from
to |
@heruan Please try Spring Boot 3.4.0. That was recently released and I believe that fixes up the boot build tools to work with multi-platform. |
@dmikusa thanks! I'm testing Spring Boot 3.4.0 and there is a new I can build images for both platforms with different tags running |
@heruan Neither For now, what you can do is build the two images independently and then use a command like If you have a minute and are able to share anything about your use case that would be appreciated. I've been trying to understand how folks are using the tool and building images to help shape how things work in the future. For example, what's your build environment/CI? What type of application are you building? Is it server/data center deployed? Is it used on end-user devices? or deployed by a variety of different people? How do multiple architectures come into play when you or your users are running the generated app image? |
@dmikusa sure, and thank you for the interest on this topic! The image is a Kubernetes Operator built with Spring Boot and the Java Operator SDK as a Maven project. Both architectures are needed since the image is public and might be pulled on AMD or ARM platforms. The image is built during a GitHub Actions workflow running:
Result of this command is a single tag ( I'd like to keep this behavior, so that I get a single tag pushed for both architectures. With Spring Boot, I'm able to run:
and get two images with two different tags, one per platform. At this point, I can push the two tagged images to Docker Hub and then create a I don't know how Ultimately, I'd like to switch to native images and building with Spring Boot and Paketo makes this very easy! I'm not looking for a single command but rather a single tag to get the images published. |
Have you tried removing those tags after you publish the multi-arch image? My understanding is that the container that the index manifest points to needs to exist, but it doesn't need to be tagged. The index should reference the sha hash digest of the images it points to, not the tags. So if you remove the tag, it shouldn't break the index manifest image. We use pack for publishing multi-arch buildpacks & stacks. It handles the multi-arch image generation for us, but we don't end up with stray tagged images. I believe that's how it accomplishes this. The other thing you can do is push your intermediate images to https://ttl.sh or a local registry (maybe only exists in your CI job) and then copy the final manifest image out to Docker Hub. We you copy that out, if you use a tool like crane, it should handle moving everything that's needed for the index image to work correctly. |
That is where things get more difficult. With Java, it's not too hard to cross-compile images for you because the Java code is the same on both architectures, we just need to install different JVMs for each architecture. When you switch to native image, you can't do that anymore because native-image doesn't cross-compile. You need to introduce emulation. I think It's possible that pack could do something similar, but pack is not as integrated with the OS as Docker, so it gets tricky. Do we require something like QEMU? Do we require users to configure that? Does pack take on the responsibility of bundling and setting that up? Can we do that inside a container, so the host OS doesn't require it? Aside from that, performance would be the next concern. Native image compiled in QEMU is like 40x slower (unscientific guesstimate), and it's fairly slow to begin with (IMHO). My guess, at least short term, is the recommendation is going to be to do something like a matrix-style CI build of your different arch images, then stuff them into an index manifest for end-user consumption. Hopefully, we can smooth that out a bit though, and maybe create a way to do that without the intermediate tags. Oh, I also forgot to mention the
|
In mac M1, generated an image for testing SB 3.3 + CDS support using packeto buildpack which is part of bootBuildImage stage. This generated image is given following warning in mac M1 but able to run the app. But if I run the same image on cloud VM which is of type ARM64, it is giving following error and immediately existed with error
exec /cnb/process/web: exec format error
.WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Docker supports, multi arch build with specified arch types so wondering when this can be added to paketo build packs.
The text was updated successfully, but these errors were encountered: