Mirror repository rewrites (v1.1)
Support CRI configuration to allow for request-time rewrite rules
applicable only to the repository portion of resource paths when pulling
images. Because the rewrites are applied at request time, images
themselves will not be "rewritten" -- images as stored by CRI (and the
underlying containerd facility) will continue to present as normal.
As an example, if you use the following config for your containerd:
```toml
[plugins]
[plugins."io.containerd.grpc.v1.cri"]
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io/v2"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io".rewrite]
"^library/(.*)" = "my-org/$1"
```
And then subsequently invoke `crictl pull alpine:3.13` it will pull
content from `docker.io/my-org/alpine:3.13` but still show up as
`docker.io/library/alpine:3.13` in the `crictl images` listing.
This commit has been reworked from the original implementation. Rewites
are now done when resolving instead of when building the request, so
that auth token scopes stored in the context properly reflect the
rewritten repository path. For the original implementation, see
06c4ea9baec2b278b8172a789bf601168292f645.
Ref: https://github.com/k3s-io/k3s/issues/11191#issuecomment-2455525773
Signed-off-by: Jacob Blain Christen <jacob@rancher.com>
Co-authored-by: Brad Davidson <brad.davidson@rancher.com>
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
This commit is contained in:
committed by
Brad Davidson
parent
676ba43ad3
commit
ba6b205d0f
@@ -196,6 +196,23 @@ type Mirror struct {
|
||||
// with host specified.
|
||||
// The scheme, host and path from the endpoint URL will be used.
|
||||
Endpoints []string `toml:"endpoint" json:"endpoint"`
|
||||
|
||||
// Rewrites are repository rewrite rules for a namespace. When fetching image resources
|
||||
// from an endpoint and a key matches the repository via regular expression matching
|
||||
// it will be replaced with the corresponding value from the map in the resource request.
|
||||
//
|
||||
// This example configures CRI to pull docker.io/library/* images from docker.io/my-org/*:
|
||||
//
|
||||
// [plugins]
|
||||
// [plugins."io.containerd.grpc.v1.cri"]
|
||||
// [plugins."io.containerd.grpc.v1.cri".registry]
|
||||
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
|
||||
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
|
||||
// endpoint = ["https://registry-1.docker.io/v2"]
|
||||
// [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io".rewrite]
|
||||
// "^library/(.*)" = "my-org/$1"
|
||||
//
|
||||
Rewrites map[string]string `toml:"rewrite" json:"rewrite"`
|
||||
}
|
||||
|
||||
// AuthConfig contains the config related to authentication to a specific registry
|
||||
|
||||
@@ -441,6 +441,10 @@ func (c *CRIImageService) registryHosts(ctx context.Context, credentials func(ho
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get registry endpoints: %w", err)
|
||||
}
|
||||
rewrites, err := c.registryRewrites(host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get registry rewrites: %w", err)
|
||||
}
|
||||
for _, e := range endpoints {
|
||||
u, err := url.Parse(e)
|
||||
if err != nil {
|
||||
@@ -492,6 +496,7 @@ func (c *CRIImageService) registryHosts(ctx context.Context, credentials func(ho
|
||||
Scheme: u.Scheme,
|
||||
Path: u.Path,
|
||||
Capabilities: docker.HostCapabilityResolve | docker.HostCapabilityPull,
|
||||
Rewrites: rewrites,
|
||||
})
|
||||
}
|
||||
return registries, nil
|
||||
@@ -564,6 +569,20 @@ func (c *CRIImageService) registryEndpoints(host string) ([]string, error) {
|
||||
return append(endpoints, defaultScheme(defaultHost)+"://"+defaultHost), nil
|
||||
}
|
||||
|
||||
func (c *CRIImageService) registryRewrites(host string) (map[string]string, error) {
|
||||
var rewrites map[string]string
|
||||
_, ok := c.config.Registry.Mirrors[host]
|
||||
if ok {
|
||||
rewrites = c.config.Registry.Mirrors[host].Rewrites
|
||||
} else {
|
||||
rewrites = c.config.Registry.Mirrors["*"].Rewrites
|
||||
}
|
||||
if rewrites == nil {
|
||||
rewrites = map[string]string{}
|
||||
}
|
||||
return rewrites, nil
|
||||
}
|
||||
|
||||
// newTransport returns a new HTTP transport used to pull image.
|
||||
// TODO(random-liu): Create a library and share this code with `ctr`.
|
||||
func newTransport() *http.Transport {
|
||||
|
||||
Reference in New Issue
Block a user