From 3a3fab3f823e69d3464ee8980c017c0ed8dc9665 Mon Sep 17 00:00:00 2001 From: Dan Mace Date: Tue, 12 Aug 2014 09:04:00 -0400 Subject: [PATCH 1/2] FEATURE: Support privileged containers in a pod Add a Privileged field to containers in a pod, in order to facilitate pods performing administrative tasks such as builds via Docker-in-Docker. Discussion: https://github.com/GoogleCloudPlatform/kubernetes/issues/391 --- pkg/api/types.go | 2 ++ pkg/api/v1beta1/types.go | 2 ++ pkg/kubelet/kubelet.go | 1 + 3 files changed, 5 insertions(+) diff --git a/pkg/api/types.go b/pkg/api/types.go index 981de1b2244..2d446df5c51 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -195,6 +195,8 @@ type Container struct { VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"` LivenessProbe *LivenessProbe `yaml:"livenessProbe,omitempty" json:"livenessProbe,omitempty"` Lifecycle *Lifecycle `yaml:"lifecycle,omitempty" json:"lifecycle,omitempty"` + // Optional: Default to false. + Privileged bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` } // Handler defines a specific action that should be taken diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index fef44d35681..552f61f2c28 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -205,6 +205,8 @@ type Container struct { VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"` LivenessProbe *LivenessProbe `yaml:"livenessProbe,omitempty" json:"livenessProbe,omitempty"` Lifecycle *Lifecycle `yaml:"lifecycle,omitempty" json:"lifecycle,omitempty"` + // Optional: Default to false. + Privileged bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` } // Handler defines a specific action that should be taken diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 79ab7843a6f..22845dba261 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -339,6 +339,7 @@ func (kl *Kubelet) runContainer(pod *Pod, container *api.Container, podVolumes v PortBindings: portBindings, Binds: binds, NetworkMode: netMode, + Privileged: container.Privileged, }) if err == nil && container.Lifecycle != nil && container.Lifecycle.PostStart != nil { handlerErr := kl.runHandler(GetPodFullName(pod), pod.Manifest.UUID, container, container.Lifecycle.PostStart) From 46d0cbd645d919d243139d50ded13fa8fb2d8fcf Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Thu, 11 Sep 2014 16:34:24 -0700 Subject: [PATCH 2/2] Add a global flag to enable/disable privileged containers --- cmd/kubelet/kubelet.go | 4 +++- pkg/kubelet/kubelet.go | 32 +++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cmd/kubelet/kubelet.go b/cmd/kubelet/kubelet.go index 21052332c8f..f072b5583ae 100644 --- a/cmd/kubelet/kubelet.go +++ b/cmd/kubelet/kubelet.go @@ -58,6 +58,7 @@ var ( dockerEndpoint = flag.String("docker_endpoint", "", "If non-empty, use this for the docker endpoint to communicate with") etcdServerList util.StringList rootDirectory = flag.String("root_dir", defaultRootDir, "Directory path for managing kubelet files (volume mounts,etc).") + allowPrivileged = flag.Bool("allow_privileged", false, "If true, allow containers to request privileged mode.") ) func init() { @@ -150,7 +151,8 @@ func main() { cadvisorClient, etcdClient, *rootDirectory, - *syncFrequency) + *syncFrequency, + *allowPrivileged) health.AddHealthChecker("exec", health.NewExecHealthChecker(k)) health.AddHealthChecker("http", health.NewHTTPHealthChecker(&http.Client{})) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 22845dba261..ee0edd6c2ec 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -67,17 +67,19 @@ func NewMainKubelet( cc CadvisorInterface, ec tools.EtcdClient, rd string, - ri time.Duration) *Kubelet { + ri time.Duration, + privileged bool) *Kubelet { return &Kubelet{ - hostname: hn, - dockerClient: dc, - cadvisorClient: cc, - etcdClient: ec, - rootDirectory: rd, - resyncInterval: ri, - podWorkers: newPodWorkers(), - runner: dockertools.NewDockerContainerCommandRunner(), - httpClient: &http.Client{}, + hostname: hn, + dockerClient: dc, + cadvisorClient: cc, + etcdClient: ec, + rootDirectory: rd, + resyncInterval: ri, + podWorkers: newPodWorkers(), + runner: dockertools.NewDockerContainerCommandRunner(), + httpClient: &http.Client{}, + allowPrivileged: privileged, } } @@ -119,6 +121,8 @@ type Kubelet struct { runner dockertools.ContainerCommandRunner // Optional, client for http requests, defaults to empty client httpClient httpGetInterface + // Optional, allow privileged containers, defaults to false + allowPrivileged bool } // Run starts the kubelet reacting to config updates @@ -335,11 +339,17 @@ func (kl *Kubelet) runContainer(pod *Pod, container *api.Container, podVolumes v if err != nil { return "", err } + privileged := false + if kl.allowPrivileged { + privileged = container.Privileged + } else if container.Privileged { + return "", fmt.Errorf("Container requested privileged mode, but it is disallowed globally.") + } err = kl.dockerClient.StartContainer(dockerContainer.ID, &docker.HostConfig{ PortBindings: portBindings, Binds: binds, NetworkMode: netMode, - Privileged: container.Privileged, + Privileged: privileged, }) if err == nil && container.Lifecycle != nil && container.Lifecycle.PostStart != nil { handlerErr := kl.runHandler(GetPodFullName(pod), pod.Manifest.UUID, container, container.Lifecycle.PostStart)