Commit 0a7537ec authored by Yifan Gu's avatar Yifan Gu Committed by Yifan Gu

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.
parent 7b4e2552
...@@ -17,6 +17,7 @@ limitations under the License. ...@@ -17,6 +17,7 @@ limitations under the License.
package rkt package rkt
import ( import (
"bufio"
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
...@@ -897,12 +898,24 @@ func serviceFilePath(serviceName string) string { ...@@ -897,12 +898,24 @@ func serviceFilePath(serviceName string) string {
func (r *Runtime) generateRunCommand(pod *api.Pod, uuid, netnsName string) (string, error) { func (r *Runtime) generateRunCommand(pod *api.Pod, uuid, netnsName string) (string, error) {
runPrepared := r.buildCommand("run-prepared").Args 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 // Network namespace set up in kubelet; rkt networking not used
runPrepared = append(runPrepared, "--net=host") runPrepared = append(runPrepared, "--net=host")
var hostname string
var err error
// Setup DNS and hostname configuration.
if len(netnsName) == 0 { if len(netnsName) == 0 {
// TODO(yifan): Let runtimeHelper.GeneratePodHostNameAndDomain() to handle this. // TODO(yifan): Let runtimeHelper.GeneratePodHostNameAndDomain() to handle this.
hostname, err = r.os.Hostname() hostname, err = r.os.Hostname()
...@@ -1051,6 +1064,12 @@ func (r *Runtime) preparePod(pod *api.Pod, podIP string, pullSecrets []api.Secre ...@@ -1051,6 +1064,12 @@ func (r *Runtime) preparePod(pod *api.Pod, podIP string, pullSecrets []api.Secre
newUnitOption(unitKubernetesSection, unitPodNamespace, pod.Namespace), 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) serviceName := makePodServiceFileName(uuid)
glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, format.Pod(pod)) glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, format.Pod(pod))
serviceFile, err := r.os.Create(serviceFilePath(serviceName)) serviceFile, err := r.os.Create(serviceFilePath(serviceName))
...@@ -2115,3 +2134,30 @@ func (r *Runtime) GetPodStatus(uid kubetypes.UID, name, namespace string) (*kube ...@@ -2115,3 +2134,30 @@ func (r *Runtime) GetPodStatus(uid kubetypes.UID, name, namespace string) (*kube
return podStatus, nil 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
}
...@@ -1190,6 +1190,27 @@ func TestGenerateRunCommand(t *testing.T) { ...@@ -1190,6 +1190,27 @@ func TestGenerateRunCommand(t *testing.T) {
nil, 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), 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{ rkt := &Runtime{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment