Skip to content

Commit a4fdb06

Browse files
Replace use of public.ecr.aws/nginx/nginx with ghcr.io/jitesoft/alpine image (#254)
* Replace use of `public.ecr.aws/nginx/nginx` with `ghcr.io/jitesoft/alpine` image * Address PR review feedback
1 parent c728f92 commit a4fdb06

File tree

7 files changed

+68
-47
lines changed

7 files changed

+68
-47
lines changed

docs/usage/registry-cache/configuration.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,5 @@ The registry cache runs with a single replica. This fact may lead to concerns fo
167167
Example: If the Service of a registry cache is deleted, then a new Service will be created. containerd's registry config will still contain the old Service's cluster IP. containerd requests against the old Service's cluster IP will time out and containerd will fall back to upstream.
168168
- Image pull of `docker.io/library/alpine:3.13.2` from the upstream takes ~2s while image pull of the same image with invalid registry cache cluster IP takes ~2m.2s.
169169
- Image pull of `eu.gcr.io/gardener-project/gardener/ops-toolbelt:0.18.0` from the upstream takes ~10s while image pull of the same image with invalid registry cache cluster IP takes ~3m.10s.
170+
171+
3. Amazon Elastic Container Registry is currently not supported. For details see [distribution/distribution#4383](https://github.com/distribution/distribution/issues/4383).

test/common/common.go

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,24 @@ import (
2929
)
3030

3131
const (
32-
// PublicEcrAwsNginx1230Image is the public.ecr.aws/nginx/nginx:1.23.0 image.
33-
PublicEcrAwsNginx1230Image = "public.ecr.aws/nginx/nginx:1.23.0"
34-
// PublicEcrAwsNginx1240Image is the public.ecr.aws/nginx/nginx:1.24.0 image.
35-
PublicEcrAwsNginx1240Image = "public.ecr.aws/nginx/nginx:1.24.0"
36-
// PublicEcrAwsNginx1250Image is the public.ecr.aws/nginx/nginx:1.25.0 image.
37-
PublicEcrAwsNginx1250Image = "public.ecr.aws/nginx/nginx:1.25.0"
32+
// For the e2e tests don't use images from the following upstreams:
33+
// - docker.io: DockerHub has rate limiting for anonymous users.
34+
// - gcr.io, registry.k8s.io, quay.io, europe-docker.pkg.dev: These are all registries used in the Gardener's local setup. Avoid using them to do not have conflicts with provider-local in some corner cases.
35+
// - Amazon ECR: The Distribution project does not support image pulls from Amazon ECR. Ref https://github.com/distribution/distribution/issues/4383.
36+
37+
// GithubRegistryJitesoftAlpine3189Image is the ghcr.io/jitesoft/alpine:3.18.9 image.
38+
GithubRegistryJitesoftAlpine3189Image = "ghcr.io/jitesoft/alpine:3.18.9"
39+
// GithubRegistryJitesoftAlpine3194Image is the ghcr.io/jitesoft/alpine:3.19.4 image.
40+
GithubRegistryJitesoftAlpine3194Image = "ghcr.io/jitesoft/alpine:3.19.4"
41+
// GithubRegistryJitesoftAlpine3203Image is the ghcr.io/jitesoft/alpine:3.20.3 image.
42+
GithubRegistryJitesoftAlpine3203Image = "ghcr.io/jitesoft/alpine:3.20.3"
43+
// GitlabRegistryJitesoftAlpine31710Image is the registry.gitlab.com/jitesoft/dockerfiles/alpine:3.17.10 image.
44+
GitlabRegistryJitesoftAlpine31710Image = "registry.gitlab.com/jitesoft/dockerfiles/alpine:3.17.10"
3845

3946
// ArtifactRegistryNginx1176Image is the europe-docker.pkg.dev/gardener-project/releases/3rd/nginx:1.17.6 image (copy of docker.io/library/nginx:1.17.6).
4047
ArtifactRegistryNginx1176Image = "europe-docker.pkg.dev/gardener-project/releases/3rd/nginx:1.17.6"
4148
// RegistryK8sNginx1154Image is the registry.k8s.io/e2e-test-images/nginx:1.15-4 image.
4249
RegistryK8sNginx1154Image = "registry.k8s.io/e2e-test-images/nginx:1.15-4"
43-
// GithubRegistryNginx1261Image is the ghcr.io/linuxserver/nginx:1.26.1 image.
44-
GithubRegistryNginx1261Image = "ghcr.io/linuxserver/nginx:1.26.1"
4550

4651
// jqExtractRegistryLocation is a jq command that extracts the source location of the '/var/lib/registry' mount from the container's config.json file.
4752
jqExtractRegistryLocation = `jq -j '.mounts[] | select(.destination=="/var/lib/registry") | .source' /run/containerd/io.containerd.runtime.v2.task/k8s.io/%s/config.json`
@@ -167,41 +172,55 @@ func VerifyHostsTOMLFilesDeletedForAllNodes(ctx context.Context, log logr.Logger
167172
}
168173
}
169174

175+
// MutatePodFn is an optional function to change the Pod specification depending on the image used.
176+
type MutatePodFn func(pod *corev1.Pod) *corev1.Pod
177+
178+
// SleepInfinity is MutatePodFn that keeps the container running indefinitely.
179+
func SleepInfinity(pod *corev1.Pod) *corev1.Pod {
180+
pod.Spec.Containers[0].Command = []string{"sleep"}
181+
pod.Spec.Containers[0].Args = []string{"infinity"}
182+
return pod
183+
}
184+
170185
// VerifyRegistryCache verifies that a registry cache works as expected.
171186
//
172187
// The verification consists of the following steps:
173-
// 1. It deploys an nginx Pod with the given image.
188+
// 1. It deploys a Pod with the given image.
174189
// 2. It waits until the Pod is running.
175190
// 3. It verifies that the image is present in the registry's volume.
176191
// This is a verification that the image pull happened via the registry cache (and the containerd didn't fall back to the upstream).
177-
func VerifyRegistryCache(parentCtx context.Context, log logr.Logger, shootClient kubernetes.Interface, nginxImage string) {
178-
By("Create nginx Pod")
192+
func VerifyRegistryCache(parentCtx context.Context, log logr.Logger, shootClient kubernetes.Interface, image string, mutateFns ...MutatePodFn) {
193+
upstream, path, tag := splitImage(image)
194+
name := strings.ReplaceAll(path, "/", "-")
195+
By(fmt.Sprintf("Create %s Pod", name))
179196
ctx, cancel := context.WithTimeout(parentCtx, 5*time.Minute)
180197
defer cancel()
181198
pod := &corev1.Pod{
182199
ObjectMeta: metav1.ObjectMeta{
183-
GenerateName: "nginx-",
200+
GenerateName: name + "-",
184201
Namespace: corev1.NamespaceDefault,
185202
},
186203
Spec: corev1.PodSpec{
187204
Containers: []corev1.Container{
188205
{
189-
Name: "nginx",
190-
Image: nginxImage,
206+
Name: name,
207+
Image: image,
191208
},
192209
},
193210
},
194211
}
212+
for _, mutateFn := range mutateFns {
213+
pod = mutateFn(pod)
214+
}
195215
ExpectWithOffset(1, shootClient.Client().Create(ctx, pod)).To(Succeed())
196216

197-
By("Wait until nginx Pod is running")
217+
By(fmt.Sprintf("Wait until %s Pod is running", name))
198218
ExpectWithOffset(1, framework.WaitUntilPodIsRunning(ctx, log, pod.Name, pod.Namespace, shootClient)).To(Succeed())
199219

200-
By("Verify the registry cache pulled the nginx image")
220+
By(fmt.Sprintf("Verify the registry cache pulled the %s image", image))
201221
ctx, cancel = context.WithTimeout(parentCtx, 2*time.Minute)
202222
defer cancel()
203223

204-
upstream, path, tag := splitImage(nginxImage)
205224
selector := labels.SelectorFromSet(labels.Set(map[string]string{"upstream-host": strings.Replace(upstream, ":", "-", 1)}))
206225
EventuallyWithOffset(1, ctx, func() error {
207226
registryPod, err := framework.GetFirstRunningPodWithLabels(ctx, selector, metav1.NamespaceSystem, shootClient)
@@ -222,20 +241,20 @@ func VerifyRegistryCache(parentCtx context.Context, log logr.Logger, shootClient
222241

223242
imageDigest, err := rootPodExecutor.Execute(ctx, fmt.Sprintf("cat %s/docker/registry/v2/repositories/%s/_manifests/tags/%s/current/link", string(registryRootPath), path, tag))
224243
if err != nil {
225-
return fmt.Errorf("failed to get the %s image digest: %w", nginxImage, err)
244+
return fmt.Errorf("failed to get the %s image digest: %w", image, err)
226245
}
227246
imageSha256Value := strings.TrimPrefix(string(imageDigest), "sha256:")
228247
imageIndexPath := fmt.Sprintf("sha256/%s/%s", imageSha256Value[:2], imageSha256Value)
229248

230249
_, err = rootPodExecutor.Execute(ctx, fmt.Sprintf(jqCountManifests, string(registryRootPath), imageIndexPath))
231250
if err != nil {
232-
return fmt.Errorf("failed to get the %s image index manifests count: %w", nginxImage, err)
251+
return fmt.Errorf("failed to get the %s image index manifests count: %w", image, err)
233252
}
234253

235254
return nil
236-
}).WithPolling(10*time.Second).Should(Succeed(), "Expected to successfully find the nginx image in the registry's volume")
255+
}).WithPolling(10*time.Second).Should(Succeed(), fmt.Sprintf("Expected to successfully find the %s image in the registry's volume", image))
237256

238-
By("Delete nginx Pod")
257+
By(fmt.Sprintf("Delete %s Pod", name))
239258
timeout := 5 * time.Minute
240259
ctx, cancel = context.WithTimeout(parentCtx, timeout)
241260
defer cancel()

test/e2e/cache/create_enable_add_remove_disable_delete.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,47 +37,47 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
3737
Expect(f.UpdateShoot(ctx, f.Shoot, func(shoot *gardencorev1beta1.Shoot) error {
3838
size := resource.MustParse("2Gi")
3939
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
40-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
40+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
4141
})
4242

4343
return nil
4444
})).To(Succeed())
4545

46-
By("[public.ecr.aws] Verify registry-cache works")
47-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.PublicEcrAwsNginx1230Image)
46+
By("[ghcr.io] Verify registry-cache works")
47+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.GithubRegistryJitesoftAlpine3189Image, common.SleepInfinity)
4848

