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

Add pkg/authn/kubernetes #1234

Merged
merged 8 commits into from
Jan 8, 2022
Merged

Add pkg/authn/kubernetes #1234

merged 8 commits into from
Jan 8, 2022

Conversation

imjasonh
Copy link
Collaborator

@imjasonh imjasonh commented Jan 6, 2022

This takes the Kubernetes client-go parts from k8schain, removes the
forked-upstream credentialprovider bits and rewrites them to include
only exactly what we need.

It also reimplements k8schain in terms of this new K8s helper, and of
wrapped cred helpers using authn.NewKeychainFromHelper.

cc @vdemeester

@codecov-commenter
Copy link

codecov-commenter commented Jan 6, 2022

Codecov Report

Merging #1234 (e0c07cf) into main (c370fbd) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1234   +/-   ##
=======================================
  Coverage   73.77%   73.77%           
=======================================
  Files         111      111           
  Lines        8183     8183           
=======================================
  Hits         6037     6037           
  Misses       1549     1549           
  Partials      597      597           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c370fbd...e0c07cf. Read the comment docs.

@imjasonh
Copy link
Collaborator Author

imjasonh commented Jan 6, 2022

hack/presubmit.sh failed in CI:

# sigs.k8s.io/json/internal/golang/encoding/json
Error: /home/runner/go/pkg/mod/sigs.k8s.io/json@v0.0.0-20211020170558-c049b76a60c6/internal/golang/encoding/json/encode.go:1249:12: sf.IsExported undefined (type reflect.StructField has no field or method IsExported)
Error: /home/runner/go/pkg/mod/sigs.k8s.io/json@v0.0.0-20211020170558-c049b76a60c6/internal/golang/encoding/json/encode.go:1255:18: sf.IsExported undefined (type reflect.StructField has no field or method IsExported)
~/work/go-containerregistry/go-containerregistry ~/work/go-containerregistry/go-containerregistry
Error: Process completed with exit code 2.

This is because StructField.IsExported was added in Go 1.17 -- the new module specifies go 1.17 which presumably picks up a later compatible sigs.k8s.io/json than is supported by the Go version used in CI. I bumped the CI version used to Go 1.17, since it's not that recent.

The pkg/authn/k8schain module is still go 1.14, maybe we should bump that to 1.17 too while we're at it. Maybe we should bump everything. I don't think it needs to be done in this PR.

