Browse code

Make node's Docker exec handler configurable

Add DockerConfig struct to hold Docker related configuration options.

Add DockerConfig field to NodeConfig.

Andy Goldstein authored on 2015/05/29 11:21:17
Showing 8 changed files
... ...
@@ -395,7 +395,17 @@ func (o CreateNodeConfigOptions) MakeNodeConfig(serverCertFile, serverKeyFile, n
395 395
 		return err
396 396
 	}
397 397
 
398
-	content, err := latestconfigapi.WriteYAML(config)
398
+	// Roundtrip the config to v1 and back to ensure proper defaults are set.
399
+	ext, err := configapi.Scheme.ConvertToVersion(config, "v1")
400
+	if err != nil {
401
+		return err
402
+	}
403
+	internal, err := configapi.Scheme.ConvertToVersion(ext, "")
404
+	if err != nil {
405
+		return err
406
+	}
407
+
408
+	content, err := latestconfigapi.WriteYAML(internal)
399 409
 	if err != nil {
400 410
 		return err
401 411
 	}
... ...
@@ -40,8 +40,27 @@ type NodeConfig struct {
40 40
 	// PodManifestConfig holds the configuration for enabling the Kubelet to
41 41
 	// create pods based from a manifest file(s) placed locally on the node
42 42
 	PodManifestConfig *PodManifestConfig
43
+
44
+	// DockerConfig holds Docker related configuration options.
45
+	DockerConfig DockerConfig
46
+}
47
+
48
+// DockerConfig holds Docker related configuration options.
49
+type DockerConfig struct {
50
+	// ExecHandlerName is the name of the handler to use for executing
51
+	// commands in Docker containers.
52
+	ExecHandlerName DockerExecHandlerType
43 53
 }
44 54
 
55
+type DockerExecHandlerType string
56
+
57
+const (
58
+	// DockerExecHandlerNative uses Docker's exec API for executing commands in containers.
59
+	DockerExecHandlerNative DockerExecHandlerType = "native"
60
+	// DockerExecHandlerNative uses nsenter for executing commands in containers.
61
+	DockerExecHandlerNsenter DockerExecHandlerType = "nsenter"
62
+)
63
+
45 64
 type MasterConfig struct {
46 65
 	api.TypeMeta
47 66
 
... ...
@@ -27,6 +27,11 @@ func init() {
27 27
 				obj.OpenShiftStoragePrefix = "openshift.io"
28 28
 			}
29 29
 		},
30
+		func(obj *DockerConfig) {
31
+			if len(obj.ExecHandlerName) == 0 {
32
+				obj.ExecHandlerName = DockerExecHandlerNative
33
+			}
34
+		},
30 35
 	)
