Skip to content

Commit

Permalink
Merge pull request #1227 from Random-Liu/new-registry-mirror
Browse files Browse the repository at this point in the history
New registry mirror
  • Loading branch information
Random-Liu committed Aug 9, 2019
2 parents 29d5eb6 + 2fd69f0 commit a748128
Show file tree
Hide file tree
Showing 146 changed files with 6,664 additions and 1,746 deletions.
74 changes: 2 additions & 72 deletions cri.go
Expand Up @@ -17,10 +17,8 @@ limitations under the License.
package cri

import (
"context"
"flag"
"path/filepath"
"time"

"github.com/containerd/containerd"
"github.com/containerd/containerd/api/services/containers/v1"
Expand Down Expand Up @@ -74,8 +72,8 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
}
log.G(ctx).Infof("Start cri plugin with config %+v", c)

if err := validateConfig(ctx, &c); err != nil {
return nil, errors.Wrap(err, "invalid config")
if err := criconfig.ValidatePluginConfig(ctx, pluginConfig); err != nil {
return nil, errors.Wrap(err, "invalid plugin config")
}

if err := setGLogLevel(); err != nil {
Expand Down Expand Up @@ -111,74 +109,6 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
return s, nil
}

// validateConfig validates the given configuration.
func validateConfig(ctx context.Context, c *criconfig.Config) error {
if c.ContainerdConfig.Runtimes == nil {
c.ContainerdConfig.Runtimes = make(map[string]criconfig.Runtime)
}

// Validation for deprecated untrusted_workload_runtime.
if c.ContainerdConfig.UntrustedWorkloadRuntime.Type != "" {
log.G(ctx).Warning("`untrusted_workload_runtime` is deprecated, please use `untrusted` runtime in `runtimes` instead")
if _, ok := c.ContainerdConfig.Runtimes[criconfig.RuntimeUntrusted]; ok {
return errors.Errorf("conflicting definitions: configuration includes both `untrusted_workload_runtime` and `runtimes[%q]`", criconfig.RuntimeUntrusted)
}
c.ContainerdConfig.Runtimes[criconfig.RuntimeUntrusted] = c.ContainerdConfig.UntrustedWorkloadRuntime
}

// Validation for deprecated default_runtime field.
if c.ContainerdConfig.DefaultRuntime.Type != "" {
log.G(ctx).Warning("`default_runtime` is deprecated, please use `default_runtime_name` to reference the default configuration you have defined in `runtimes`")
c.ContainerdConfig.DefaultRuntimeName = criconfig.RuntimeDefault
c.ContainerdConfig.Runtimes[criconfig.RuntimeDefault] = c.ContainerdConfig.DefaultRuntime
}

// Validation for default_runtime_name
if c.ContainerdConfig.DefaultRuntimeName == "" {
return errors.New("`default_runtime_name` is empty")
}
if _, ok := c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName]; !ok {
return errors.New("no corresponding runtime configured in `runtimes` for `default_runtime_name`")
}

// Validation for deprecated runtime options.
if c.SystemdCgroup {
if c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName].Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`systemd_cgroup` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`systemd_cgroup` is deprecated, please use runtime `options` instead")
}
if c.NoPivot {
if c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName].Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`no_pivot` only works for runtime %s", plugin.RuntimeLinuxV1)
}
// NoPivot can't be deprecated yet, because there is no alternative config option
// for `io.containerd.runtime.v1.linux`.
}
for _, r := range c.ContainerdConfig.Runtimes {
if r.Engine != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_engine` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_engine` is deprecated, please use runtime `options` instead")
}
if r.Root != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_root` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_root` is deprecated, please use runtime `options` instead")
}
}

// Validation for stream_idle_timeout
if c.StreamIdleTimeout != "" {
if _, err := time.ParseDuration(c.StreamIdleTimeout); err != nil {
return errors.Wrap(err, "invalid stream idle timeout")
}
}
return nil
}