49-
By("Add the ghcr.io upstream to the registry-cache extension")
49+
By("Add the registry.gitlab.com upstream to the registry-cache extension")
5050
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)
5151
defer cancel()
5252
Expect(f.UpdateShoot(ctx, f.Shoot, func(shoot *gardencorev1beta1.Shoot) error {
5353
size := resource.MustParse("2Gi")
5454
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
55-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
5655
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
56+
{Upstream: "registry.gitlab.com", Volume: &v1alpha3.Volume{Size: &size}},
5757
})
5858

5959
return nil
6060
})).To(Succeed())
6161

62-
By("[ghcr.io] Verify registry-cache works")
63-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.GithubRegistryNginx1261Image)
62+
By("[registry.gitlab.com] Verify registry-cache works")
63+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.GitlabRegistryJitesoftAlpine31710Image, common.SleepInfinity)
6464

65-
By("Remove the ghcr.io upstream from the registry-cache extension")
65+
By("Remove the registry.gitlab.com upstream from the registry-cache extension")
6666
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)
6767
defer cancel()
6868
Expect(f.UpdateShoot(ctx, f.Shoot, func(shoot *gardencorev1beta1.Shoot) error {
6969
size := resource.MustParse("2Gi")
7070
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
71-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
71+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
7272
})
7373

7474
return nil
7575
})).To(Succeed())
7676

