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

Implement registries for Kubernetes backend #4092

Merged

Conversation

meln5674
Copy link
Contributor

@meln5674 meln5674 commented Sep 7, 2024

According to the documentation, per-organization and per-pipeline registries are currently unsupported for the Kubernetes backend.

This patch implements this missing functionality by creating and deleting a matching secret for each pod with a matched registry, using the same name, labels, and annotations as the pod, and appending it to its imagePullSecrets list.

This patch adds tests for the new functionality, and has been manually end-to-end-tested in KinD by using a private image hosted in the matching gitea instance.

This will require updating the matching helm charts to add the create/delete permissions to the agent role, which is already done.

close #2987

* For each step that matches an registry, create a secret with the same
  name as its pod
* Delete this same secret when the pod is deleted
@qwerty287 qwerty287 added enhancement improve existing features backend/kubernetes build_pr_images If set, the CI will build images for this PR and push to Dockerhub labels Sep 7, 2024
@6543
Copy link
Member

6543 commented Sep 7, 2024

Please also update the docs :)

Copy link
Contributor

@zc-devs zc-devs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Am I correct, that only one image pull secret is supported?
  2. There was registry field in UI, as I remember. You don't use it, right?

https://woodpecker-ci.org/docs/usage/registries#images-from-private-registries

Woodpecker matches the registry hostname to each image in your YAML. If the hostnames match, the registry credentials are used to authenticate to your registry and pull the image.


Seems, registries are checked on the Server. As you create/delete secret each time, it should work as intended and comments above are invalid.
However, I still believe, that creating one secret with all available registries/auths and then "attach" it (via imagePullSecret) to needed steps/pods is a better approach.

pipeline/backend/kubernetes/image_pull_secret.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/image_pull_secret.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/image_pull_secret_test.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/image_pull_secret_test.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/pod.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/pod.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/pod.go Outdated Show resolved Hide resolved
@zc-devs
Copy link
Contributor

zc-devs commented Sep 7, 2024

#2987

@meln5674
Copy link
Contributor Author

meln5674 commented Sep 7, 2024

Please also update the docs :)

Can do, I wasn't sure if the docs site was live at HEAD or if there was some separate release process for them.

  1. Am I correct, that only one image pull secret is supported?
  2. There was registry field in UI, as I remember. You don't use it, right?

https://woodpecker-ci.org/docs/usage/registries#images-from-private-registries

Woodpecker matches the registry hostname to each image in your YAML. If the hostnames match, the registry credentials are used to authenticate to your registry and pull the image.

Seems, registries are checked on the Server. As you create/delete secret each time, it should work as intended and comments above are invalid. However, I still believe, that creating one secret with all available registries/auths and then "attach" it (via imagePullSecret) to needed steps/pods is a better approach.

In Kubernetes? No, any number of secrets is supported, with any number of auths in each one . In woodpecker, I saw that the AuthConfig for a step is a single user:pass pair, which is matched against the list of repo, org, and global registries, so in that sense, a single extra secret is supported. That said, in the future, if sidecars are also supported, it may make sense for this one secret to contain multiple auths. Because you can have as many imagePullSecrets as you want in a pod, it makes much more sense to list the user-managed ones and then the agent-managed ones, instead of reading them from the API server and writing them back out, as the kubelet will do that for you, and retry against each one in sequence in the event of authentication errors.

* Updated docs to remove unsupported functionality note and fix grammar
* Use term "registry secret" in source to refer to temporary secrets created to
  contain registry authentication
* Added separate env's to add extra labels and annotations to registry
  secrets
* Consolidated registry secret functions into secrets.go
* Moved secret creation/cleanup logic to separate functions in
  secret.go, called in kubernetes.go
* Fixed whitespace errors and unused fields in test code
@woodpecker-bot
Copy link
Collaborator

woodpecker-bot commented Sep 8, 2024

Copy link
Contributor

@zc-devs zc-devs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looks very well to me.


Am I correct, that only one image pull secret is supported?
There was registry field in UI, as I remember. You don't use it, right?

I was confused by flashbacks from #3122. I thought, if registry isn't passed within AuthConfig, then how Kubernetes would choose right secret? Or the only one secret/registry would be supported.
Then I reread through my PR

Made the secrets pipeline-wide instead of step-wide as in Docker backend

and understood everything :) ⬇️

registries are checked on the Server. As you create/delete secret each time, it should work as intended

--

if sidecars are also supported, it may make sense for this one secret to contain multiple auths

Good catch.

instead of reading them from the API server and writing them back out

Don't get this. Who reads regcreds from API? Kubernetes API? What is the "back"?

kubelet will do that for you, and retry against each one

That is exactly, what I had in mind, implementing #3122. ⬇️

However, I still believe, that creating one secret with all available registries/auths and then "attach" it (via imagePullSecret) to needed steps/pods is a better approach.

Yeah, maybe even not to "needed" pods, but all of them. And let Kubernetes cope with that.

pipeline/backend/kubernetes/flags.go Outdated Show resolved Hide resolved
pipeline/backend/kubernetes/secrets.go Show resolved Hide resolved
Copy link
Contributor

@zc-devs zc-devs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it is tested and works (#4092 (comment)), no more comments from me.
Thank you for the contribution 🎉

@6543 6543 merged commit b52b021 into woodpecker-ci:main Sep 30, 2024
6 of 7 checks passed
@woodpecker-bot woodpecker-bot mentioned this pull request Sep 30, 2024
1 task
@woodpecker-bot woodpecker-bot mentioned this pull request Dec 14, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend/kubernetes build_pr_images If set, the CI will build images for this PR and push to Dockerhub enhancement improve existing features highlight
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Kubernetes backend references non-existing pull secret: regcred
6 participants