31 36
 	if err != nil {
32 37
 		// If one of the conversion functions is malformed, detect it immediately.
... ...
@@ -39,8 +39,27 @@ type NodeConfig struct {
39 39
 	// PodManifestConfig holds the configuration for enabling the Kubelet to
40 40
 	// create pods based from a manifest file(s) placed locally on the node
41 41
 	PodManifestConfig *PodManifestConfig `json:"podManifestConfig"`
42
+
43
+	// DockerConfig holds Docker related configuration options.
44
+	DockerConfig DockerConfig `json:"dockerConfig"`
45
+}
46
+
47
+// DockerConfig holds Docker related configuration options.
48
+type DockerConfig struct {
49
+	// ExecHandlerName is the name of the handler to use for executing
50
+	// commands in Docker containers.
51
+	ExecHandlerName DockerExecHandlerType `json:"execHandlerName"`
42 52
 }
43 53
 
54
+type DockerExecHandlerType string
55
+
56
+const (
57
+	// DockerExecHandlerNative uses Docker's exec API for executing commands in containers.
58
+	DockerExecHandlerNative DockerExecHandlerType = "native"
59
+	// DockerExecHandlerNative uses nsenter for executing commands in containers.
60
+	DockerExecHandlerNsenter DockerExecHandlerType = "nsenter"
61
+)
62
+
44 63
 type MasterConfig struct {
45 64
 	v1.TypeMeta `json:",inline"`
46 65
 
... ...
@@ -19,6 +19,8 @@ const (
19 19
 apiVersion: v1
20 20
 dnsDomain: ""
21 21
 dnsIP: ""
22
+dockerConfig:
23
+  execHandlerName: ""
22 24
 imageConfig:
23 25
   format: ""
24 26
   latest: false
... ...
@@ -1,6 +1,9 @@
1 1
 package validation
2 2
 
3 3
 import (
4
+	"fmt"
5
+	"strings"
6
+
4 7
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
5 8
 
6 9
 	"github.com/openshift/origin/pkg/cmd/server/api"
... ...
@@ -26,5 +29,21 @@ func ValidateNodeConfig(config *api.NodeConfig) fielderrors.ValidationErrorList
26 26
 		allErrs = append(allErrs, ValidatePodManifestConfig(config.PodManifestConfig).Prefix("podManifestConfig")...)
27 27
 	}
28 28
 
29
+	allErrs = append(allErrs, ValidateDockerConfig(config.DockerConfig).Prefix("dockerConfig")...)
30
+
31
+	return allErrs
32
+}
33
+
34
+func ValidateDockerConfig(config api.DockerConfig) fielderrors.ValidationErrorList {
35
+	allErrs := fielderrors.ValidationErrorList{}
36
+
37
+	switch config.ExecHandlerName {
38
+	case api.DockerExecHandlerNative, api.DockerExecHandlerNsenter:
39
+		// ok
40
+	default:
41
+		validValues := strings.Join([]string{string(api.DockerExecHandlerNative), string(api.DockerExecHandlerNsenter)}, ", ")
42
+		allErrs = append(allErrs, fielderrors.NewFieldInvalid("execHandlerName", config.ExecHandlerName, fmt.Sprintf("must be one of %s", validValues)))
43
+	}
44
+
29 45
 	return allErrs
30 46
 }
... ...
@@ -226,6 +226,7 @@ func (c *NodeConfig) RunKubelet() {
226 226
 		DockerDaemonContainer:     "",
227 227
 		ConfigureCBR0:             false,
228 228
 		MaxPods:                   200,
229
+		DockerExecHandler:         c.DockerExecHandler,
229 230
 	}
230 231
 	kapp.RunKubelet(&kcfg, nil)
231 232
 }
... ...
@@ -62,6 +62,10 @@ type NodeConfig struct {
62 62
 	// PodManifestCheckIntervalSeconds is the interval in seconds for checking the manifest file(s) for new data
63 63
 	// The interval needs to be a positive value
64 64
 	PodManifestCheckIntervalSeconds int64
65
+
66
+	// DockerExecHandler is the handler to use for executing
67
+	// commands in Docker containers.
68
+	DockerExecHandler dockertools.ExecHandler
65 69
 }
66 70
 
67 71
 func BuildKubernetesNodeConfig(options configapi.NodeConfig) (*NodeConfig, error) {
... ...
@@ -98,6 +102,15 @@ func BuildKubernetesNodeConfig(options configapi.NodeConfig) (*NodeConfig, error
98 98
 		fileCheckInterval = options.PodManifestConfig.FileCheckIntervalSeconds
99 99
 	}
100 100
 
101
+	var dockerExecHandler dockertools.ExecHandler
102
+
103
+	switch options.DockerConfig.ExecHandlerName {
104
+	case configapi.DockerExecHandlerNative:
105
+		dockerExecHandler = &dockertools.NativeExecHandler{}
106
+	case configapi.DockerExecHandlerNsenter:
107
+		dockerExecHandler = &dockertools.NsenterExecHandler{}
108
+	}
109
+
101 110
 	config := &NodeConfig{
102 111
 		NodeHost:    options.NodeName,
103 112
 		BindAddress: options.ServingInfo.BindAddress,
... ...
@@ -119,6 +132,8 @@ func BuildKubernetesNodeConfig(options configapi.NodeConfig) (*NodeConfig, error
119 119
 
120 120
 		PodManifestPath:                 path,
121 121
 		PodManifestCheckIntervalSeconds: fileCheckInterval,
122
+
123
+		DockerExecHandler: dockerExecHandler,
122 124
 	}
123 125
 
124 126
 	return config, nil