Add DefaultRuntimeName option.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2019-04-08 16:39:28 -07:00
parent a5c5d55c90
commit ba4a04ae70
6 changed files with 120 additions and 79 deletions

View File

@ -176,9 +176,11 @@ disabled_plugins = ["restart"]
conf_template = "${cni_template_path}"
[plugins.cri.registry.mirrors."docker.io"]
endpoint = ["https://mirror.gcr.io","https://registry-1.docker.io"]
[plugins.cri.containerd.default_runtime]
[plugins.cri.containerd]
default_runtime_name = "${CONTAINERD_DEFAULT_RUNTIME:-"runc"}"
[plugins.cri.containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v1"
[plugins.cri.containerd.default_runtime.options]
[plugins.cri.containerd.runtimes.runc.options]
BinaryName = "${CONTAINERD_HOME}/usr/local/sbin/runc"
EOF
chmod 644 "${config_path}"

37
cri.go
View File

@ -17,6 +17,7 @@ limitations under the License.
package cri
import (
"context"
"flag"
"path/filepath"
"time"
@ -73,7 +74,7 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
}
log.G(ctx).Infof("Start cri plugin with config %+v", c)
if err := validateConfig(&c); err != nil {
if err := validateConfig(ctx, &c); err != nil {
return nil, errors.Wrap(err, "invalid config")
}
@ -111,14 +112,36 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
}
// validateConfig validates the given configuration.
func validateConfig(c *criconfig.Config) error {
// It is an error to provide both an UntrustedWorkloadRuntime & define an 'untrusted' runtime.
if _, ok := c.ContainerdConfig.Runtimes[criconfig.RuntimeUntrusted]; ok {
if c.ContainerdConfig.UntrustedWorkloadRuntime.Type != "" {
return errors.New("conflicting definitions: configuration includes untrusted_workload_runtime and runtimes['untrusted']")
}
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 instead")
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 stream_idle_timeout
if c.StreamIdleTimeout != "" {
if _, err := time.ParseDuration(c.StreamIdleTimeout); err != nil {
return errors.Wrap(err, "invalid stream idle timeout")

View File

@ -47,14 +47,14 @@ type Runtime struct {
type ContainerdConfig struct {
// Snapshotter is the snapshotter used by containerd.
Snapshotter string `toml:"snapshotter" json:"snapshotter"`
// DefaultRuntimeName is the default runtime name to use from the runtimes table.
DefaultRuntimeName string `toml:"default_runtime_name" json:"defaultRuntimeName"`
// DefaultRuntime is the default runtime to use in containerd.
// This runtime is used when no runtime handler (or the empty string) is provided.
// DEPRECATED: use DefaultRuntimeName instead. Remove in containerd 1.4.
DefaultRuntime Runtime `toml:"default_runtime" json:"defaultRuntime"`
// UntrustedWorkloadRuntime is a runtime to run untrusted workloads on it.
// DEPRECATED: use Runtimes instead. If provided, this runtime is mapped to the runtime handler
// named 'untrusted'. It is a configuration error to provide both the (now deprecated)
// UntrustedWorkloadRuntime and a handler in the Runtimes handler map (below) for 'untrusted'
// workloads at the same time. Please provide one or the other.
// DEPRECATED: use `untrusted` runtime in Runtimes instead. Remove in containerd 1.4.
UntrustedWorkloadRuntime Runtime `toml:"untrusted_workload_runtime" json:"untrustedWorkloadRuntime"`
// Runtimes is a map from CRI RuntimeHandler strings, which specify types of runtime
// configurations, to the matching configurations.
@ -195,13 +195,14 @@ func DefaultConfig() PluginConfig {
NetworkPluginConfTemplate: "",
},
ContainerdConfig: ContainerdConfig{
Snapshotter: containerd.DefaultSnapshotter,
DefaultRuntime: Runtime{
Type: "io.containerd.runtime.v1.linux",
Engine: "",
Root: "",
Snapshotter: containerd.DefaultSnapshotter,
DefaultRuntimeName: "runc",
NoPivot: false,
Runtimes: map[string]Runtime{
"runc": {
Type: "io.containerd.runc.v1",
},
},
NoPivot: false,
},
StreamServerAddress: "127.0.0.1",
StreamServerPort: "0",
@ -229,4 +230,6 @@ func DefaultConfig() PluginConfig {
const (
// RuntimeUntrusted is the implicit runtime defined for ContainerdConfig.UntrustedWorkloadRuntime
RuntimeUntrusted = "untrusted"
// RuntimeDefault is the implicit runtime defined for ContainerdConfig.DefaultRuntime
RuntimeDefault = "default"
)

View File

@ -212,7 +212,8 @@ func TestGenerateRuntimeOptions(t *testing.T) {
systemd_cgroup = true
[containerd]
no_pivot = true
[containerd.default_runtime]
default_runtime_name = "default"
[containerd.runtimes.legacy]
runtime_type = "` + linuxRuntime + `"
[containerd.runtimes.runc]
runtime_type = "` + runcRuntimeV1 + `"
@ -223,11 +224,12 @@ systemd_cgroup = true
systemd_cgroup = true
[containerd]
no_pivot = true
[containerd.default_runtime]
default_runtime_name = "default"
[containerd.runtimes.legacy]
runtime_type = "` + linuxRuntime + `"
[containerd.default_runtime.options]
Runtime = "default"
RuntimeRoot = "/default"
[containerd.runtimes.legacy.options]
Runtime = "legacy"
RuntimeRoot = "/legacy"
[containerd.runtimes.runc]
runtime_type = "` + runcRuntimeV1 + `"
[containerd.runtimes.runc.options]
@ -246,8 +248,8 @@ systemd_cgroup = true
require.NoError(t, err)
_, err = toml.Decode(nonNilOpts, &nonNilOptsConfig)
require.NoError(t, err)
require.Len(t, nilOptsConfig.Runtimes, 2)
require.Len(t, nonNilOptsConfig.Runtimes, 2)
require.Len(t, nilOptsConfig.Runtimes, 3)
require.Len(t, nonNilOptsConfig.Runtimes, 3)
for desc, test := range map[string]struct {
r criconfig.Runtime
@ -265,7 +267,7 @@ systemd_cgroup = true
expectedOptions: nil,
},
"when options is nil, should use legacy fields for legacy runtime": {
r: nilOptsConfig.DefaultRuntime,
r: nilOptsConfig.Runtimes["legacy"],
c: nilOptsConfig,
expectedOptions: &runctypes.RuncOptions{
SystemdCgroup: true,
@ -290,11 +292,11 @@ systemd_cgroup = true
},
},
"when options is not nil, should be able to decode for legacy runtime": {
r: nonNilOptsConfig.DefaultRuntime,
r: nonNilOptsConfig.Runtimes["legacy"],
c: nonNilOptsConfig,
expectedOptions: &runctypes.RuncOptions{
Runtime: "default",
RuntimeRoot: "/default",
Runtime: "legacy",
RuntimeRoot: "/legacy",
},
},
} {

View File

@ -628,16 +628,11 @@ func (c *criService) getSandboxRuntime(config *runtime.PodSandboxConfig, runtime
return criconfig.Runtime{}, errors.New("untrusted workload with host access is not allowed")
}
// Handle the deprecated UntrustedWorkloadRuntime.
if c.config.ContainerdConfig.UntrustedWorkloadRuntime.Type != "" {
return c.config.ContainerdConfig.UntrustedWorkloadRuntime, nil
}
runtimeHandler = criconfig.RuntimeUntrusted
}
if runtimeHandler == "" {
return c.config.ContainerdConfig.DefaultRuntime, nil
runtimeHandler = c.config.ContainerdConfig.DefaultRuntimeName
}
handler, ok := c.config.ContainerdConfig.Runtimes[runtimeHandler]

View File

@ -681,13 +681,11 @@ func TestGetSandboxRuntime(t *testing.T) {
}
for desc, test := range map[string]struct {
sandboxConfig *runtime.PodSandboxConfig
runtimeHandler string
defaultRuntime criconfig.Runtime
untrustedWorkloadRuntime criconfig.Runtime
runtimes map[string]criconfig.Runtime
expectErr bool
expectedRuntime criconfig.Runtime
sandboxConfig *runtime.PodSandboxConfig
runtimeHandler string
runtimes map[string]criconfig.Runtime
expectErr bool
expectedRuntime criconfig.Runtime
}{
"should return error if untrusted workload requires host access": {
sandboxConfig: &runtime.PodSandboxConfig{
@ -705,9 +703,11 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
expectErr: true,
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
},
expectErr: true,
},
"should use untrusted workload runtime for untrusted workload": {
sandboxConfig: &runtime.PodSandboxConfig{
@ -715,15 +715,18 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
expectedRuntime: untrustedWorkloadRuntime,
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
},
expectedRuntime: untrustedWorkloadRuntime,
},
"should use default runtime for regular workload": {
sandboxConfig: &runtime.PodSandboxConfig{},
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
expectedRuntime: defaultRuntime,
sandboxConfig: &runtime.PodSandboxConfig{},
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
},
expectedRuntime: defaultRuntime,
},
"should use default runtime for trusted workload": {
sandboxConfig: &runtime.PodSandboxConfig{
@ -731,9 +734,11 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "false",
},
},
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
expectedRuntime: defaultRuntime,
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
},
expectedRuntime: defaultRuntime,
},
"should return error if untrusted workload runtime is required but not configured": {
sandboxConfig: &runtime.PodSandboxConfig{
@ -741,8 +746,10 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
defaultRuntime: defaultRuntime,
expectErr: true,
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
},
expectErr: true,
},
"should use 'untrusted' runtime for untrusted workload": {
sandboxConfig: &runtime.PodSandboxConfig{
@ -750,8 +757,10 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
defaultRuntime: defaultRuntime,
runtimes: map[string]criconfig.Runtime{criconfig.RuntimeUntrusted: untrustedWorkloadRuntime},
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
},
expectedRuntime: untrustedWorkloadRuntime,
},
"should use 'untrusted' runtime for untrusted workload & handler": {
@ -760,9 +769,11 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
runtimeHandler: "untrusted",
defaultRuntime: defaultRuntime,
runtimes: map[string]criconfig.Runtime{criconfig.RuntimeUntrusted: untrustedWorkloadRuntime},
runtimeHandler: "untrusted",
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
},
expectedRuntime: untrustedWorkloadRuntime,
},
"should return an error if untrusted annotation with conflicting handler": {
@ -771,26 +782,32 @@ func TestGetSandboxRuntime(t *testing.T) {
annotations.UntrustedWorkload: "true",
},
},
runtimeHandler: "foo",
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
runtimes: map[string]criconfig.Runtime{"foo": fooRuntime},
expectErr: true,
runtimeHandler: "foo",
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
"foo": fooRuntime,
},
expectErr: true,
},
"should use correct runtime for a runtime handler": {
sandboxConfig: &runtime.PodSandboxConfig{},
runtimeHandler: "foo",
defaultRuntime: defaultRuntime,
untrustedWorkloadRuntime: untrustedWorkloadRuntime,
runtimes: map[string]criconfig.Runtime{"foo": fooRuntime},
expectedRuntime: fooRuntime,
sandboxConfig: &runtime.PodSandboxConfig{},
runtimeHandler: "foo",
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
criconfig.RuntimeUntrusted: untrustedWorkloadRuntime,
"foo": fooRuntime,
},
expectedRuntime: fooRuntime,
},
"should return error if runtime handler is required but not configured": {
sandboxConfig: &runtime.PodSandboxConfig{},
runtimeHandler: "bar",
defaultRuntime: defaultRuntime,
runtimes: map[string]criconfig.Runtime{"foo": fooRuntime},
expectErr: true,
runtimes: map[string]criconfig.Runtime{
criconfig.RuntimeDefault: defaultRuntime,
"foo": fooRuntime,
},
expectErr: true,
},
} {
t.Run(desc, func(t *testing.T) {
@ -798,8 +815,7 @@ func TestGetSandboxRuntime(t *testing.T) {
cri.config = criconfig.Config{
PluginConfig: criconfig.DefaultConfig(),
}
cri.config.ContainerdConfig.DefaultRuntime = test.defaultRuntime
cri.config.ContainerdConfig.UntrustedWorkloadRuntime = test.untrustedWorkloadRuntime
cri.config.ContainerdConfig.DefaultRuntimeName = criconfig.RuntimeDefault
cri.config.ContainerdConfig.Runtimes = test.runtimes
r, err := cri.getSandboxRuntime(test.sandboxConfig, test.runtimeHandler)
assert.Equal(t, test.expectErr, err != nil)