Merge pull request #367 from sameo/topic/host-privileged-runtime

Support alternate runtime for host privileged operations
This commit is contained in:
Pengfei Ni 2017-03-05 07:53:20 +08:00 committed by GitHub
commit 3195f45904
7 changed files with 116 additions and 52 deletions

View file

@ -76,6 +76,10 @@ type RuntimeConfig struct {
// yet merged a CLI API (so we assume runC's API here).
Runtime string `toml:"runtime"`
// RuntimeHostPrivileged is a path to the OCI runtime which ocid will be
// using for host privileged operations.
RuntimeHostPrivileged string `toml:"runtime_host_privileged"`
// Conmon is the path to conmon binary, used for managing the runtime.
Conmon string `toml:"conmon"`
@ -205,8 +209,9 @@ func DefaultConfig() *Config {
Listen: "/var/run/ocid.sock",
},
RuntimeConfig: RuntimeConfig{
Runtime: "/usr/bin/runc",
Conmon: conmonPath,
Runtime: "/usr/bin/runc",
RuntimeHostPrivileged: "",
Conmon: conmonPath,
ConmonEnv: []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
},

View file

@ -25,6 +25,37 @@ const (
seccompLocalhostPrefix = "localhost/"
)
func addOciBindMounts(sb *sandbox, containerConfig *pb.ContainerConfig, specgen *generate.Generator) error {
mounts := containerConfig.GetMounts()
for _, mount := range mounts {
dest := mount.ContainerPath
if dest == "" {
return fmt.Errorf("Mount.ContainerPath is empty")
}
src := mount.HostPath
if src == "" {
return fmt.Errorf("Mount.HostPath is empty")
}
options := []string{"rw"}
if mount.Readonly {
options = []string{"ro"}
}
if mount.SelinuxRelabel {
// Need a way in kubernetes to determine if the volume is shared or private
if err := label.Relabel(src, sb.mountLabel, true); err != nil && err != syscall.ENOTSUP {
return fmt.Errorf("relabel failed %s: %v", src, err)
}
}
specgen.AddBindMount(src, dest, options)
}
return nil
}
// CreateContainer creates a new container in specified PodSandbox
func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (res *pb.CreateContainerResponse, err error) {
logrus.Debugf("CreateContainerRequest %+v", req)
@ -145,31 +176,8 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
}
}
mounts := containerConfig.GetMounts()
for _, mount := range mounts {
dest := mount.ContainerPath
if dest == "" {
return nil, fmt.Errorf("Mount.ContainerPath is empty")
}
src := mount.HostPath
if src == "" {
return nil, fmt.Errorf("Mount.HostPath is empty")
}
options := []string{"rw"}
if mount.Readonly {
options = []string{"ro"}
}
if mount.SelinuxRelabel {
// Need a way in kubernetes to determine if the volume is shared or private
if err := label.Relabel(src, sb.mountLabel, true); err != nil && err != syscall.ENOTSUP {
return nil, fmt.Errorf("relabel failed %s: %v", src, err)
}
}
specgen.AddBindMount(src, dest, options)
if err := addOciBindMounts(sb, containerConfig, &specgen); err != nil {
return nil, err
}
labels := containerConfig.GetLabels()
@ -384,7 +392,7 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
return nil, err
}
container, err := oci.NewContainer(containerID, containerName, containerInfo.RunDir, logPath, sb.netNs(), labels, annotations, imageSpec, metadata, sb.id, containerConfig.Tty)
container, err := oci.NewContainer(containerID, containerName, containerInfo.RunDir, logPath, sb.netNs(), labels, annotations, imageSpec, metadata, sb.id, containerConfig.Tty, sb.privileged)
if err != nil {
return nil, err
}

View file

@ -139,6 +139,7 @@ type sandbox struct {
metadata *pb.PodSandboxMetadata
shmPath string
cgroupParent string
privileged bool
}
const (

View file

@ -17,6 +17,32 @@ import (
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
// privilegedSandbox returns true if the sandbox configuration
// requires additional host privileges for the sandbox.
func (s *Server) privilegedSandbox(req *pb.RunPodSandboxRequest) bool {
securityContext := req.GetConfig().GetLinux().GetSecurityContext()
if securityContext == nil {
return false
}
if securityContext.Privileged {
return true
}
namespaceOptions := securityContext.GetNamespaceOptions()
if namespaceOptions == nil {
return false
}
if namespaceOptions.HostNetwork ||
namespaceOptions.HostPid ||
namespaceOptions.HostIpc {
return true
}
return false
}
func (s *Server) runContainer(container *oci.Container) error {
if err := s.runtime.CreateContainer(container); err != nil {
return err
@ -218,6 +244,8 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
}
}()
privileged := s.privilegedSandbox(req)
g.AddAnnotation("ocid/metadata", string(metadataJSON))
g.AddAnnotation("ocid/labels", string(labelsJSON))
g.AddAnnotation("ocid/annotations", string(annotationsJSON))
@ -228,6 +256,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
g.AddAnnotation("ocid/container_name", containerName)
g.AddAnnotation("ocid/container_id", id)
g.AddAnnotation("ocid/shm_path", shmPath)
g.AddAnnotation("ocid/privileged_runtime", fmt.Sprintf("%v", privileged))
sb := &sandbox{
id: id,
@ -240,6 +269,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
mountLabel: mountLabel,
metadata: metadata,
shmPath: shmPath,
privileged: privileged,
}
s.addSandbox(sb)
@ -344,7 +374,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
return nil, fmt.Errorf("failed to write runtime configuration for pod sandbox %s(%s): %v", sb.name, id, err)
}
container, err := oci.NewContainer(id, containerName, podContainer.RunDir, logDir, sb.netNs(), labels, annotations, nil, nil, id, false)
container, err := oci.NewContainer(id, containerName, podContainer.RunDir, logDir, sb.netNs(), labels, annotations, nil, nil, id, false, sb.privileged)
if err != nil {
return nil, err
}

View file

@ -105,7 +105,7 @@ func (s *Server) loadContainer(id string) error {
return err
}
ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations["ocid/log_path"], sb.netNs(), labels, annotations, img, &metadata, sb.id, tty)
ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations["ocid/log_path"], sb.netNs(), labels, annotations, img, &metadata, sb.id, tty, sb.privileged)
if err != nil {
return err
}
@ -173,6 +173,8 @@ func (s *Server) loadSandbox(id string) error {
return err
}
privileged := m.Annotations["ocid/privileged_runtime"] == "true"
sb := &sandbox{
id: id,
name: name,
@ -184,6 +186,7 @@ func (s *Server) loadSandbox(id string) error {
annotations: annotations,
metadata: &metadata,
shmPath: m.Annotations["ocid/shm_path"],
privileged: privileged,
}
// We add a netNS only if we can load a permanent one.
@ -223,7 +226,8 @@ func (s *Server) loadSandbox(id string) error {
s.releaseContainerName(cname)
}
}()
scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], cname, sandboxPath, sandboxPath, sb.netNs(), labels, annotations, nil, nil, id, false)
scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], cname, sandboxPath, sandboxPath, sb.netNs(), labels, annotations, nil, nil, id, false, privileged)
if err != nil {
return err
}
@ -452,7 +456,7 @@ func New(config *Config) (*Server, error) {
return nil, err
}
r, err := oci.New(config.Runtime, config.Conmon, config.ConmonEnv, config.CgroupManager)
r, err := oci.New(config.Runtime, config.RuntimeHostPrivileged, config.Conmon, config.ConmonEnv, config.CgroupManager)
if err != nil {
return nil, err
}