-
Notifications
You must be signed in to change notification settings - Fork 141
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
Tagging of multiarch images on gcr #82
Tagging of multiarch images on gcr #82
Conversation
Hi @vitt-bagal. Thanks for your PR. I'm waiting for a kubernetes-csi member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/cc @pohly @namrata-ibm @dims |
@vitt-bagal: GitHub didn't allow me to request PR reviews from the following users: namrata-ibm, dims. Note that only kubernetes-csi members and repo collaborators can review this PR, and authors cannot review their own PRs. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that this moves the build rules into the Makefile, that'll make it easier to share them between repos and just have the bare minimum cloudbuild.yaml
in each repo separately.
However, we cannot merge a modified release-tools/build.make
into node-driver-registrar because "no local modifications in release-tools" is enforced by a test. Instead, we need to do one more round of experimentation where the new push-multiarch
is put into the top-level Makefile
. If that works, we can copy it to csi-release-tools
.
release-tools/build.make
Outdated
@@ -12,7 +12,8 @@ | |||
# See the License for the specific language governing permissions and | |||
# limitations under the License. | |||
|
|||
.PHONY: build-% build container-% container push-% push clean test | |||
# Added push-multiarch to build and push multiarch image |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That comment can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed comment
release-tools/build.make
Outdated
@@ -52,6 +53,7 @@ IMAGE_TAGS+=$(shell tagged="$$(git describe --tags --match='v*' --abbrev=0)"; if | |||
|
|||
# Images are named after the command contained in them. | |||
IMAGE_NAME=$(REGISTRY_NAME)/$* | |||
MULTIARCH_IMAGE_NAME=gcr.io/k8s-staging-csi/$* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a separate MULTIARCH_IMAGE_NAME
. Just use IMAGE_NAME
and make sure that cloudbuild.yaml
overrides it with make push-multiarch REGISTRY_NAME=gcr.io/k8s-staging-csi
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed MULTIARCH_IMAGE_NAME
extra variable. Added REGISTRY_CI
env variable in cloudbuild to override REGISTRY_NAME
value in makefile
release-tools/build.make
Outdated
|
||
push-multiarch-%: | ||
export DOCKER_CLI_EXPERIMENTAL=enabled | ||
make BUILD_PLATFORMS="windows amd64 .exe" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make build for windows is required as Windows binary is needed to copy it in windows dockerfile
release-tools/build.make
Outdated
RELEASE_ALIAS_TAG=$(PULL_BASE_REF) | ||
|
||
push-multiarch-%: | ||
export DOCKER_CLI_EXPERIMENTAL=enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't do anything, the variable is getting set and the shell in which it was set exits. You need to join the lines with ; \
:
push-multiarch-%:
gcloud auth configure-docker
set -ex; \
DOCKER_CLI_EXPERIMENTAL=enabled; \
export DOCKER_CLI_EXPERIMENTAL; \
docker buildx create --use --name multiarchimage-buildertest; \
pushMultiArch () { \
I intentionally avoided export DOCKER_CLI_EXPERIMENTAL=enabled
because that only works in bash.
release-tools/build.make
Outdated
set -ex; \ | ||
pushMultiArch () { \ | ||
tag=$$1 ;\ | ||
docker buildx build --push -t $(MULTIARCH_IMAGE_NAME):amd64-linux-$$tag --platform=linux/amd64 -f Dockerfile.multiarch . ;\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We loose the ability here to build different images in the same repo with different Docker files. Can you add something similar to build-%
where it locates the Docker file with $(shell if [ -e ./cmd/$*/Dockerfile ]; then echo ./cmd/$*/Dockerfile; else echo Dockerfile; fi)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated docker buildx build
command using approach of locating file.
release-tools/build.make
Outdated
}; \ | ||
if [ $(RELEASE_ALIAS_TAG) = "master" ]; then \ | ||
: "creating or overwriting canary image"; \ | ||
pushMultiArch canary ; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For canary images, the rev
label used to specify the source code revision (= result of git describe). This is useful to determine what the image contains because there is no other indicator.
Can this be done also for cloud builds? If we override REV
in cloudbuild.yaml
, then we can simply use --label rev=$(REV)
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As rev
value from git describe command(build.make) is same as tag-n-hash
value from _GIT_TAG( vYYYYMMDD-tag-n-hash form). Added code to extract tag-n-hash
value from REV(REV_CI cloudbuild env)in push-multiarch target and passing this as label value to docker build.
release-tools/build.make
Outdated
@@ -101,9 +106,42 @@ push-%: container-% | |||
fi; \ | |||
done | |||
|
|||
RELEASE_ALIAS_TAG=$(PULL_BASE_REF) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introducing another name for PULL_BASE_REF
IMHO obscures what's going on. Better just use PULL_BASE_REF
directly below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed RELEASE_ALIAS_TAG
. Using PULL_BASE_REF
directly in push-multiarch target
cloudbuild.yaml
Outdated
@@ -12,28 +12,17 @@ steps: | |||
env: | |||
- DOCKER_CLI_EXPERIMENTAL=enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed now, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
cloudbuild.yaml
Outdated
@@ -12,28 +12,17 @@ steps: | |||
env: | |||
- DOCKER_CLI_EXPERIMENTAL=enabled | |||
- VERSION=$_GIT_TAG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of exporting an unused VERSION env variable, can we use this to override the useless REV
make variable, like this:
make push-multiarch 'REV=$_GIT_TAG'
Or do substitutions only work under env
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added changes in Makefile to override REV value with REV_CI value passed as env in cloudbuild
do substitutions only work under env?
I am also not sure about how substitutions works. May be you can tag someone who can comment on this
release-tools/build.make
Outdated
@@ -69,6 +71,9 @@ endif | |||
# toolchain. | |||
BUILD_PLATFORMS = | |||
|
|||
# To enable experimental features on the Docker daemon | |||
export DOCKER_CLI_EXPERIMENTAL:=enabled |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO this is better done locally in push-multiarch-%.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this in push-multiarch target
@pohly Thanks for review comment. Added few changes as per your suggestions. |
Makefile
Outdated
make BUILD_PLATFORMS="windows amd64 .exe" | ||
set -ex; \ | ||
gcloud auth configure-docker; \ | ||
label_rev=v$$(echo $(REV) | cut -f3- -d 'v'); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this specific to the cloud build? Then put it into cloudbuild.yaml
and explain what it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved rev calculation to cloudbuild.yaml
Makefile
Outdated
# Override registry, revision and Images | ||
REV=$(REV_CI) | ||
REGISTRY_NAME=$(REGISTRY_CI) | ||
IMAGE_NAME=$(REGISTRY_NAME)/$* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do this without REGISTRY_CI
and REV_CI
? The goal is to write a make target that can be copied 1:1 into release-tools/build.make
, with as few special cases as possible.
You can use REV
and REGISTRY_NAME
and override them with make REV=... REGISTRY_NAME=...
in the cloudbuild.yaml
invocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed extra CI variables. Updated push-multiarch invocation as make push-multiarch REV=v$(echo $_GIT_TAG | cut -f3- -d 'v') REGISTRY_NAME=gcr.io/k8s-staging-csi
in cloudbuild
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs further work before it's ready for csi-release-tools, but should be good enough for another test run.
/ok-to-test
/approve
/lgtm
# Currently amd, s390x and Windows manifest is pushed for canary, release branch and released tags. | ||
# Images generated from Prow build are pushed to staging area on gcr | ||
push-multiarch-%: | ||
make BUILD_PLATFORMS="windows amd64 .exe" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not sure what this make
invocation is needed for.
Ah, it's because Dockerfile.Windows
doesn't build its binary. We probably should fix this and ideally remove the special Dockerfile for Windows entirely. But this can probably wait until later. We have to sort it out before including it in csi-release-tools.
@ddebroy: is there a chance to use gcr.io/distroless/static:latest
as base for a Windows image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to use buildx to build windows image on a linux machine, we cannot include any RUN command in the Dockerfile, so I think this limitation means we cannot build binary as a step in Dockerfile.
docker buildx create --use --name multiarchimage-buildertest; \ | ||
pushMultiArch () { \ | ||
tag=$$1; \ | ||
docker buildx build --push -t $(IMAGE_NAME):amd64-linux-$$tag --platform=linux/amd64 -f $(shell if [ -e ./cmd/$*/Dockerfile.multiarch ]; then echo ./cmd/$*/Dockerfile.multiarch; else echo Dockerfile.multiarch; fi) --label revision=$(REV) .; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps create a local variable dockerfile=$(shell if [ -e ./cmd/$*/Dockerfile.multiarch ]; then echo ./cmd/$*/Dockerfile.multiarch; else echo Dockerfile.multiarch; fi)
above and use it here and below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can use this once windows is also a part of Dockerfile.multiarch
. otherwise we have to set an extra variable for windows dockerfile too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any way we can make the list of linux platforms as a variable instead of hard coding the command for each platform?
Unfortunately I don't think there's much we can do to generalize windows atm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently with the help of this PR we are just testing that whether push-multiarch (keeping cloudbuild minimal) can be used to correctly tag multiarch images.
Once all these changes are working fine as expected then we can modify docker buildx command as docker buildx build --push -t $(IMAGE_NAME):$$tag --platform=linux/amd64,linux/s390x -f ...
which will have single docker buildx command for linux (with multiaple arch)
tag=$$1; \ | ||
docker buildx build --push -t $(IMAGE_NAME):amd64-linux-$$tag --platform=linux/amd64 -f $(shell if [ -e ./cmd/$*/Dockerfile.multiarch ]; then echo ./cmd/$*/Dockerfile.multiarch; else echo Dockerfile.multiarch; fi) --label revision=$(REV) .; \ | ||
docker buildx build --push -t $(IMAGE_NAME):s390x-linux-$$tag --platform=linux/s390x -f $(shell if [ -e ./cmd/$*/Dockerfile.multiarch ]; then echo ./cmd/$*/Dockerfile.multiarch; else echo Dockerfile.multiarch; fi) --label revision=$(REV) .; \ | ||
docker buildx build --push -t $(IMAGE_NAME):amd64-windows-$$tag --platform=windows -f $(shell if [ -e ./cmd/$*/Dockerfile.Windows ]; then echo ./cmd/$*/Dockerfile.Windows; else echo Dockerfile.Windows; fi) --label revision=$(REV) .; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried doing this with Dockerfile.multiarch
instead of Dockerfile.Windows
?
You must extract the target OS from TARGETPLATFORM instead of hard-coding linux
and the .exe suffix may need special handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried doing this with Dockerfile.multiarch instead of Dockerfile.Windows?
I haven't tried this. We can't test windows images at our end. May be @jingxu97 can try this out.
Ideally instead of writing different docker buildx build
command for each arch build and then creating manifest for them, single command with --push --platform=linux/amd64,linux/s390x
should work. However I feel we can try this out later, once current changes are working as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Dockerfile.multiarch contains a 'RUN' command, we cannot use it to build windows image on a linux machine with buildx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we can build Windows binaries on the Linux host, but not inside a Docker container? Or does building for Windows need a Windows host?
/release-note-none |
In https://github.com/kubernetes-csi/node-driver-registrar/pull/82/files/3e9e449f9f279c0c6e0859c1bce7c9b4b0007141#r425692239, we were discussing how to unify handling of Windows and Linux images. @jingxu97 pointed out that "Since Dockerfile.multiarch contains a 'RUN' command, we cannot use it to build windows image on a linux machine with buildx.". I was then wondering what we can use. I tried it: we can and do cross-compile Windows binaries on a linux/amd64 host, just as we do for all other currently supported platforms (https://github.com/kubernetes-csi/csi-release-tools/blob/9084fecb84ddb47af8360d9ebe4f48a6b7a65c1d/prow.sh#L88). As we are stuck with cross-compilation (correct, @jingxu97?), I am not sure whether we need to use "docker buildx". While in theory it may be nicer (building for multiple platforms with one instruction), we are not taking advantage of that and may as well do something like https://github.com/MarcusWichelmann/PrometheusSolarExporter/blob/3f2ee21b071af79a741cd1fefc02cba74c9bf166/.github/workflows/build.yml#L48-L65 @vitt-bagal, agreed that this could work? However, one open question is whether can use the same base image or need something special for Windows. Is "gcr.io/distroless/static:latest" just for Linux and we have to use |
I tried building multi-arch images with a local Docker registry, but I am running into docker/cli#2396. |
@pohly Even i also got the same issue with local docker registry. You can try with dockerhub. |
@pohly Docker buildx adds correct manifest for mutiarch images as we are using distroless image in Dockerfile. There are issues using manifest commands, for more reference: bazelbuild/rules_docker#300 (comment)
Distroless seems to be for Linux only: https://github.com/GoogleContainerTools/distroless/tree/master/base#image-contents @pohly how about testing Linux and Windows through different commands for now, considering various open issues? |
push-multiarch-%: | ||
make BUILD_PLATFORMS="windows amd64 .exe" | ||
set -ex; \ | ||
gcloud auth configure-docker; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to require gcloud? Can we put this in the cloudbuild.yml instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Earlier gcloud command was a part of cloudbuild only but later we have moved it to make target in order to keep cloudbuild simple and minimal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be preferable to keep gcloud command outside of this otherwise anybody that wants to build a multiarch image is going to require gcloud to be installed.
If you still want put it in the makefile to reduce the commands in cloudbuild, then I would maybe wrap "push-multiarch" with a "cloudbuild-push-multiarch"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @msau42 that this belongs into cloudbuild.yml. push-multiarch-%
should be independent of the registry. cloudbuild.yml
is where we prepare for pushing to gcr.
docker buildx create --use --name multiarchimage-buildertest; \ | ||
pushMultiArch () { \ | ||
tag=$$1; \ | ||
docker buildx build --push -t $(IMAGE_NAME):amd64-linux-$$tag --platform=linux/amd64 -f $(shell if [ -e ./cmd/$*/Dockerfile.multiarch ]; then echo ./cmd/$*/Dockerfile.multiarch; else echo Dockerfile.multiarch; fi) --label revision=$(REV) .; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any way we can make the list of linux platforms as a variable instead of hard coding the command for each platform?
Unfortunately I don't think there's much we can do to generalize windows atm.
For making progress on testing, this lgtm. My comments about making this more extensible can be addressed as a followup. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: msau42, pohly, vitt-bagal The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
The problem is the usage of "make" as entry point for the build. Variable expansion and splitting at spaces don't work when doing that. Obvious in retrospect, right? 😝 This might fix it (untested):
|
What type of PR is this?
/kind feature
What this PR does / why we need it:
This PR will push canary image for
master
branch andvX.Y.Z
image depending on tag.@pohly Could you please review ?