77-
By("[ghcr.io] Verify registry configuration is removed")
77+
By("[registry.gitlab.com] Verify registry configuration is removed")
7878
ctx, cancel = context.WithTimeout(parentCtx, 2*time.Minute)
7979
defer cancel()
80-
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootFramework.ShootClient, []string{"ghcr.io"})
80+
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootFramework.ShootClient, []string{"registry.gitlab.com"})
8181

8282
By("Disable the registry-cache extension")
8383
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)
@@ -88,10 +88,10 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
8888
return nil
8989
})).To(Succeed())
9090

91-
By("[public.ecr.aws] Verify registry configuration is removed")
91+
By("[ghcr.io] Verify registry configuration is removed")
9292
ctx, cancel = context.WithTimeout(parentCtx, 2*time.Minute)
9393
defer cancel()
94-
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootFramework.ShootClient, []string{"public.ecr.aws"})
94+
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootFramework.ShootClient, []string{"ghcr.io"})
9595

9696
By("Delete Shoot")
9797
ctx, cancel = context.WithTimeout(parentCtx, 15*time.Minute)

test/e2e/cache/create_enabled_force_delete.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
2424
shoot := e2e.DefaultShoot("e2e-cache-fd")
2525
size := resource.MustParse("2Gi")
2626
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
27-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
27+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
2828
})
2929
f.Shoot = shoot
3030

@@ -36,7 +36,7 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
3636
f.Verify()
3737

3838
By("Verify registry-cache works")
39-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.PublicEcrAwsNginx1230Image)
39+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.GithubRegistryJitesoftAlpine3189Image, common.SleepInfinity)
4040

