diff --git a/pkg/agent/containerd/config.go b/pkg/agent/containerd/config.go index 760b5d5a28..23199ee3a7 100644 --- a/pkg/agent/containerd/config.go +++ b/pkg/agent/containerd/config.go @@ -99,6 +99,9 @@ func getHostConfigs(registry *registries.Registry, noDefaultEndpoint bool, mirro } } + // track which endpoints we've already seen to avoid creating duplicates + seenEndpoint := map[string]bool{} + // TODO: rewrites are currently copied from the mirror settings into each endpoint. // In the future, we should allow for per-endpoint rewrites, instead of expecting // all mirrors to have the same structure. This will require changes to the registries.yaml @@ -107,7 +110,10 @@ func getHostConfigs(registry *registries.Registry, noDefaultEndpoint bool, mirro registryName, url, override, err := normalizeEndpointAddress(endpoint, mirrorAddr) if err != nil { logrus.Warnf("Ignoring invalid endpoint URL %d=%s for %s: %v", i, endpoint, host, err) + } else if _, ok := seenEndpoint[url.String()]; ok { + logrus.Warnf("Skipping duplicate endpoint URL %d=%s for %s", i, endpoint, host) } else { + seenEndpoint[url.String()] = true var rewrites map[string]string // Do not apply rewrites to the embedded registry endpoint if url.Host != mirrorAddr { diff --git a/pkg/agent/containerd/config_test.go b/pkg/agent/containerd/config_test.go index 915f404d29..7fc1dd8971 100644 --- a/pkg/agent/containerd/config_test.go +++ b/pkg/agent/containerd/config_test.go @@ -475,6 +475,86 @@ func Test_UnitGetHostConfigs(t *testing.T) { }, }, }, + { + name: "registry with mirror endpoint - duplicate endpoints", + args: args{ + registryContent: ` + mirrors: + docker.io: + endpoint: + - registry.example.com + - registry.example.com + `, + }, + want: HostConfigs{ + "docker.io": templates.HostConfig{ + Program: "k3s", + Default: &templates.RegistryEndpoint{ + URL: u("https://registry-1.docker.io/v2"), + }, + Endpoints: []templates.RegistryEndpoint{ + { + URL: u("https://registry.example.com/v2"), + }, + }, + }, + }, + }, + { + name: "registry with mirror endpoint - duplicate endpoints in different formats", + args: args{ + registryContent: ` + mirrors: + docker.io: + endpoint: + - registry.example.com + - https://registry.example.com + - https://registry.example.com/v2 + `, + }, + want: HostConfigs{ + "docker.io": templates.HostConfig{ + Program: "k3s", + Default: &templates.RegistryEndpoint{ + URL: u("https://registry-1.docker.io/v2"), + }, + Endpoints: []templates.RegistryEndpoint{ + { + URL: u("https://registry.example.com/v2"), + }, + }, + }, + }, + }, + { + name: "registry with mirror endpoint - duplicate endpoints in different positions", + args: args{ + registryContent: ` + mirrors: + docker.io: + endpoint: + - https://registry.example.com + - https://registry.example.org + - https://registry.example.com + `, + }, + want: HostConfigs{ + "docker.io": templates.HostConfig{ + Program: "k3s", + Default: &templates.RegistryEndpoint{ + URL: u("https://registry-1.docker.io/v2"), + }, + Endpoints: []templates.RegistryEndpoint{ + { + URL: u("https://registry.example.com/v2"), + }, + { + URL: u("https://registry.example.org/v2"), + }, + }, + }, + }, + }, { name: "registry with mirror endpoint - localhost and port only", args: args{