Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
3aee57d4
Commit
3aee57d4
authored
Nov 04, 2016
by
Pengfei Ni
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add security context support in dockershim
parent
3df60eb1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
496 additions
and
71 deletions
+496
-71
convert.go
pkg/kubelet/dockershim/convert.go
+14
-1
docker_container.go
pkg/kubelet/dockershim/docker_container.go
+8
-24
docker_sandbox.go
pkg/kubelet/dockershim/docker_sandbox.go
+18
-23
docker_sandbox_test.go
pkg/kubelet/dockershim/docker_sandbox_test.go
+7
-1
helpers.go
pkg/kubelet/dockershim/helpers.go
+6
-1
security_context.go
pkg/kubelet/dockershim/security_context.go
+158
-0
security_context_test.go
pkg/kubelet/dockershim/security_context_test.go
+257
-0
docker_manager.go
pkg/kubelet/dockertools/docker_manager.go
+3
-3
docker_manager_test.go
pkg/kubelet/dockertools/docker_manager_test.go
+1
-1
provider.go
pkg/securitycontext/provider.go
+11
-4
provider_test.go
pkg/securitycontext/provider_test.go
+8
-8
types.go
pkg/securitycontext/types.go
+5
-5
No files found.
pkg/kubelet/dockershim/convert.go
View file @
3aee57d4
...
@@ -18,12 +18,14 @@ package dockershim
...
@@ -18,12 +18,14 @@ package dockershim
import
(
import
(
"fmt"
"fmt"
"strconv"
"strings"
"strings"
"time"
"time"
dockertypes
"github.com/docker/engine-api/types"
dockertypes
"github.com/docker/engine-api/types"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/kubelet/dockertools"
)
)
// This file contains helper functions to convert docker API types to runtime
// This file contains helper functions to convert docker API types to runtime
...
@@ -55,14 +57,25 @@ func imageInspectToRuntimeAPIImage(image *dockertypes.ImageInspect) (*runtimeApi
...
@@ -55,14 +57,25 @@ func imageInspectToRuntimeAPIImage(image *dockertypes.ImageInspect) (*runtimeApi
return
nil
,
fmt
.
Errorf
(
"unable to convert a nil pointer to a runtime API image"
)
return
nil
,
fmt
.
Errorf
(
"unable to convert a nil pointer to a runtime API image"
)
}
}
var
err
error
var
uid
int64
size
:=
uint64
(
image
.
VirtualSize
)
size
:=
uint64
(
image
.
VirtualSize
)
imageUid
:=
dockertools
.
GetUidFromUser
(
image
.
Config
.
User
)
// Convert image UID to int64 format. Not that it assumes the process in
// the image is running as root if image.Config.User is not set.
if
imageUid
!=
""
{
uid
,
err
=
strconv
.
ParseInt
(
imageUid
,
10
,
64
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"non-numeric user (%q)"
,
imageUid
)
}
}
return
&
runtimeApi
.
Image
{
return
&
runtimeApi
.
Image
{
Id
:
&
image
.
ID
,
Id
:
&
image
.
ID
,
RepoTags
:
image
.
RepoTags
,
RepoTags
:
image
.
RepoTags
,
RepoDigests
:
image
.
RepoDigests
,
RepoDigests
:
image
.
RepoDigests
,
Size_
:
&
size
,
Size_
:
&
size
,
Uid
:
&
uid
,
},
nil
},
nil
}
}
func
toPullableImageID
(
id
string
,
image
*
dockertypes
.
ImageInspect
)
string
{
func
toPullableImageID
(
id
string
,
image
*
dockertypes
.
ImageInspect
)
string
{
...
...
pkg/kubelet/dockershim/docker_container.go
View file @
3aee57d4
...
@@ -120,34 +120,15 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
...
@@ -120,34 +120,15 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
// Fill the HostConfig.
// Fill the HostConfig.
hc
:=
&
dockercontainer
.
HostConfig
{
hc
:=
&
dockercontainer
.
HostConfig
{
Binds
:
generateMountBindings
(
config
.
GetMounts
()),
Binds
:
generateMountBindings
(
config
.
GetMounts
()),
ReadonlyRootfs
:
config
.
GetReadonlyRootfs
(),
Privileged
:
config
.
GetPrivileged
(),
}
}
// Apply
options
derived from the sandbox config.
// Apply
cgroupsParent
derived from the sandbox config.
if
lc
:=
sandboxConfig
.
GetLinux
();
lc
!=
nil
{
if
lc
:=
sandboxConfig
.
GetLinux
();
lc
!=
nil
{
// Apply Cgroup options.
// Apply Cgroup options.
// TODO: Check if this works with per-pod cgroups.
// TODO: Check if this works with per-pod cgroups.
// TODO: we need to pass the cgroup in syntax expected by cgroup driver but shim does not use docker info yet...
// TODO: we need to pass the cgroup in syntax expected by cgroup driver but shim does not use docker info yet...
hc
.
CgroupParent
=
lc
.
GetCgroupParent
()
hc
.
CgroupParent
=
lc
.
GetCgroupParent
()
// Apply namespace options.
sandboxNSMode
:=
fmt
.
Sprintf
(
"container:%v"
,
podSandboxID
)
hc
.
NetworkMode
=
dockercontainer
.
NetworkMode
(
sandboxNSMode
)
hc
.
IpcMode
=
dockercontainer
.
IpcMode
(
sandboxNSMode
)
hc
.
UTSMode
=
""
hc
.
PidMode
=
""
nsOpts
:=
lc
.
GetNamespaceOptions
()
if
nsOpts
!=
nil
{
if
nsOpts
.
GetHostNetwork
()
{
hc
.
UTSMode
=
namespaceModeHost
}
if
nsOpts
.
GetHostPid
()
{
hc
.
PidMode
=
namespaceModeHost
}
}
}
}
// Apply Linux-specific options if applicable.
// Apply Linux-specific options if applicable.
...
@@ -167,6 +148,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
...
@@ -167,6 +148,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
hc
.
OomScoreAdj
=
int
(
rOpts
.
GetOomScoreAdj
())
hc
.
OomScoreAdj
=
int
(
rOpts
.
GetOomScoreAdj
())
}
}
// Note: ShmSize is handled in kube_docker_client.go
// Note: ShmSize is handled in kube_docker_client.go
// Apply security context.
applyContainerSecurityContext
(
lc
,
podSandboxID
,
createConfig
.
Config
,
hc
)
}
}
// Set devices for container.
// Set devices for container.
...
@@ -180,12 +164,12 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
...
@@ -180,12 +164,12 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
}
}
hc
.
Resources
.
Devices
=
devices
hc
.
Resources
.
Devices
=
devices
var
err
error
// Apply appArmor and seccomp options.
hc
.
SecurityOpt
,
err
=
getContainerSecurityOpts
(
config
.
Metadata
.
GetName
(),
sandboxConfig
,
ds
.
seccompProfileRoot
)
securityOpts
,
err
:
=
getContainerSecurityOpts
(
config
.
Metadata
.
GetName
(),
sandboxConfig
,
ds
.
seccompProfileRoot
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"failed to generate container security options for container %q: %v"
,
config
.
Metadata
.
GetName
(),
err
)
return
""
,
fmt
.
Errorf
(
"failed to generate container security options for container %q: %v"
,
config
.
Metadata
.
GetName
(),
err
)
}
}
// TODO: Add or drop capabilities.
hc
.
SecurityOpt
=
append
(
hc
.
SecurityOpt
,
securityOpts
...
)
createConfig
.
HostConfig
=
hc
createConfig
.
HostConfig
=
hc
createResp
,
err
:=
ds
.
client
.
CreateContainer
(
createConfig
)
createResp
,
err
:=
ds
.
client
.
CreateContainer
(
createConfig
)
...
...
pkg/kubelet/dockershim/docker_sandbox.go
View file @
3aee57d4
...
@@ -79,7 +79,7 @@ func (ds *dockerService) RunPodSandbox(config *runtimeApi.PodSandboxConfig) (str
...
@@ -79,7 +79,7 @@ func (ds *dockerService) RunPodSandbox(config *runtimeApi.PodSandboxConfig) (str
if
err
!=
nil
{
if
err
!=
nil
{
return
createResp
.
ID
,
fmt
.
Errorf
(
"failed to start sandbox container for pod %q: %v"
,
config
.
Metadata
.
GetName
(),
err
)
return
createResp
.
ID
,
fmt
.
Errorf
(
"failed to start sandbox container for pod %q: %v"
,
config
.
Metadata
.
GetName
(),
err
)
}
}
if
config
.
GetLinux
()
.
GetNamespaceOptions
()
.
GetHostNetwork
()
{
if
config
.
GetLinux
()
.
Get
SecurityContext
()
.
Get
NamespaceOptions
()
.
GetHostNetwork
()
{
return
createResp
.
ID
,
nil
return
createResp
.
ID
,
nil
}
}
...
@@ -286,6 +286,18 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]
...
@@ -286,6 +286,18 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]
return
result
,
nil
return
result
,
nil
}
}
// applySandboxLinuxOptions applies LinuxPodSandboxConfig to dockercontainer.HostConfig and dockercontainer.ContainerCreateConfig.
func
(
ds
*
dockerService
)
applySandboxLinuxOptions
(
hc
*
dockercontainer
.
HostConfig
,
lc
*
runtimeApi
.
LinuxPodSandboxConfig
,
createConfig
*
dockertypes
.
ContainerCreateConfig
,
image
string
)
error
{
// Apply Cgroup options.
// TODO: Check if this works with per-pod cgroups.
hc
.
CgroupParent
=
lc
.
GetCgroupParent
()
// Apply security context.
applySandboxSecurityContext
(
lc
,
createConfig
.
Config
,
hc
)
return
nil
}
// makeSandboxDockerConfig returns dockertypes.ContainerCreateConfig based on runtimeApi.PodSandboxConfig.
func
(
ds
*
dockerService
)
makeSandboxDockerConfig
(
c
*
runtimeApi
.
PodSandboxConfig
,
image
string
)
(
*
dockertypes
.
ContainerCreateConfig
,
error
)
{
func
(
ds
*
dockerService
)
makeSandboxDockerConfig
(
c
*
runtimeApi
.
PodSandboxConfig
,
image
string
)
(
*
dockertypes
.
ContainerCreateConfig
,
error
)
{
// Merge annotations and labels because docker supports only labels.
// Merge annotations and labels because docker supports only labels.
labels
:=
makeLabels
(
c
.
GetLabels
(),
c
.
GetAnnotations
())
labels
:=
makeLabels
(
c
.
GetLabels
(),
c
.
GetAnnotations
())
...
@@ -316,29 +328,11 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig,
...
@@ -316,29 +328,11 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig,
// Apply linux-specific options.
// Apply linux-specific options.
if
lc
:=
c
.
GetLinux
();
lc
!=
nil
{
if
lc
:=
c
.
GetLinux
();
lc
!=
nil
{
// Apply Cgroup options.
if
err
:=
ds
.
applySandboxLinuxOptions
(
hc
,
lc
,
createConfig
,
image
);
err
!=
nil
{
// TODO: Check if this works with per-pod cgroups.
return
nil
,
err
hc
.
CgroupParent
=
lc
.
GetCgroupParent
()
// Apply namespace options.
hc
.
NetworkMode
,
hc
.
UTSMode
,
hc
.
PidMode
=
""
,
""
,
""
nsOpts
:=
lc
.
GetNamespaceOptions
()
if
nsOpts
!=
nil
{
if
nsOpts
.
GetHostNetwork
()
{
hc
.
NetworkMode
=
namespaceModeHost
}
else
{
// Assume kubelet uses either the cni or the kubenet plugin.
// TODO: support docker networking.
hc
.
NetworkMode
=
"none"
}
if
nsOpts
.
GetHostIpc
()
{
hc
.
IpcMode
=
namespaceModeHost
}
if
nsOpts
.
GetHostPid
()
{
hc
.
PidMode
=
namespaceModeHost
}
}
}
}
}
// Set port mappings.
// Set port mappings.
exposedPorts
,
portBindings
:=
makePortsAndBindings
(
c
.
GetPortMappings
())
exposedPorts
,
portBindings
:=
makePortsAndBindings
(
c
.
GetPortMappings
())
createConfig
.
Config
.
ExposedPorts
=
exposedPorts
createConfig
.
Config
.
ExposedPorts
=
exposedPorts
...
@@ -355,10 +349,11 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig,
...
@@ -355,10 +349,11 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig,
setSandboxResources
(
hc
)
setSandboxResources
(
hc
)
// Set security options.
// Set security options.
hc
.
SecurityOpt
,
err
=
getSandboxSecurityOpts
(
c
,
ds
.
seccompProfileRoot
)
securityOpts
,
err
:
=
getSandboxSecurityOpts
(
c
,
ds
.
seccompProfileRoot
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to generate sandbox security options for sandbox %q: %v"
,
c
.
Metadata
.
GetName
(),
err
)
return
nil
,
fmt
.
Errorf
(
"failed to generate sandbox security options for sandbox %q: %v"
,
c
.
Metadata
.
GetName
(),
err
)
}
}
hc
.
SecurityOpt
=
append
(
hc
.
SecurityOpt
,
securityOpts
...
)
return
createConfig
,
nil
return
createConfig
,
nil
}
}
...
...
pkg/kubelet/dockershim/docker_sandbox_test.go
View file @
3aee57d4
...
@@ -186,7 +186,13 @@ func TestHostNetworkPluginInvocation(t *testing.T) {
...
@@ -186,7 +186,13 @@ func TestHostNetworkPluginInvocation(t *testing.T) {
map
[
string
]
string
{
"annotation"
:
ns
},
map
[
string
]
string
{
"annotation"
:
ns
},
)
)
hostNetwork
:=
true
hostNetwork
:=
true
c
.
Linux
=
&
runtimeApi
.
LinuxPodSandboxConfig
{
NamespaceOptions
:
&
runtimeApi
.
NamespaceOption
{
HostNetwork
:
&
hostNetwork
}}
c
.
Linux
=
&
runtimeApi
.
LinuxPodSandboxConfig
{
SecurityContext
:
&
runtimeApi
.
LinuxSandboxSecurityContext
{
NamespaceOptions
:
&
runtimeApi
.
NamespaceOption
{
HostNetwork
:
&
hostNetwork
,
},
},
}
cID
:=
kubecontainer
.
ContainerID
{
Type
:
runtimeName
,
ID
:
fmt
.
Sprintf
(
"/%v"
,
makeSandboxName
(
c
))}
cID
:=
kubecontainer
.
ContainerID
{
Type
:
runtimeName
,
ID
:
fmt
.
Sprintf
(
"/%v"
,
makeSandboxName
(
c
))}
// No calls to network plugin are expected
// No calls to network plugin are expected
...
...
pkg/kubelet/dockershim/helpers.go
View file @
3aee57d4
...
@@ -123,13 +123,18 @@ func extractLabels(input map[string]string) (map[string]string, map[string]strin
...
@@ -123,13 +123,18 @@ func extractLabels(input map[string]string) (map[string]string, map[string]strin
// '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux
// '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux
// relabeling and the pod provides an SELinux label
// relabeling and the pod provides an SELinux label
func
generateMountBindings
(
mounts
[]
*
runtimeApi
.
Mount
)
(
result
[]
string
)
{
func
generateMountBindings
(
mounts
[]
*
runtimeApi
.
Mount
)
(
result
[]
string
)
{
// TODO: resolve podHasSELinuxLabel
for
_
,
m
:=
range
mounts
{
for
_
,
m
:=
range
mounts
{
bind
:=
fmt
.
Sprintf
(
"%s:%s"
,
m
.
GetHostPath
(),
m
.
GetContainerPath
())
bind
:=
fmt
.
Sprintf
(
"%s:%s"
,
m
.
GetHostPath
(),
m
.
GetContainerPath
())
readOnly
:=
m
.
GetReadonly
()
readOnly
:=
m
.
GetReadonly
()
if
readOnly
{
if
readOnly
{
bind
+=
":ro"
bind
+=
":ro"
}
}
// Only request relabeling if the pod provides an SELinux context. If the pod
// does not provide an SELinux context relabeling will label the volume with
// the container's randomly allocated MCS label. This would restrict access
// to the volume to the container which mounts it first.
// TODO: always relabel if SELinux is enabled and the volume support relabeling
// (refer #33951 and #33663).
if
m
.
GetSelinuxRelabel
()
{
if
m
.
GetSelinuxRelabel
()
{
if
readOnly
{
if
readOnly
{
bind
+=
",Z"
bind
+=
",Z"
...
...
pkg/kubelet/dockershim/security_context.go
0 → 100644
View file @
3aee57d4
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
dockershim
import
(
"fmt"
"strconv"
dockercontainer
"github.com/docker/engine-api/types/container"
"k8s.io/kubernetes/pkg/api"
runtimeapi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/securitycontext"
)
// applySandboxSecurityContext updates docker sandbox options according to security context.
func
applySandboxSecurityContext
(
lc
*
runtimeapi
.
LinuxPodSandboxConfig
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
)
{
if
lc
==
nil
{
return
}
var
sc
*
runtimeapi
.
LinuxContainerSecurityContext
if
lc
.
SecurityContext
!=
nil
{
sc
=
&
runtimeapi
.
LinuxContainerSecurityContext
{
// TODO: We skip application of supplemental groups to the
// sandbox container to work around a runc issue which
// requires containers to have the '/etc/group'. For more
// information see: https://github.com/opencontainers/runc/pull/313.
// This can be removed once the fix makes it into the required
// version of docker.
RunAsUser
:
lc
.
SecurityContext
.
RunAsUser
,
ReadonlyRootfs
:
lc
.
SecurityContext
.
ReadonlyRootfs
,
SelinuxOptions
:
lc
.
SecurityContext
.
SelinuxOptions
,
NamespaceOptions
:
lc
.
SecurityContext
.
NamespaceOptions
,
}
}
modifyContainerConfig
(
sc
,
config
)
modifyHostConfig
(
sc
,
""
,
hc
)
}
// applyContainerSecurityContext updates docker container options according to security context.
func
applyContainerSecurityContext
(
lc
*
runtimeapi
.
LinuxContainerConfig
,
sandboxID
string
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
)
{
if
lc
==
nil
{
return
}
modifyContainerConfig
(
lc
.
SecurityContext
,
config
)
modifyHostConfig
(
lc
.
SecurityContext
,
sandboxID
,
hc
)
return
}
// modifyContainerConfig applies container security context config to dockercontainer.Config.
func
modifyContainerConfig
(
sc
*
runtimeapi
.
LinuxContainerSecurityContext
,
config
*
dockercontainer
.
Config
)
{
if
sc
!=
nil
&&
sc
.
RunAsUser
!=
nil
{
config
.
User
=
strconv
.
FormatInt
(
sc
.
GetRunAsUser
(),
10
)
}
}
// modifyHostConfig applies security context config to dockercontainer.HostConfig.
func
modifyHostConfig
(
sc
*
runtimeapi
.
LinuxContainerSecurityContext
,
sandboxID
string
,
hostConfig
*
dockercontainer
.
HostConfig
)
{
// Apply namespace options.
modifyNamespaceOptions
(
sc
.
GetNamespaceOptions
(),
sandboxID
,
hostConfig
)
if
sc
==
nil
{
return
}
// Apply supplemental groups.
for
_
,
group
:=
range
sc
.
SupplementalGroups
{
hostConfig
.
GroupAdd
=
append
(
hostConfig
.
GroupAdd
,
strconv
.
FormatInt
(
group
,
10
))
}
// Apply security context for the container.
if
sc
.
Privileged
!=
nil
{
hostConfig
.
Privileged
=
sc
.
GetPrivileged
()
}
if
sc
.
ReadonlyRootfs
!=
nil
{
hostConfig
.
ReadonlyRootfs
=
sc
.
GetReadonlyRootfs
()
}
if
sc
.
Capabilities
!=
nil
{
hostConfig
.
CapAdd
=
sc
.
GetCapabilities
()
.
GetAddCapabilities
()
hostConfig
.
CapDrop
=
sc
.
GetCapabilities
()
.
GetDropCapabilities
()
}
if
sc
.
SelinuxOptions
!=
nil
{
hostConfig
.
SecurityOpt
=
securitycontext
.
ModifySecurityOptions
(
hostConfig
.
SecurityOpt
,
&
api
.
SELinuxOptions
{
User
:
sc
.
SelinuxOptions
.
GetUser
(),
Role
:
sc
.
SelinuxOptions
.
GetRole
(),
Type
:
sc
.
SelinuxOptions
.
GetType
(),
Level
:
sc
.
SelinuxOptions
.
GetLevel
(),
},
)
}
}
// modifyNamespaceOptions applies namespaceoptions to dockercontainer.HostConfig.
func
modifyNamespaceOptions
(
nsOpts
*
runtimeapi
.
NamespaceOption
,
sandboxID
string
,
hostConfig
*
dockercontainer
.
HostConfig
)
{
hostNetwork
:=
false
if
nsOpts
!=
nil
{
if
nsOpts
.
HostNetwork
!=
nil
{
hostNetwork
=
nsOpts
.
GetHostNetwork
()
}
if
nsOpts
.
GetHostPid
()
{
hostConfig
.
PidMode
=
namespaceModeHost
}
if
nsOpts
.
GetHostIpc
()
{
hostConfig
.
IpcMode
=
namespaceModeHost
}
}
// Set for sandbox if sandboxID is not provided.
if
sandboxID
==
""
{
modifyHostNetworkOptionForSandbox
(
hostNetwork
,
hostConfig
)
}
else
{
// Set for container is sandboxID is provided.
modifyHostNetworkOptionForContainer
(
hostNetwork
,
sandboxID
,
hostConfig
)
}
}
// modifyHostNetworkOptionForSandbox applies NetworkMode/UTSMode to sandbox's dockercontainer.HostConfig.
func
modifyHostNetworkOptionForSandbox
(
hostNetwork
bool
,
hc
*
dockercontainer
.
HostConfig
)
{
if
hostNetwork
{
hc
.
NetworkMode
=
namespaceModeHost
}
else
{
// Assume kubelet uses either the cni or the kubenet plugin.
// TODO: support docker networking.
hc
.
NetworkMode
=
"none"
}
}
// modifyHostNetworkOptionForContainer applies NetworkMode/UTSMode to container's dockercontainer.HostConfig.
func
modifyHostNetworkOptionForContainer
(
hostNetwork
bool
,
sandboxID
string
,
hc
*
dockercontainer
.
HostConfig
)
{
sandboxNSMode
:=
fmt
.
Sprintf
(
"container:%v"
,
sandboxID
)
hc
.
NetworkMode
=
dockercontainer
.
NetworkMode
(
sandboxNSMode
)
hc
.
IpcMode
=
dockercontainer
.
IpcMode
(
sandboxNSMode
)
hc
.
UTSMode
=
""
hc
.
PidMode
=
""
if
hostNetwork
{
hc
.
UTSMode
=
namespaceModeHost
}
}
pkg/kubelet/dockershim/security_context_test.go
0 → 100644
View file @
3aee57d4
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
dockershim
import
(
"fmt"
"strconv"
"testing"
dockercontainer
"github.com/docker/engine-api/types/container"
"github.com/stretchr/testify/assert"
runtimeapi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/securitycontext"
)
func
TestModifyContainerConfig
(
t
*
testing
.
T
)
{
var
uid
int64
=
123
cases
:=
[]
struct
{
name
string
sc
*
runtimeapi
.
LinuxContainerSecurityContext
expected
*
dockercontainer
.
Config
}{
{
name
:
"container.SecurityContext.RunAsUser set"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{
RunAsUser
:
&
uid
,
},
expected
:
&
dockercontainer
.
Config
{
User
:
strconv
.
FormatInt
(
uid
,
10
),
},
},
{
name
:
"no RunAsUser value set"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{},
expected
:
&
dockercontainer
.
Config
{},
},
}
for
_
,
tc
:=
range
cases
{
dockerCfg
:=
&
dockercontainer
.
Config
{}
modifyContainerConfig
(
tc
.
sc
,
dockerCfg
)
assert
.
Equal
(
t
,
tc
.
expected
,
dockerCfg
,
"[Test case %q]"
,
tc
.
name
)
}
}
func
TestModifyHostConfig
(
t
*
testing
.
T
)
{
priv
:=
true
setPrivSC
:=
&
runtimeapi
.
LinuxContainerSecurityContext
{}
setPrivSC
.
Privileged
=
&
priv
setPrivHC
:=
&
dockercontainer
.
HostConfig
{
Privileged
:
true
,
NetworkMode
:
"none"
,
}
setCapsHC
:=
&
dockercontainer
.
HostConfig
{
NetworkMode
:
"none"
,
CapAdd
:
[]
string
{
"addCapA"
,
"addCapB"
},
CapDrop
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
}
setSELinuxHC
:=
&
dockercontainer
.
HostConfig
{
NetworkMode
:
"none"
,
SecurityOpt
:
[]
string
{
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelLevel
,
"level"
),
},
}
cases
:=
[]
struct
{
name
string
sc
*
runtimeapi
.
LinuxContainerSecurityContext
expected
*
dockercontainer
.
HostConfig
}{
{
name
:
"fully set container.SecurityContext"
,
sc
:
fullValidSecurityContext
(),
expected
:
fullValidHostConfig
(),
},
{
name
:
"container.SecurityContext.Privileged"
,
sc
:
setPrivSC
,
expected
:
setPrivHC
,
},
{
name
:
"container.SecurityContext.Capabilities"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{
Capabilities
:
inputCapabilities
(),
},
expected
:
setCapsHC
,
},
{
name
:
"container.SecurityContext.SELinuxOptions"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{
SelinuxOptions
:
inputSELinuxOptions
(),
},
expected
:
setSELinuxHC
,
},
}
for
_
,
tc
:=
range
cases
{
dockerCfg
:=
&
dockercontainer
.
HostConfig
{}
modifyHostConfig
(
tc
.
sc
,
""
,
dockerCfg
)
assert
.
Equal
(
t
,
tc
.
expected
,
dockerCfg
,
"[Test case %q]"
,
tc
.
name
)
}
}
func
TestModifyHostConfigWithGroups
(
t
*
testing
.
T
)
{
supplementalGroupsSC
:=
&
runtimeapi
.
LinuxContainerSecurityContext
{}
supplementalGroupsSC
.
SupplementalGroups
=
[]
int64
{
2222
}
supplementalGroupHC
:=
&
dockercontainer
.
HostConfig
{
NetworkMode
:
"none"
}
supplementalGroupHC
.
GroupAdd
=
[]
string
{
"2222"
}
testCases
:=
[]
struct
{
name
string
securityContext
*
runtimeapi
.
LinuxContainerSecurityContext
expected
*
dockercontainer
.
HostConfig
}{
{
name
:
"nil"
,
securityContext
:
nil
,
expected
:
&
dockercontainer
.
HostConfig
{
NetworkMode
:
"none"
},
},
{
name
:
"SupplementalGroup"
,
securityContext
:
supplementalGroupsSC
,
expected
:
supplementalGroupHC
,
},
}
for
_
,
tc
:=
range
testCases
{
dockerCfg
:=
&
dockercontainer
.
HostConfig
{}
modifyHostConfig
(
tc
.
securityContext
,
""
,
dockerCfg
)
assert
.
Equal
(
t
,
tc
.
expected
,
dockerCfg
,
"[Test case %q]"
,
tc
.
name
)
}
}
func
TestModifyHostConfigWithSandboxID
(
t
*
testing
.
T
)
{
priv
:=
true
sandboxID
:=
"sandbox"
sandboxNSMode
:=
fmt
.
Sprintf
(
"container:%v"
,
sandboxID
)
setPrivSC
:=
&
runtimeapi
.
LinuxContainerSecurityContext
{}
setPrivSC
.
Privileged
=
&
priv
setPrivHC
:=
&
dockercontainer
.
HostConfig
{
Privileged
:
true
,
IpcMode
:
dockercontainer
.
IpcMode
(
sandboxNSMode
),
NetworkMode
:
dockercontainer
.
NetworkMode
(
sandboxNSMode
),
}
setCapsHC
:=
&
dockercontainer
.
HostConfig
{
CapAdd
:
[]
string
{
"addCapA"
,
"addCapB"
},
CapDrop
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
IpcMode
:
dockercontainer
.
IpcMode
(
sandboxNSMode
),
NetworkMode
:
dockercontainer
.
NetworkMode
(
sandboxNSMode
),
}
setSELinuxHC
:=
&
dockercontainer
.
HostConfig
{
SecurityOpt
:
[]
string
{
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelLevel
,
"level"
),
},
IpcMode
:
dockercontainer
.
IpcMode
(
sandboxNSMode
),
NetworkMode
:
dockercontainer
.
NetworkMode
(
sandboxNSMode
),
}
cases
:=
[]
struct
{
name
string
sc
*
runtimeapi
.
LinuxContainerSecurityContext
expected
*
dockercontainer
.
HostConfig
}{
{
name
:
"container.SecurityContext.Privileged"
,
sc
:
setPrivSC
,
expected
:
setPrivHC
,
},
{
name
:
"container.SecurityContext.Capabilities"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{
Capabilities
:
inputCapabilities
(),
},
expected
:
setCapsHC
,
},
{
name
:
"container.SecurityContext.SELinuxOptions"
,
sc
:
&
runtimeapi
.
LinuxContainerSecurityContext
{
SelinuxOptions
:
inputSELinuxOptions
(),
},
expected
:
setSELinuxHC
,
},
}
for
_
,
tc
:=
range
cases
{
dockerCfg
:=
&
dockercontainer
.
HostConfig
{}
modifyHostConfig
(
tc
.
sc
,
sandboxID
,
dockerCfg
)
assert
.
Equal
(
t
,
tc
.
expected
,
dockerCfg
,
"[Test case %q]"
,
tc
.
name
)
}
}
func
fullValidSecurityContext
()
*
runtimeapi
.
LinuxContainerSecurityContext
{
priv
:=
true
return
&
runtimeapi
.
LinuxContainerSecurityContext
{
Privileged
:
&
priv
,
Capabilities
:
inputCapabilities
(),
SelinuxOptions
:
inputSELinuxOptions
(),
}
}
func
inputCapabilities
()
*
runtimeapi
.
Capability
{
return
&
runtimeapi
.
Capability
{
AddCapabilities
:
[]
string
{
"addCapA"
,
"addCapB"
},
DropCapabilities
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
}
}
func
inputSELinuxOptions
()
*
runtimeapi
.
SELinuxOption
{
user
:=
"user"
role
:=
"role"
stype
:=
"type"
level
:=
"level"
return
&
runtimeapi
.
SELinuxOption
{
User
:
&
user
,
Role
:
&
role
,
Type
:
&
stype
,
Level
:
&
level
,
}
}
func
fullValidHostConfig
()
*
dockercontainer
.
HostConfig
{
return
&
dockercontainer
.
HostConfig
{
Privileged
:
true
,
NetworkMode
:
"none"
,
CapAdd
:
[]
string
{
"addCapA"
,
"addCapB"
},
CapDrop
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
SecurityOpt
:
[]
string
{
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
securitycontext
.
DockerLabelLevel
,
"level"
),
},
}
}
pkg/kubelet/dockertools/docker_manager.go
View file @
3aee57d4
...
@@ -2474,7 +2474,7 @@ func (dm *DockerManager) isImageRoot(image string) (bool, error) {
...
@@ -2474,7 +2474,7 @@ func (dm *DockerManager) isImageRoot(image string) (bool, error) {
return
false
,
fmt
.
Errorf
(
"unable to inspect image %s, nil Config"
,
image
)
return
false
,
fmt
.
Errorf
(
"unable to inspect image %s, nil Config"
,
image
)
}
}
user
:=
g
etUidFromUser
(
img
.
Config
.
User
)
user
:=
G
etUidFromUser
(
img
.
Config
.
User
)
// if no user is defined container will run as root
// if no user is defined container will run as root
if
user
==
""
{
if
user
==
""
{
return
true
,
nil
return
true
,
nil
...
@@ -2488,8 +2488,8 @@ func (dm *DockerManager) isImageRoot(image string) (bool, error) {
...
@@ -2488,8 +2488,8 @@ func (dm *DockerManager) isImageRoot(image string) (bool, error) {
return
uid
==
0
,
nil
return
uid
==
0
,
nil
}
}
//
g
etUidFromUser splits the uid out of an uid:gid string.
//
G
etUidFromUser splits the uid out of an uid:gid string.
func
g
etUidFromUser
(
id
string
)
string
{
func
G
etUidFromUser
(
id
string
)
string
{
if
id
==
""
{
if
id
==
""
{
return
id
return
id
}
}
...
...
pkg/kubelet/dockertools/docker_manager_test.go
View file @
3aee57d4
...
@@ -1454,7 +1454,7 @@ func TestGetUidFromUser(t *testing.T) {
...
@@ -1454,7 +1454,7 @@ func TestGetUidFromUser(t *testing.T) {
},
},
}
}
for
k
,
v
:=
range
tests
{
for
k
,
v
:=
range
tests
{
actual
:=
g
etUidFromUser
(
v
.
input
)
actual
:=
G
etUidFromUser
(
v
.
input
)
if
actual
!=
v
.
expect
{
if
actual
!=
v
.
expect
{
t
.
Errorf
(
"%s failed. Expected %s but got %s"
,
k
,
v
.
expect
,
actual
)
t
.
Errorf
(
"%s failed. Expected %s but got %s"
,
k
,
v
.
expect
,
actual
)
}
}
...
...
pkg/securitycontext/provider.go
View file @
3aee57d4
...
@@ -91,13 +91,20 @@ func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container
...
@@ -91,13 +91,20 @@ func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container
}
}
if
effectiveSC
.
SELinuxOptions
!=
nil
{
if
effectiveSC
.
SELinuxOptions
!=
nil
{
hostConfig
.
SecurityOpt
=
modifySecurityOption
(
hostConfig
.
SecurityOpt
,
dockerLabelUser
,
effectiveSC
.
SELinuxOptions
.
User
)
hostConfig
.
SecurityOpt
=
ModifySecurityOptions
(
hostConfig
.
SecurityOpt
,
effectiveSC
.
SELinuxOptions
)
hostConfig
.
SecurityOpt
=
modifySecurityOption
(
hostConfig
.
SecurityOpt
,
dockerLabelRole
,
effectiveSC
.
SELinuxOptions
.
Role
)
hostConfig
.
SecurityOpt
=
modifySecurityOption
(
hostConfig
.
SecurityOpt
,
dockerLabelType
,
effectiveSC
.
SELinuxOptions
.
Type
)
hostConfig
.
SecurityOpt
=
modifySecurityOption
(
hostConfig
.
SecurityOpt
,
dockerLabelLevel
,
effectiveSC
.
SELinuxOptions
.
Level
)
}
}
}
}
// ModifySecurityOptions adds SELinux options to config.
func
ModifySecurityOptions
(
config
[]
string
,
selinuxOpts
*
api
.
SELinuxOptions
)
[]
string
{
config
=
modifySecurityOption
(
config
,
DockerLabelUser
,
selinuxOpts
.
User
)
config
=
modifySecurityOption
(
config
,
DockerLabelRole
,
selinuxOpts
.
Role
)
config
=
modifySecurityOption
(
config
,
DockerLabelType
,
selinuxOpts
.
Type
)
config
=
modifySecurityOption
(
config
,
DockerLabelLevel
,
selinuxOpts
.
Level
)
return
config
}
// modifySecurityOption adds the security option of name to the config array with value in the form
// modifySecurityOption adds the security option of name to the config array with value in the form
// of name:value
// of name:value
func
modifySecurityOption
(
config
[]
string
,
name
,
value
string
)
[]
string
{
func
modifySecurityOption
(
config
[]
string
,
name
,
value
string
)
[]
string
{
...
...
pkg/securitycontext/provider_test.go
View file @
3aee57d4
...
@@ -104,10 +104,10 @@ func TestModifyHostConfig(t *testing.T) {
...
@@ -104,10 +104,10 @@ func TestModifyHostConfig(t *testing.T) {
setSELinuxHC
:=
&
dockercontainer
.
HostConfig
{}
setSELinuxHC
:=
&
dockercontainer
.
HostConfig
{}
setSELinuxHC
.
SecurityOpt
=
[]
string
{
setSELinuxHC
.
SecurityOpt
=
[]
string
{
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelLevel
,
"level"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelLevel
,
"level"
),
}
}
// seLinuxLabelsSC := fullValidSecurityContext()
// seLinuxLabelsSC := fullValidSecurityContext()
...
@@ -325,10 +325,10 @@ func fullValidHostConfig() *dockercontainer.HostConfig {
...
@@ -325,10 +325,10 @@ func fullValidHostConfig() *dockercontainer.HostConfig {
CapAdd
:
[]
string
{
"addCapA"
,
"addCapB"
},
CapAdd
:
[]
string
{
"addCapA"
,
"addCapB"
},
CapDrop
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
CapDrop
:
[]
string
{
"dropCapA"
,
"dropCapB"
},
SecurityOpt
:
[]
string
{
SecurityOpt
:
[]
string
{
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelUser
,
"user"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelRole
,
"role"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelType
,
"type"
),
fmt
.
Sprintf
(
"%s:%s"
,
d
ockerLabelLevel
,
"level"
),
fmt
.
Sprintf
(
"%s:%s"
,
D
ockerLabelLevel
,
"level"
),
},
},
}
}
}
}
pkg/securitycontext/types.go
View file @
3aee57d4
...
@@ -41,9 +41,9 @@ type SecurityContextProvider interface {
...
@@ -41,9 +41,9 @@ type SecurityContextProvider interface {
}
}
const
(
const
(
d
ockerLabelUser
string
=
"label:user"
D
ockerLabelUser
string
=
"label:user"
d
ockerLabelRole
string
=
"label:role"
D
ockerLabelRole
string
=
"label:role"
d
ockerLabelType
string
=
"label:type"
D
ockerLabelType
string
=
"label:type"
d
ockerLabelLevel
string
=
"label:level"
D
ockerLabelLevel
string
=
"label:level"
d
ockerLabelDisable
string
=
"label:disable"
D
ockerLabelDisable
string
=
"label:disable"
)
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment