-
Notifications
You must be signed in to change notification settings - Fork 39.8k
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
AWS: Allow cross-region image pulling with ECR #24369
Conversation
// by the client when attempting to pull an image and it will create the actual | ||
// provider only when we actually need it the first time. | ||
func (p *lazyEcrProvider) LazyProvide() *credentialprovider.DockerConfigEntry { | ||
if p.actualProvider == nil { |
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.
What do you think instead of having the code here inside the if, move the code to create the actualProvider to another function, and do something like:
if p.actualProvider == nil {
p.actualProvider = <func to create the actualProvider here>
}
entry := p.actualProvider.Provide()[p.regionURL]
return &entry
I'm not sure how the k8s code styling is (will check next week :)), but this is a small detail but it seems slightly more readable for me. And it's not like TONs of parameters will be needed in the func to create the actual provider.
What do you think?
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, I was going to try a helper function next. And perhaps, instead of creating N lazy providers, just one, which does a string match against the image getting loaded, figuring the region, then maintaining a map of ecrProviders.
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 not sure about that. The code this way is pretty simple and the N lazy providers shouldn't make noticiable difference in mem or cpu, and as no real provider is created for the unused, not even messages with the cloud provider are used.
So, I'd do it only if it is equally or more readable than now, and equally or less error prone. If the code gets more messy, I don't think it's worth the effort.
But your call :)
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.
Helper/constructor added. I'm still tempted to have one lazy provider (which would definitely require more tests).
@therc: nice! I did two small questions, but looks great for me (will test it next week :)) |
@@ -59,56 +76,96 @@ func (p *ecrTokenGetter) GetAuthorizationToken(input *ecr.GetAuthorizationTokenI | |||
return p.svc.GetAuthorizationToken(input) | |||
} | |||
|
|||
// lazyEcrProvider is a DockerConfigProvider that creates on demand an |
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.
Tip: I personally like to do this:
var _ DockerConfigProvider = &lazyEcrProvider{}
Apparently there's some debate as to whether or not to do it, but I like that it makes the intent very clear and that it is then checked immediately by the golang compiler.
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 both.
A few code nits/questions, but also: How does cross-region ECR work in terms of authentication? Are the IAM instance credentials for us-east-1 valid against a us-west ECR? Do we now construct an ECR provider against every region? I don't quite understand how the laziness works... |
@justinsb in my testing, it looks like my IAM instance credentials in us-east-1 were enough to invoke GetAuthorizationToken in us-west. We only create empty lazy providers in every region. This layered approach is a compromise between two extremes:
The real ECR provider is only created the first time we try to pull an actual image. |
Feedback addessed. I'm still on the fence on whether we should have just one lazy provider vs one for each and every region. |
@therc: great! |
@therc: I'm not familiar with the code at all, but I'm unsure why it's not better to move the lazy-ness to the "credentialprovider.CachingDockerConfigProvider". I'll try to have a look next week, but don't worry about me. Thanks! :) |
Rebased to pick up ap-northeast-2 from #24457 |
Ping? |
This is step two. We now create long-lived, lazy ECR providers in all regions. When first used, they will create the actual ECR providers doing the work behind the scenes, namely talking to ECR in the region where the image lives, rather than the one our instance is running in. Also: - moved the list of AWS regions out of the AWS cloudprovider and into the credentialprovider, then exported it from there. - improved logging Behold, running in us-east-1: ``` aws_credentials.go:127] Creating ecrProvider for us-west-2 aws_credentials.go:63] AWS request: ecr:GetAuthorizationToken in us-west-2 aws_credentials.go:217] Adding credentials for user AWS in us-west-2 Successfully pulled image 123456789012.dkr.ecr.us-west-2.amazonaws.com/test:latest" ``` *"One small step for a pod, one giant leap for Kube-kind."*
Use constructor for ecrProvider Rename package to "credentials" like golint requests Don't wrap the lazy provider with a caching provider Add immedita compile-time interface conformance checks for the interfaces Added comments
@therc |
GCE e2e build/test passed for commit 684517f. |
@@ -42,7 +42,7 @@ import ( | |||
|
|||
"k8s.io/kubernetes/pkg/api" | |||
"k8s.io/kubernetes/pkg/cloudprovider" | |||
"k8s.io/kubernetes/pkg/credentialprovider/aws" | |||
aws_credentials "k8s.io/kubernetes/pkg/credentialprovider/aws" |
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 a confusing alias (I would have guessed "github.com/aws/aws-sdk-go/aws/credentials"), but I can't think of a better one that isn't 30 characters long.
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.
aws_cred_provider?
I do find this very confusing, so I'm tempted to attempt a refactor, but let's get this merged! Thanks for implementing - will be very helpful to a lot of people. |
I'll create another PR with a mini design doc, a link to it and miscellaneous remaining fixes, but yes, it has to be either confusing like this or very inefficient, given the existing design of credential providers. |
@therc let's get the AWS PR backlog (of my fault) merged, and then maybe let's look at reworking the design of the credentials provider? I'm certainly game to take a look, and there's no point doing a lot of documentation it if we're going to change it. If/when I/we discover this is actually harder than I think and the design must stay, then more documentation is very welcome :-) |
@k8s-bot test this [submit-queue is verifying that this PR is safe to merge] |
GCE e2e build/test passed for commit 684517f. |
Automatic merge from submit-queue |
Fetching images from a registry hosted in a different region has been supported since 1.3 with kubernetes/kubernetes#24369
Fetching images from a registry hosted in a different region has been supported since 1.3 with kubernetes/kubernetes#24369
…iserver-throttling-4.3 Bug 1788621: Improve logging of kubelet-apiserver logging Origin-commit: 02753713077e72421e6076edc4c32e90312f9660
Fixes #23298
Definitely should be in the release notes; should maybe get merged in 1.2 along with #23594 after some soaking. Documentation changes to follow.
cc @justinsb @erictune @rata @miguelfrde
This is step two. We now create long-lived, lazy ECR providers in all regions.
When first used, they will create the actual ECR providers doing the work
behind the scenes, namely talking to ECR in the region where the image lives,
rather than the one our instance is running in.
Also:
credentialprovider, then exported it from there.
Behold, running in us-east-1:
"One small step for a pod, one giant leap for Kube-kind."
This change is