Add wildcard mirror support.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
8021850e91
commit
81ca274c6f
@ -13,12 +13,23 @@ To configure image registries create/modify the `/etc/containerd/config.toml` as
|
|||||||
endpoint = ["https://HostIP1:Port1"]
|
endpoint = ["https://HostIP1:Port1"]
|
||||||
[plugins.cri.registry.mirrors."test.insecure-registry.io"]
|
[plugins.cri.registry.mirrors."test.insecure-registry.io"]
|
||||||
endpoint = ["http://HostIP2:Port2"]
|
endpoint = ["http://HostIP2:Port2"]
|
||||||
|
# wildcard matching is supported but not required.
|
||||||
|
[plugins.cri.registry.mirrors."*"]
|
||||||
|
endpoint = ["http://HostIP3:Port3"]
|
||||||
```
|
```
|
||||||
|
|
||||||
The default configuration can be generated by `containerd config default > /etc/containerd/config.toml`.
|
The default configuration can be generated by `containerd config default > /etc/containerd/config.toml`.
|
||||||
|
|
||||||
The endpoint is a list that can contain multiple image registry URLs split by commas. When pulling an image
|
The endpoint is a list that can contain multiple image registry URLs split by commas. When pulling an image
|
||||||
from a registry, containerd will try these endpoint URLs one by one, and use the first working one.
|
from a registry, containerd will try these endpoint URLs one by one, and use the first working one. Please note
|
||||||
|
that if the default registry endpoint is not already specified in the endpoint list, it will be automatically
|
||||||
|
tried at the end with scheme `https` and path `v2`, e.g. `https://gcr.io/v2` for `gcr.io`.
|
||||||
|
|
||||||
|
As an example, for the image `gcr.io/library/busybox:latest`, the endpoints are:
|
||||||
|
* `gcr.io` is configured: endpoints for `gcr.io` + default endpoint `https://gcr.io/v2`.
|
||||||
|
* `*` is configured, and `gcr.io` is not: endpoints for `*` + default
|
||||||
|
endpoint `https://gcr.io/v2`.
|
||||||
|
* None of above is configured: default endpoint `https:/gcr.io/v2`.
|
||||||
|
|
||||||
After modify this config, you need restart the `containerd` service.
|
After modify this config, you need restart the `containerd` service.
|
||||||
|
|
||||||
|
@ -293,11 +293,9 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost
|
|||||||
return func(host string) ([]docker.RegistryHost, error) {
|
return func(host string) ([]docker.RegistryHost, error) {
|
||||||
var registries []docker.RegistryHost
|
var registries []docker.RegistryHost
|
||||||
|
|
||||||
// Try mirrors in order, and then try the default registry if not tried.
|
endpoints, err := c.registryEndpoints(host)
|
||||||
endpoints, err := addDefaultEndpoint(
|
|
||||||
c.config.Registry.Mirrors[host].Endpoints, host)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "add default endpoint")
|
return nil, errors.Wrap(err, "get registry endpoints")
|
||||||
}
|
}
|
||||||
for _, e := range endpoints {
|
for _, e := range endpoints {
|
||||||
u, err := url.Parse(e)
|
u, err := url.Parse(e)
|
||||||
@ -347,9 +345,17 @@ func (c *criService) registryHosts(auth *runtime.AuthConfig) docker.RegistryHost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// addDefaultEndpoint add default registry endpoint if it does not
|
// registryEndpoints returns endpoints for a given host.
|
||||||
// exist in the passed-in endpoint list.
|
// It adds default registry endpoint if it does not exist in the passed-in endpoint list.
|
||||||
func addDefaultEndpoint(endpoints []string, host string) ([]string, error) {
|
// It also supports wildcard host matching with `*`.
|
||||||
|
func (c *criService) registryEndpoints(host string) ([]string, error) {
|
||||||
|
var endpoints []string
|
||||||
|
_, ok := c.config.Registry.Mirrors[host]
|
||||||
|
if ok {
|
||||||
|
endpoints = c.config.Registry.Mirrors[host].Endpoints
|
||||||
|
} else {
|
||||||
|
endpoints = c.config.Registry.Mirrors["*"].Endpoints
|
||||||
|
}
|
||||||
defaultHost, err := docker.DefaultHost(host)
|
defaultHost, err := docker.DefaultHost(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "get default host")
|
return nil, errors.Wrap(err, "get default host")
|
||||||
|
@ -22,6 +22,8 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
|
|
||||||
|
criconfig "github.com/containerd/cri/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParseAuth(t *testing.T) {
|
func TestParseAuth(t *testing.T) {
|
||||||
@ -103,16 +105,34 @@ func TestParseAuth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddDefaultEndpoint(t *testing.T) {
|
func TestRegistryEndpoints(t *testing.T) {
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
endpoints []string
|
mirrors map[string]criconfig.Mirror
|
||||||
host string
|
host string
|
||||||
expected []string
|
expected []string
|
||||||
}{
|
}{
|
||||||
"default endpoint not in list": {
|
"no mirror configured": {
|
||||||
endpoints: []string{
|
mirrors: map[string]criconfig.Mirror{
|
||||||
"https://registry-1.io",
|
"registry-1.io": {
|
||||||
"https://registry-2.io",
|
Endpoints: []string{
|
||||||
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
host: "registry-3.io",
|
||||||
|
expected: []string{
|
||||||
|
"https://registry-3.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"mirror configured": {
|
||||||
|
mirrors: map[string]criconfig.Mirror{
|
||||||
|
"registry-3.io": {
|
||||||
|
Endpoints: []string{
|
||||||
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
host: "registry-3.io",
|
host: "registry-3.io",
|
||||||
expected: []string{
|
expected: []string{
|
||||||
@ -121,11 +141,50 @@ func TestAddDefaultEndpoint(t *testing.T) {
|
|||||||
"https://registry-3.io",
|
"https://registry-3.io",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"default endpoint in list with http": {
|
"wildcard mirror configured": {
|
||||||
endpoints: []string{
|
mirrors: map[string]criconfig.Mirror{
|
||||||
|
"*": {
|
||||||
|
Endpoints: []string{
|
||||||
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
host: "registry-3.io",
|
||||||
|
expected: []string{
|
||||||
"https://registry-1.io",
|
"https://registry-1.io",
|
||||||
"https://registry-2.io",
|
"https://registry-2.io",
|
||||||
"http://registry-3.io",
|
"https://registry-3.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"host should take precedence if both host and wildcard mirrors are configured": {
|
||||||
|
mirrors: map[string]criconfig.Mirror{
|
||||||
|
"*": {
|
||||||
|
Endpoints: []string{
|
||||||
|
"https://registry-1.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"registry-3.io": {
|
||||||
|
Endpoints: []string{
|
||||||
|
"https://registry-2.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
host: "registry-3.io",
|
||||||
|
expected: []string{
|
||||||
|
"https://registry-2.io",
|
||||||
|
"https://registry-3.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"default endpoint in list with http": {
|
||||||
|
mirrors: map[string]criconfig.Mirror{
|
||||||
|
"registry-3.io": {
|
||||||
|
Endpoints: []string{
|
||||||
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
"http://registry-3.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
host: "registry-3.io",
|
host: "registry-3.io",
|
||||||
expected: []string{
|
expected: []string{
|
||||||
@ -135,10 +194,14 @@ func TestAddDefaultEndpoint(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"default endpoint in list with https": {
|
"default endpoint in list with https": {
|
||||||
endpoints: []string{
|
mirrors: map[string]criconfig.Mirror{
|
||||||
"https://registry-1.io",
|
"registry-3.io": {
|
||||||
"https://registry-2.io",
|
Endpoints: []string{
|
||||||
"https://registry-3.io",
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
"https://registry-3.io",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
host: "registry-3.io",
|
host: "registry-3.io",
|
||||||
expected: []string{
|
expected: []string{
|
||||||
@ -148,10 +211,14 @@ func TestAddDefaultEndpoint(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"default endpoint in list with path": {
|
"default endpoint in list with path": {
|
||||||
endpoints: []string{
|
mirrors: map[string]criconfig.Mirror{
|
||||||
"https://registry-1.io",
|
"registry-3.io": {
|
||||||
"https://registry-2.io",
|
Endpoints: []string{
|
||||||
"https://registry-3.io/path",
|
"https://registry-1.io",
|
||||||
|
"https://registry-2.io",
|
||||||
|
"https://registry-3.io/path",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
host: "registry-3.io",
|
host: "registry-3.io",
|
||||||
expected: []string{
|
expected: []string{
|
||||||
@ -162,7 +229,9 @@ func TestAddDefaultEndpoint(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
got, err := addDefaultEndpoint(test.endpoints, test.host)
|
c := newTestCRIService()
|
||||||
|
c.config.Registry.Mirrors = test.mirrors
|
||||||
|
got, err := c.registryEndpoints(test.host)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, test.expected, got)
|
assert.Equal(t, test.expected, got)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user