return nil, err
}
for k, v := range cfg.Auths {
m[k] = v
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This (and line 119 below) means that later-specified secrets with matching repo/registry keys will overwrite previous ones. New fetches explicitly listed imagePullSecrets before searching for those attached to the SA, so those later ones, if there's a conflict, will win.

We have some options:

  • don't overwrite -- first matching auth wins
  • fetch implicit SA secrets before explicitly listed secrets

In any case, we probably need to spell it out better and guard it with tests.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just to chime in here (I meant to before). If this matches K8s' behavior, then it SGTM. It's unfortunate we don't track that anymore, but it felt like that was only a matter of time anyways.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Well, it turns out the previous behavior was first-one-wins, which I verified with a test on main that I ported to this PR.

Comment on lines 52 to 53
//
// Deprecated: Use pkg/authn/kubernetes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is probably worth separating the conversation about Deprecation from this PR, because I don't see the value in forcing all of the folks that are using k8schain to drop it so that we can stop maintaining what is now a very small shim. We can always add these later if we can agree on a path forward for folks.

To me the main win here is cutting out the need for Vincent's fork, which is HUGE, and I totally appreciate all of the work (and arguing!) to get us to this point. When the world stops ending, I owe you some beverages 🍻

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, you're probably right. Done.

@@ -0,0 +1,47 @@
module github.com/google/go-containerregistry/pkg/authn/kubernetes
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this just live in k8schain rather than having yet another submodule?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suspect (@imjasonh can correct) this was in an effort to deprecate k8schain, which I think warrants more discussion. So if we push out deprecation for another convo, this SGTM.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it's useful to be able to have a K8s-secret-backed Keychain that doesn't also pull in all of k8schain's dependencies, even though they're much smaller and more well behaved now.

Copy link
Contributor

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

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

@imjasonh just one question, because we remove the files that have //go:build !disable_gcp, are we sure the behavior of the new thing we use instead (some part of go-containerregistry) doesn't do what upstream k8s did (querying a url infinitely if it came to not answering) ?
I am mainly asking to not re-open a bug in tekton (and knative) on openshift 😝. Otherwise looks good and simple 😻

@@ -3,11 +3,16 @@ module github.com/google/go-containerregistry/pkg/authn/k8schain
go 1.14

require (
github.com/google/go-containerregistry v0.5.2-0.20210609162550-f0ce2270b3b4
github.com/vdemeester/k8s-pkg-credentialprovider v1.21.0-1
Copy link
Contributor

Choose a reason for hiding this comment

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

❤️

@imjasonh
Copy link
Collaborator Author

imjasonh commented Jan 7, 2022

@imjasonh just one question, because we remove the files that have //go:build !disable_gcp, are we sure the behavior of the new thing we use instead (some part of go-containerregistry) doesn't do what upstream k8s did (querying a url infinitely if it came to not answering) ? I am mainly asking to not re-open a bug in tekton (and knative) on openshift 😝. Otherwise looks good and simple 😻

Good question.

First, based on my testing with the AWS keychain imported but not used, it doesn't exhibit the 10-minute mystery wait that was observed in Tekton (tektoncd/pipeline#4087). This isn't a guaranteed fix, because to be fair I never saw the mystery wait anyway, even before Tekton snipped it out. Maybe I wasn't testing the right way? 🤷

Secondly, a nice thing about k8schain effectively becoming a shorthand wrapper for N different keychains is that consumers like Tekton/Knative can just choose their own keychains, to remove some, or reorder them, etc. So in this world, if it's a concern, Tekton/Knative or OpenShift Pipelines/Serverless, could replace k8schain.NewNoClient() with the equivalent authn.NewMultiKeychain(default, k8s, google) and remove problematic/unnecessary keychains.

Tekton could even jump through some hoops and retain the build tag logic, and have AWS disabled selectively at compile-time. We can discuss that in the PR where we bring this change into Tekton.

@vdemeester
Copy link
Contributor

Secondly, a nice thing about k8schain effectively becoming a shorthand wrapper for N different keychains is that consumers like Tekton/Knative can just choose their own keychains, to remove some, or reorder them, etc. So in this world, if it's a concern, Tekton/Knative or OpenShift Pipelines/Serverless, could replace k8schain.NewNoClient() with the equivalent authn.NewMultiKeychain(default, k8s, google) and remove problematic/unnecessary keychains.

Ah that make complete sense 😬 👍🏼

@mattmoor
Copy link
Collaborator

mattmoor commented Jan 7, 2022

Another alternative would be to simply go mod -replace k8schain downstream with a shim that includes the helpers you want. Personally, I have been toying with the idea of doing precisely that (for other reasons), so inlining this shim downstream is also (in some sense) a breaking change 😅

This takes the Kubernetes client-go parts from k8schain, removes the
forked-upstream credentialprovider bits and rewrites them to include
only exactly what we need.

It also reimplements k8schain in terms of this new K8s helper, and of
wrapped cred helpers using authn.NewKeychainFromHelper.
pkg/authn/k8schain/go.mod Outdated Show resolved Hide resolved
@hasheddan
Copy link
Contributor

@imjasonh just a heads up, we have previously had issues with the hanging requests in @crossplane and recently had them resurface when folks are using proxies, so definitely happy to see this land. I have some community members running tests of consuming this implementation across a variety of environments (pull through caches, pulling using IRSA, etc.) in crossplane/crossplane#2841. Happy to exercise any other scenarios of interest and report back as helpful. Appreciate the efforts here :)

@imjasonh
Copy link
Collaborator Author

@hasheddan that's great to hear! More testers on this will definitely be helpful. ❤️

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 this pull request may close these issues.

None yet

7 participants