4141
By("Force Delete Shoot")
4242
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)

test/e2e/cache/create_enabled_hibernate_reconcile_delete.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
2626
shoot := e2e.DefaultShoot("e2e-cache-hib")
2727
size := resource.MustParse("2Gi")
2828
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
29-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
29+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
3030
})
3131
f.Shoot = shoot
3232

@@ -38,7 +38,7 @@ var _ = Describe("Registry Cache Extension Tests", Label("cache"), func() {
3838
f.Verify()
3939

4040
By("Verify registry-cache works")
41-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.PublicEcrAwsNginx1230Image)
41+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootFramework.ShootClient, common.GithubRegistryJitesoftAlpine3189Image, common.SleepInfinity)
4242

4343
By("Hibernate Shoot")
4444
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)

test/testmachinery/shoot/enable_disable_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ var _ = Describe("Shoot registry cache testing", func() {
3838
}
3939

4040
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
41-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
41+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
4242
})
4343

4444
return nil
4545
})).To(Succeed())
4646

4747
By("Verify registry-cache works")
48-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.PublicEcrAwsNginx1230Image)
48+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.GithubRegistryJitesoftAlpine3189Image, common.SleepInfinity)
4949

5050
By("Disable the registry-cache extension")
5151
ctx, cancel = context.WithTimeout(parentCtx, 10*time.Minute)
@@ -59,7 +59,7 @@ var _ = Describe("Shoot registry cache testing", func() {
5959
By("Verify registry configuration is removed")
6060
ctx, cancel = context.WithTimeout(parentCtx, 2*time.Minute)
6161
defer cancel()
62-
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootClient, []string{"public.ecr.aws"})
62+
common.VerifyHostsTOMLFilesDeletedForAllNodes(ctx, f.Logger, f.ShootClient, []string{"ghcr.io"})
6363
}, defaultTestTimeout, framework.WithCAfterTest(func(ctx context.Context) {
6464
if common.HasRegistryCacheExtension(f.Shoot) {
6565
By("Disable the registry-cache extension")

test/testmachinery/shoot/enable_hibernate_reconcile_wakeup_disable_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ var _ = Describe("Shoot registry cache testing", func() {
4040
}
4141

4242
common.AddOrUpdateRegistryCacheExtension(shoot, []v1alpha3.RegistryCache{
43-
{Upstream: "public.ecr.aws", Volume: &v1alpha3.Volume{Size: &size}},
43+
{Upstream: "ghcr.io", Volume: &v1alpha3.Volume{Size: &size}},
4444
})
4545

4646
return nil
4747
})).To(Succeed())
4848

4949
By("Verify registry-cache works")
50-
// We are using nginx:1.24.0 as nginx:1.23.0 is already used by the "should enable and disable the registry-cache extension" test.
51-
// Hence, nginx:1.23.0 will be present in the Node.
52-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.PublicEcrAwsNginx1240Image)
50+
// We are using ghcr.io/jitesoft/alpine:3.19.4 as ghcr.io/jitesoft/alpine:3.18.9 is already used by the "should enable and disable the registry-cache extension" test.
51+
// Hence, ghcr.io/jitesoft/alpine:3.18.9 will be present in the Node.
52+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.GithubRegistryJitesoftAlpine3194Image, common.SleepInfinity)
5353

5454
By("Hibernate Shoot")
5555
ctx, cancel = context.WithTimeout(parentCtx, 15*time.Minute)
@@ -72,8 +72,8 @@ var _ = Describe("Shoot registry cache testing", func() {
7272
Expect(f.WakeUpShoot(ctx)).To(Succeed())
7373

7474
By("Verify registry-cache works after wake up")
75-
// We are using nginx:1.25.0 as nginx:1.24.0 is already used above and already present in the Node and in the registry cache.
76-
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.PublicEcrAwsNginx1250Image)
75+
// We are using ghcr.io/jitesoft/alpine:3.20.3 as ghcr.io/jitesoft/alpine:3.19.4 is already used above and already present in the Node and in the registry cache.
76+
common.VerifyRegistryCache(parentCtx, f.Logger, f.ShootClient, common.GithubRegistryJitesoftAlpine3203Image, common.SleepInfinity)
7777
}, hibernationTestTimeout, framework.WithCAfterTest(func(ctx context.Context) {
7878
if v1beta1helper.HibernationIsEnabled(f.Shoot) {
7979
By("Wake up Shoot")

0 commit comments

Comments
 (0)