Merge pull request #24901 from yifan-gu/support_selinux

Automatic merge from submit-queue

rkt: Add pod selinux support.

Currently only pod level selinux context is supported, besides when
running selinux, we will not be able to use the overlay fs, see:
https://github.com/coreos/rkt/issues/1727#issuecomment-173203129.


cc @kubernetes/sig-node  @alban @mjg59 @pmorie
This commit is contained in:
k8s-merge-robot 2016-06-02 07:48:02 -07:00
commit a27058156f
2 changed files with 70 additions and 3 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package rkt
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
@ -904,12 +905,24 @@ func serviceFilePath(serviceName string) string {
func (r *Runtime) generateRunCommand(pod *api.Pod, uuid, netnsName string) (string, error) {
runPrepared := buildCommand(r.config, "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()
@ -1058,6 +1071,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))
@ -2122,3 +2141,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
}

View File

@ -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{