// getServicesOpts get service options from plugin context.
func getServicesOpts(ic *plugin.InitContext) ([]containerd.ServicesOpt, error) {
plugins, err := ic.GetByType(plugin.ServicePlugin)
Expand Down
19 changes: 9 additions & 10 deletions docs/registry.md
Expand Up @@ -27,8 +27,8 @@ After modify this config, you need restart the `containerd` service.

To configure the TLS settings for a specific registry, create/modify the `/etc/containerd/config.toml` as follows:
```toml
[plugins.cri.registry.tls_configs]
[plugins.cri.registry.tls_configs."my.custom.registry"]
# The registry host has to be an FDQN or IP.
[plugins.cri.registry.configs."my.custom.registry".tls]
ca_file = "ca.pem"
cert_file = "cert.pem"
key_file = "key.pem"
Expand All @@ -37,20 +37,19 @@ To configure the TLS settings for a specific registry, create/modify the `/etc/c
In the config example shown above, TLS mutual authentication will be used for communications with the registry endpoint located at https://my.custom.registry.
`ca_file` is file name of the certificate authority (CA) certificate used to authenticate the x509 certificate/key pair specified by the files respectively pointed to by `cert_file` and `key_file`.


## Configure Registry Credentials

`cri` plugin also supports docker like registry credential config.

To configure a credential for a specific registry endpoint, create/modify the
To configure a credential for a specific registry, create/modify the
`/etc/containerd/config.toml` as follows:
```toml
[plugins.cri.registry.auths]
[plugins.cri.registry.auths."https://gcr.io"]
username = ""
password = ""
auth = ""
identitytoken = ""
# The registry host has to be an FDQN or IP.
[plugins.cri.registry.configs."gcr.io".auth]
username = ""
password = ""
auth = ""
identitytoken = ""
```
The meaning of each field is the same with the corresponding field in `.docker/config.json`.

Expand Down
103 changes: 101 additions & 2 deletions pkg/config/config.go
Expand Up @@ -17,8 +17,14 @@ limitations under the License.
package config

import (
"context"
"time"

"github.com/BurntSushi/toml"
"github.com/containerd/containerd"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/plugin"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
)

Expand Down Expand Up @@ -95,6 +101,7 @@ type Mirror struct {
// Endpoints are endpoints for a namespace. CRI plugin will try the endpoints
// one by one until a working one is found. The endpoint must be a valid url
// with host specified.
// The scheme, host and path from the endpoint URL will be used.
Endpoints []string `toml:"endpoint" json:"endpoint"`
}

Expand Down Expand Up @@ -123,12 +130,23 @@ type TLSConfig struct {
type Registry struct {
// Mirrors are namespace to mirror mapping for all namespaces.
Mirrors map[string]Mirror `toml:"mirrors" json:"mirrors"`
// Configs are configs for each registry.
// The key is the FDQN or IP of the registry.
Configs map[string]RegistryConfig `toml:"configs" json:"configs"`

// Auths are registry endpoint to auth config mapping. The registry endpoint must
// be a valid url with host specified.
// DEPRECATED: Use Configs instead. Remove in containerd 1.4.
Auths map[string]AuthConfig `toml:"auths" json:"auths"`
// TLSConfigs are pairs of CA/Cert/Key which then are used when creating the transport
}

// RegistryConfig contains configuration used to communicate with the registry.
type RegistryConfig struct {
// Auth contains information to authenticate to the registry.
Auth *AuthConfig `toml:"auth" json:"auth"`
// TLS is a pair of CA/Cert/Key which then are used when creating the transport
// that communicates with the registry.
TLSConfigs map[string]TLSConfig `toml:"tls_configs" json:"tlsConfigs"`
TLS *TLSConfig `toml:"tls" json:"tls"`
}

// PluginConfig contains toml config related to CRI plugin,
Expand Down Expand Up @@ -260,3 +278,84 @@ const (
// RuntimeDefault is the implicit runtime defined for ContainerdConfig.DefaultRuntime
RuntimeDefault = "default"
)

// ValidatePluginConfig validates the given plugin configuration.
func ValidatePluginConfig(ctx context.Context, c *PluginConfig) error {
if c.ContainerdConfig.Runtimes == nil {
c.ContainerdConfig.Runtimes = make(map[string]Runtime)
}

// Validation for deprecated untrusted_workload_runtime.
if c.ContainerdConfig.UntrustedWorkloadRuntime.Type != "" {
log.G(ctx).Warning("`untrusted_workload_runtime` is deprecated, please use `untrusted` runtime in `runtimes` instead")
if _, ok := c.ContainerdConfig.Runtimes[RuntimeUntrusted]; ok {
return errors.Errorf("conflicting definitions: configuration includes both `untrusted_workload_runtime` and `runtimes[%q]`", RuntimeUntrusted)
}
c.ContainerdConfig.Runtimes[RuntimeUntrusted] = c.ContainerdConfig.UntrustedWorkloadRuntime
}

// Validation for deprecated default_runtime field.
if c.ContainerdConfig.DefaultRuntime.Type != "" {
log.G(ctx).Warning("`default_runtime` is deprecated, please use `default_runtime_name` to reference the default configuration you have defined in `runtimes`")
c.ContainerdConfig.DefaultRuntimeName = RuntimeDefault
c.ContainerdConfig.Runtimes[RuntimeDefault] = c.ContainerdConfig.DefaultRuntime
}

// Validation for default_runtime_name
if c.ContainerdConfig.DefaultRuntimeName == "" {
return errors.New("`default_runtime_name` is empty")
}
if _, ok := c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName]; !ok {
return errors.New("no corresponding runtime configured in `runtimes` for `default_runtime_name`")
}

// Validation for deprecated runtime options.
if c.SystemdCgroup {
if c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName].Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`systemd_cgroup` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`systemd_cgroup` is deprecated, please use runtime `options` instead")
}
if c.NoPivot {
if c.ContainerdConfig.Runtimes[c.ContainerdConfig.DefaultRuntimeName].Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`no_pivot` only works for runtime %s", plugin.RuntimeLinuxV1)
}
// NoPivot can't be deprecated yet, because there is no alternative config option
// for `io.containerd.runtime.v1.linux`.
}
for _, r := range c.ContainerdConfig.Runtimes {
if r.Engine != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_engine` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_engine` is deprecated, please use runtime `options` instead")
}
if r.Root != "" {
if r.Type != plugin.RuntimeLinuxV1 {
return errors.Errorf("`runtime_root` only works for runtime %s", plugin.RuntimeLinuxV1)
}
log.G(ctx).Warning("`runtime_root` is deprecated, please use runtime `options` instead")
}
}

// Validation for deprecated auths options and mapping it to configs.
if len(c.Registry.Auths) != 0 {
if c.Registry.Configs == nil {
c.Registry.Configs = make(map[string]RegistryConfig)
}
for endpoint, auth := range c.Registry.Auths {
config := c.Registry.Configs[endpoint]
config.Auth = &auth
c.Registry.Configs[endpoint] = config
}
log.G(ctx).Warning("`auths` is deprecated, please use registry`configs` instead")
}

// Validation for stream_idle_timeout
if c.StreamIdleTimeout != "" {
if _, err := time.ParseDuration(c.StreamIdleTimeout); err != nil {
return errors.Wrap(err, "invalid stream idle timeout")
}
}
return nil
}

0 comments on commit a748128

Please sign in to comment.