Bug Description
The linux/arm64 variant of the Alpine container image ships an x86-64 userland. The proxy binary itself is correctly cross-compiled for arm64, but busybox, apk, and everything else is x86-64. On arm64 nodes, /bin/sh and all other tools fail with exec format error, and the proxy's --fuse mode is broken because fusermount is an x86-64 binary.
Root cause: the final stage of Dockerfile.alpine pins alpine:3 to an amd64-specific image manifest digest instead of the multi-arch index digest. Digest pinning bypasses buildx platform selection, so the --platform linux/arm64 build silently uses the amd64 rootfs. The pin is unchanged at v2.24.1, so current releases are affected.
The removed bookworm variant (#2630) had the identical defect (see step 3 below), which suggests the digest-update automation systematically resolves platform manifest digests instead of index digests. Suggested fix: pin the index digest for alpine:3 (the tag already publishes linux/arm64 in its manifest list), and fix the automation so the pin does not regress on the next update.
Example code (or command)
# Dockerfile.alpine (unchanged as of v2.24.1) — final stage pins an
# amd64-only manifest digest:
FROM alpine:3@sha256:79ff19e9084a00eece421b2523fb93e22d730e2c0e525905de047e848e56d95f
# Runtime symptom on an arm64 node:
$ kubectl exec -it <pod> -c cloud-sql-proxy -- /bin/sh
exec /bin/sh: exec format error
Stacktrace
Steps to reproduce?
No arm64 hardware is required; everything below inspects the published images with crane.
- Compare the base rootfs layer of the amd64 and arm64 manifests. They are identical, which is impossible for a correct multi-arch build:
IMG=gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.23-alpine
crane manifest $IMG | jq -r '.manifests[] | select(.platform.os == "linux") | "\(.platform.architecture) \(.digest)"'
# then, for each digest:
crane manifest gcr.io/cloud-sql-connectors/cloud-sql-proxy@<digest> | jq -r '.layers[0].digest'
# Observed:
# amd64 layers[0] = sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4
# arm64 layers[0] = sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4
# (the alpine 3.24.1 x86_64 minirootfs layer)
- Confirm that busybox in the arm64 image is an x86-64 ELF:
$ crane export --platform linux/arm64 $IMG - | tar -xO bin/busybox | head -c 20 | xxd
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 ..>.
# e_machine = 0x3e (EM_X86_64); aarch64 would be 0xb7
- (Optional) Confirm the same pattern in the removed bookworm variant:
# 2.23-bookworm shares its base layer across platforms:
# amd64 (sha256:06b15bd1b81bb27956d45da63d574010258ca14f605dbc79e446d6b742873461)
# layers[0] = sha256:20face757db20cd2eddf8149ec7d6b4f1630481ae00d25ad6396bcc5bef5b082
# arm64 (sha256:d80cd7c7689e6e56d76b8f4248513910cc09747eb66d8a91b3e5aef343bbe16a)
# layers[0] = sha256:20face757db20cd2eddf8149ec7d6b4f1630481ae00d25ad6396bcc5bef5b082
- (Optional) On any arm64 host, run a shell in the image to observe
the runtime failure:
docker run --rm -it --entrypoint /bin/sh gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.23-alpine
# exec /bin/sh: exec format error
Environment
- Image:
gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.23-alpine (linux/arm64 variant); Dockerfile.alpine carries the same pin at v2.24.1, so current releases are affected as well
- Host: any linux/arm64 node (e.g. GKE arm64 node pools); the defect is also verifiable host-independently with
crane as above
- Tools used for verification:
crane, jq, xxd
Additional Details
No response
Bug Description
The linux/arm64 variant of the Alpine container image ships an x86-64 userland. The proxy binary itself is correctly cross-compiled for arm64, but busybox, apk, and everything else is x86-64. On arm64 nodes,
/bin/shand all other tools fail withexec format error, and the proxy's--fusemode is broken becausefusermountis an x86-64 binary.Root cause: the final stage of
Dockerfile.alpinepinsalpine:3to an amd64-specific image manifest digest instead of the multi-arch index digest. Digest pinning bypasses buildx platform selection, so the--platform linux/arm64build silently uses the amd64 rootfs. The pin is unchanged at v2.24.1, so current releases are affected.The removed bookworm variant (#2630) had the identical defect (see step 3 below), which suggests the digest-update automation systematically resolves platform manifest digests instead of index digests. Suggested fix: pin the index digest for
alpine:3(the tag already publishes linux/arm64 in its manifest list), and fix the automation so the pin does not regress on the next update.Example code (or command)
Stacktrace
Steps to reproduce?
No arm64 hardware is required; everything below inspects the published images with
crane.the runtime failure:
docker run --rm -it --entrypoint /bin/sh gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.23-alpine # exec /bin/sh: exec format errorEnvironment
gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.23-alpine(linux/arm64variant);Dockerfile.alpinecarries the same pin atv2.24.1, so current releases are affected as wellcraneas abovecrane,jq,xxdAdditional Details
No response