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

feat(nodeadm): use ecr-credential-provider for public.ecr.aws in 1.27+ #2153

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

mselim00
Copy link
Contributor

Issue #, if available:

Description of changes:

Ports 78f54f6 to nodeadm/al2023

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Testing Done

Built a 1.30 AMI, checked the config file had public.ecr.aws in the machImages list and that running a pod using an image from public ECR (public.ecr.aws/nginx/nginx:latest) does not fail when using a role without ecr-public permissions.

See this guide for recommended testing for PRs. Some tests may not apply. Completing tests and providing additional validation steps are not required, but it is recommended and may reduce review time and time to merge.

Comment on lines 1 to 4
{
"apiVersion": "{{.ConfigApiVersion}}",
"kind": "CredentialProviderConfig",
"providers": [
Copy link
Member

@ndbaker1 ndbaker1 Feb 14, 2025

Choose a reason for hiding this comment

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

thoughts on just using the go type for CredentialProviderConfig and serializing it to json?

@@ -74,6 +88,8 @@ func generateImageCredentialProviderConfig(cfg *api.NodeConfig, ecrCredentialPro
} else {
templateVars.ConfigApiVersion = "kubelet.config.k8s.io/v1"
templateVars.ProviderApiVersion = "credentialprovider.kubelet.k8s.io/v1"
// ecr-credential-provider has support for public.ecr.aws in 1.27+
templateVars.MatchImages = append(templateVars.MatchImages, "public.ecr.aws")
Copy link
Member

Choose a reason for hiding this comment

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

ignore me -- I breezed past this part.

Nick's suggestion to use a go type is probably reasonable given how clunky loops are in a go template. Looks like the versions we need are still available in the latest k/k: k8s.io/kubelet/config/v1alpha1, etc

@suhailms18
Copy link

Hi @cartermckinnon,
I’m encountering an issue while building an Amazon EKS AMI using the latest version from the following repository:
https://github.com/awslabs/amazon-eks-ami/tree/v20250228.

I'm using the following command for the build:
make k8s=1.29 os_distro=al2023

During the build process, I receive the following error:
error="hosts-store error\nnot found\nstat /var/lib/nerdctl/1935db59/etchosts/k8s.io/7451a4dfa45ee2ca955fddc355b7bb609155714ad64a09c6896d6fdcb8b552b5/meta.json: no such file or directory"

@cartermckinnon
Copy link
Member

@suhailms18 I don't see how that's related to this PR, please open a new issue.

@mselim00 mselim00 force-pushed the public-ecr-al2023 branch from c36507e to b9ba3e7 Compare March 5, 2025 05:44
@mselim00 mselim00 force-pushed the public-ecr-al2023 branch from b9ba3e7 to f06baef Compare March 5, 2025 05:54
@mselim00 mselim00 force-pushed the public-ecr-al2023 branch from f06baef to d14a8f9 Compare March 5, 2025 05:57
@tzneal
Copy link
Contributor

tzneal commented Mar 5, 2025

Have we verified:

  • does this require new permissions (e.g. ecr-public:GetAuthorizationToken) that may not be on all nodes?
  • what happens if that permission doesn't exist, does it fall back to anonymous access, or does the image pull fail

@cartermckinnon
Copy link
Member

@tzneal yep! @mselim00 tested this in an earlier PR: #1949 (comment)

@mselim00 mselim00 force-pushed the public-ecr-al2023 branch from ac449db to aeb233c Compare March 5, 2025 18:10
"*.dkr.ecr.*.c2s.ic.gov",
"*.dkr.ecr.*.sc2s.sgov.gov",
"*.dkr.ecr.*.cloud.adc-e.uk",
"*.dkr.ecr.*.csp.hci.ic.gov",
}
kubeletVersion, err := GetKubeletVersion()
Copy link
Member

Choose a reason for hiding this comment

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

this is now available in cfg.Status.KubeletVersion, so you should keep that param in this func

Comment on lines +16 to +20
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json"
k8sconfigv1 "k8s.io/kubelet/config/v1"
k8sconfigv1alpha1 "k8s.io/kubelet/config/v1alpha1"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
k8sjson "k8s.io/apimachinery/pkg/runtime/serializer/json"
k8sconfigv1 "k8s.io/kubelet/config/v1"
k8sconfigv1alpha1 "k8s.io/kubelet/config/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
configv1 "k8s.io/kubelet/config/v1"
configv1alpha1 "k8s.io/kubelet/config/v1alpha1"

Copy link
Member

Choose a reason for hiding this comment

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

You can also remove the force import of embed, I think?

func generateImageCredentialProviderConfig(ecrCredentialProviderBinPath string) ([]byte, error) {
scheme := k8sruntime.NewScheme()
providerName := filepath.Base(ecrCredentialProviderBinPath)
defaultCacheDuration := &k8smetav1.Duration{Duration: 12 * time.Hour}
Copy link
Member

Choose a reason for hiding this comment

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

Should be a package-level constant, I think?

Name: providerName,
MatchImages: matchImages,
DefaultCacheDuration: defaultCacheDuration,
APIVersion: "credentialprovider.kubelet.k8s.io/v1alpha1",
Copy link
Member

Choose a reason for hiding this comment

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

This should be set by the scheme encoder

Providers: []k8sconfigv1.CredentialProvider{
{
Name: providerName,
MatchImages: append(matchImages, "public.ecr.aws"),
Copy link
Member

Choose a reason for hiding this comment

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

Need a comment here explaining why this is only for v1/1.27+

Comment on lines +110 to +114
gvk, err := apiutil.GVKForObject(cfg, scheme)
if err != nil {
return nil, err
}
cfg.GetObjectKind().SetGroupVersionKind(gvk)
Copy link
Member

Choose a reason for hiding this comment

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

this looks like a no-op, what's it for?

if semver.Compare(kubeletVersion, "v1.27.0") < 0 {
templateVars.ConfigApiVersion = "kubelet.config.k8s.io/v1alpha1"
templateVars.ProviderApiVersion = "credentialprovider.kubelet.k8s.io/v1alpha1"
err = k8sconfigv1alpha1.AddToScheme(scheme)
Copy link
Member

Choose a reason for hiding this comment

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

I think you should move the scheme setup stuff into init()

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.

5 participants