From 0a7537ecbfd94d7659f7629fb62ea882f2ac07eb Mon Sep 17 00:00:00 2001 From: Yifan Gu Date: Wed, 27 Apr 2016 17:16:28 -0700 Subject: [PATCH] rkt: Add pod selinux support. Currently only pod level selinux context is supported, besides when running selinux, for now we will not be able to use the overlay fs except for coreos, see: https://github.com/coreos/rkt/issues/1727#issuecomment-173203129. --- pkg/kubelet/rkt/rkt.go | 52 ++++++++++++++++++++++++++++++++++--- pkg/kubelet/rkt/rkt_test.go | 21 +++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index 9e06ddf82a6..1471c132e3a 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -17,6 +17,7 @@ limitations under the License. package rkt import ( + "bufio" "bytes" "encoding/json" "fmt" @@ -897,12 +898,24 @@ func serviceFilePath(serviceName string) string { func (r *Runtime) generateRunCommand(pod *api.Pod, uuid, netnsName string) (string, error) { runPrepared := r.buildCommand("run-prepared").Args + var hostname string + var err error + + osInfos, err := getOSReleaseInfo() + if err != nil { + glog.Errorf("rkt: Failed to read the os release info: %v", err) + } + + // Overlay fs is not supported for SELinux yet on many distros. + // See https://github.com/coreos/rkt/issues/1727#issuecomment-173203129. + // For now, coreos carries a patch to support it: https://github.com/coreos/coreos-overlay/pull/1703 + if osInfos["ID"] != "coreos" && pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil { + runPrepared = append(runPrepared, "--no-overlay=true") + } + // Network namespace set up in kubelet; rkt networking not used runPrepared = append(runPrepared, "--net=host") - var hostname string - var err error - // Setup DNS and hostname configuration. if len(netnsName) == 0 { // TODO(yifan): Let runtimeHelper.GeneratePodHostNameAndDomain() to handle this. hostname, err = r.os.Hostname() @@ -1051,6 +1064,12 @@ func (r *Runtime) preparePod(pod *api.Pod, podIP string, pullSecrets []api.Secre newUnitOption(unitKubernetesSection, unitPodNamespace, pod.Namespace), } + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil { + opt := pod.Spec.SecurityContext.SELinuxOptions + selinuxContext := fmt.Sprintf("%s:%s:%s:%s", opt.User, opt.Role, opt.Type, opt.Level) + units = append(units, newUnitOption("Service", "SELinuxContext", selinuxContext)) + } + serviceName := makePodServiceFileName(uuid) glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, format.Pod(pod)) serviceFile, err := r.os.Create(serviceFilePath(serviceName)) @@ -2115,3 +2134,30 @@ func (r *Runtime) GetPodStatus(uid kubetypes.UID, name, namespace string) (*kube return podStatus, nil } + +// getOSReleaseInfo reads /etc/os-release and returns a map +// that contains the key value pairs in that file. +func getOSReleaseInfo() (map[string]string, error) { + result := make(map[string]string) + + path := "/etc/os-release" + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + info := strings.SplitN(line, "=", 2) + if len(info) != 2 { + return nil, fmt.Errorf("unexpected entry in os-release %q", line) + } + result[info[0]] = info[1] + } + if err := scanner.Err(); err != nil { + return nil, err + } + return result, nil +} diff --git a/pkg/kubelet/rkt/rkt_test.go b/pkg/kubelet/rkt/rkt_test.go index d9e858b901d..d421c6108d7 100644 --- a/pkg/kubelet/rkt/rkt_test.go +++ b/pkg/kubelet/rkt/rkt_test.go @@ -1190,6 +1190,27 @@ func TestGenerateRunCommand(t *testing.T) { nil, fmt.Sprintf("/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=host --hostname=%s rkt-uuid-foo", hostName), }, + // Case #5, returns --net=host --no-overlay + { + &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "pod-name-foo", + }, + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{ + HostNetwork: true, + SELinuxOptions: &api.SELinuxOptions{}, + }, + }, + }, + "rkt-uuid-foo", + "", + []string{""}, + []string{""}, + "pod-hostname-foo", + nil, + fmt.Sprintf("/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --no-overlay=true --net=host --hostname=%s rkt-uuid-foo", hostName), + }, } rkt := &Runtime{