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
ac76766a
Commit
ac76766a
authored
May 01, 2017
by
Pengfei Ni
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CRI: move apparmor annotations to container security context
parent
08606b53
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
89 additions
and
91 deletions
+89
-91
api.pb.go
pkg/kubelet/api/v1alpha1/runtime/api.pb.go
+0
-0
api.proto
pkg/kubelet/api/v1alpha1/runtime/api.proto
+8
-12
docker_container.go
pkg/kubelet/dockershim/docker_container.go
+7
-6
docker_sandbox.go
pkg/kubelet/dockershim/docker_sandbox.go
+4
-2
helpers.go
pkg/kubelet/dockershim/helpers.go
+18
-12
helpers_test.go
pkg/kubelet/dockershim/helpers_test.go
+21
-47
security_context.go
pkg/kubelet/dockershim/security_context.go
+23
-9
docker_manager.go
pkg/kubelet/dockertools/docker_manager.go
+3
-3
BUILD
pkg/kubelet/kuberuntime/BUILD
+1
-0
security_context.go
pkg/kubelet/kuberuntime/security_context.go
+4
-0
No files found.
pkg/kubelet/api/v1alpha1/runtime/api.pb.go
View file @
ac76766a
This diff is collapsed.
Click to expand it.
pkg/kubelet/api/v1alpha1/runtime/api.proto
View file @
ac76766a
...
...
@@ -269,17 +269,7 @@ message PodSandboxConfig {
// and the CRI). Whenever possible, however, runtime authors SHOULD
// consider proposing new typed fields for any new features instead.
//
// 1. AppArmor
//
// key: container.apparmor.security.beta.kubernetes.io/<container_name>
// description: apparmor profile for a container in this pod.
// value:
// * runtime/default: equivalent to not specifying a profile.
// * localhost/<profile_name>: profile loaded on the node
// (localhost) by name. The possible profile names are detailed at
// http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference
//
// 2. Seccomp
// 1. Seccomp
//
// key: security.alpha.kubernetes.io/seccomp/pod
// description: the seccomp profile for the containers of an entire pod.
...
...
@@ -296,7 +286,7 @@ message PodSandboxConfig {
// local seccomp profile root. Note that profile root is set in
// kubelet, and it is not passed in CRI yet, see https://issues.k8s.io/36997.
//
//
3
. Sysctls
//
2
. Sysctls
//
// key: security.alpha.kubernetes.io/sysctls
// description: list of safe sysctls which are set for the sandbox.
...
...
@@ -526,6 +516,12 @@ message LinuxContainerSecurityContext {
// List of groups applied to the first process run in the container, in
// addition to the container's primary GID.
repeated
int64
supplemental_groups
=
8
;
// AppArmor profile for the container, candidate values are:
// * runtime/default: equivalent to not specifying a profile.
// * localhost/<profile_name>: profile loaded on the node
// (localhost) by name. The possible profile names are detailed at
// http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference
string
apparmor_profile
=
9
;
}
// LinuxContainerConfig contains platform-specific configuration for
...
...
pkg/kubelet/dockershim/docker_container.go
View file @
ac76766a
...
...
@@ -145,7 +145,6 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi
// Apply Linux-specific options if applicable.
if
lc
:=
config
.
GetLinux
();
lc
!=
nil
{
// Apply resource options.
// TODO: Check if the units are correct.
// TODO: Can we assume the defaults are sane?
rOpts
:=
lc
.
GetResources
()
...
...
@@ -162,7 +161,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi
// Note: ShmSize is handled in kube_docker_client.go
// Apply security context.
applyContainerSecurityContext
(
lc
,
podSandboxID
,
createConfig
.
Config
,
hc
,
securityOptSep
)
if
err
=
applyContainerSecurityContext
(
lc
,
podSandboxID
,
createConfig
.
Config
,
hc
,
securityOptSep
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"failed to apply container security context for container %q: %v"
,
config
.
Metadata
.
Name
,
err
)
}
modifyPIDNamespaceOverrides
(
ds
.
disableSharedPID
,
apiVersion
,
hc
)
}
...
...
@@ -187,12 +188,12 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeapi
}
hc
.
Resources
.
Devices
=
devices
// Apply
appArmor and
seccomp options.
sec
urityOpts
,
err
:=
getContainer
SecurityOpts
(
config
.
Metadata
.
Name
,
sandboxConfig
,
ds
.
seccompProfileRoot
,
securityOptSep
)
// Apply seccomp options.
sec
compSecurityOpts
,
err
:=
getSeccomp
SecurityOpts
(
config
.
Metadata
.
Name
,
sandboxConfig
,
ds
.
seccompProfileRoot
,
securityOptSep
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"failed to generate
container
security options for container %q: %v"
,
config
.
Metadata
.
Name
,
err
)
return
""
,
fmt
.
Errorf
(
"failed to generate
seccomp
security options for container %q: %v"
,
config
.
Metadata
.
Name
,
err
)
}
hc
.
SecurityOpt
=
append
(
hc
.
SecurityOpt
,
securityOpts
...
)
hc
.
SecurityOpt
=
append
(
hc
.
SecurityOpt
,
sec
compSec
urityOpts
...
)
createConfig
.
HostConfig
=
hc
createResp
,
err
:=
ds
.
client
.
CreateContainer
(
createConfig
)
...
...
pkg/kubelet/dockershim/docker_sandbox.go
View file @
ac76766a
...
...
@@ -475,7 +475,9 @@ func (ds *dockerService) applySandboxLinuxOptions(hc *dockercontainer.HostConfig
}
hc
.
CgroupParent
=
cgroupParent
// Apply security context.
applySandboxSecurityContext
(
lc
,
createConfig
.
Config
,
hc
,
ds
.
network
,
separator
)
if
err
=
applySandboxSecurityContext
(
lc
,
createConfig
.
Config
,
hc
,
ds
.
network
,
separator
);
err
!=
nil
{
return
err
}
return
nil
}
...
...
@@ -541,7 +543,7 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeapi.PodSandboxConfig,
}
// Set security options.
securityOpts
,
err
:=
getS
andboxSecurityOpts
(
c
,
ds
.
seccompProfileRoot
,
securityOptSep
)
securityOpts
,
err
:=
getS
eccompSecurityOpts
(
sandboxContainerName
,
c
,
ds
.
seccompProfileRoot
,
securityOptSep
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to generate sandbox security options for sandbox %q: %v"
,
c
.
Metadata
.
Name
,
err
)
}
...
...
pkg/kubelet/dockershim/helpers.go
View file @
ac76766a
...
...
@@ -181,26 +181,32 @@ func makePortsAndBindings(pm []*runtimeapi.PortMapping) (map[dockernat.Port]stru
return
exposedPorts
,
portBindings
}
// get
ContainerSecurityOpt gets container security options from container and sandbox config, currently from
sandbox
// annotations.
// get
SeccompSecurityOpts gets container seccomp options from container and
sandbox
//
config, currently from sandbox
annotations.
// It is an experimental feature and may be promoted to official runtime api in the future.
func
getContainerSecurityOpts
(
containerName
string
,
sandboxConfig
*
runtimeapi
.
PodSandboxConfig
,
seccompProfileRoot
string
,
separator
rune
)
([]
string
,
error
)
{
appArmorOpts
,
err
:=
dockertools
.
GetAppArmorOpts
(
sandboxConfig
.
GetAnnotations
(),
containerName
)
if
err
!=
nil
{
return
nil
,
err
}
func
getSeccompSecurityOpts
(
containerName
string
,
sandboxConfig
*
runtimeapi
.
PodSandboxConfig
,
seccompProfileRoot
string
,
separator
rune
)
([]
string
,
error
)
{
seccompOpts
,
err
:=
dockertools
.
GetSeccompOpts
(
sandboxConfig
.
GetAnnotations
(),
containerName
,
seccompProfileRoot
)
if
err
!=
nil
{
return
nil
,
err
}
securityOpts
:=
append
(
appArmorOpts
,
seccompOpts
...
)
fmtOpts
:=
dockertools
.
FmtDockerOpts
(
sec
urity
Opts
,
separator
)
fmtOpts
:=
dockertools
.
FmtDockerOpts
(
sec
comp
Opts
,
separator
)
return
fmtOpts
,
nil
}
func
getSandboxSecurityOpts
(
sandboxConfig
*
runtimeapi
.
PodSandboxConfig
,
seccompProfileRoot
string
,
separator
rune
)
([]
string
,
error
)
{
// sandboxContainerName doesn't exist in the pod, so pod security options will be returned by default.
return
getContainerSecurityOpts
(
sandboxContainerName
,
sandboxConfig
,
seccompProfileRoot
,
separator
)
// getApparmorSecurityOpts gets apparmor options from container config.
func
getApparmorSecurityOpts
(
sc
*
runtimeapi
.
LinuxContainerSecurityContext
,
separator
rune
)
([]
string
,
error
)
{
if
sc
==
nil
||
sc
.
ApparmorProfile
==
""
{
return
nil
,
nil
}
appArmorOpts
,
err
:=
dockertools
.
GetAppArmorOpts
(
sc
.
ApparmorProfile
)
if
err
!=
nil
{
return
nil
,
err
}
fmtOpts
:=
dockertools
.
FmtDockerOpts
(
appArmorOpts
,
separator
)
return
fmtOpts
,
nil
}
func
getNetworkNamespace
(
c
*
dockertypes
.
ContainerJSON
)
string
{
...
...
pkg/kubelet/dockershim/helpers_test.go
View file @
ac76766a
...
...
@@ -43,10 +43,10 @@ func TestLabelsAndAnnotationsRoundTrip(t *testing.T) {
assert
.
Equal
(
t
,
expectedAnnotations
,
actualAnnotations
)
}
// TestGet
ContainerSecurityOpts tests the logic of generating container security
options from sandbox annotations.
// TestGet
SeccompSecurityOpts tests the logic of generating container seccomp
options from sandbox annotations.
// The actual profile loading logic is tested in dockertools.
// TODO: Migrate the corresponding test to dockershim.
func
TestGet
Container
SecurityOpts
(
t
*
testing
.
T
)
{
func
TestGet
Seccomp
SecurityOpts
(
t
*
testing
.
T
)
{
containerName
:=
"bar"
makeConfig
:=
func
(
annotations
map
[
string
]
string
)
*
runtimeapi
.
PodSandboxConfig
{
return
makeSandboxConfigWithLabelsAndAnnotations
(
"pod"
,
"ns"
,
"1234"
,
1
,
nil
,
annotations
)
...
...
@@ -78,29 +78,10 @@ func TestGetContainerSecurityOpts(t *testing.T) {
v1
.
SeccompPodAnnotationKey
:
"docker/default"
,
}),
expectedOpts
:
nil
,
},
{
msg
:
"AppArmor runtime/default"
,
config
:
makeConfig
(
map
[
string
]
string
{
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileRuntimeDefault
,
}),
expectedOpts
:
[]
string
{
"seccomp=unconfined"
},
},
{
msg
:
"AppArmor local profile"
,
config
:
makeConfig
(
map
[
string
]
string
{
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileNamePrefix
+
"foo"
,
}),
expectedOpts
:
[]
string
{
"seccomp=unconfined"
,
"apparmor=foo"
},
},
{
msg
:
"AppArmor and seccomp profile"
,
config
:
makeConfig
(
map
[
string
]
string
{
v1
.
SeccompContainerAnnotationKeyPrefix
+
containerName
:
"docker/default"
,
apparmor
.
ContainerAnnotationKeyPrefix
+
containerName
:
apparmor
.
ProfileNamePrefix
+
"foo"
,
}),
expectedOpts
:
[]
string
{
"apparmor=foo"
},
}}
for
i
,
test
:=
range
tests
{
opts
,
err
:=
get
Container
SecurityOpts
(
containerName
,
test
.
config
,
"test/seccomp/profile/root"
,
'='
)
opts
,
err
:=
get
Seccomp
SecurityOpts
(
containerName
,
test
.
config
,
"test/seccomp/profile/root"
,
'='
)
assert
.
NoError
(
t
,
err
,
"TestCase[%d]: %s"
,
i
,
test
.
msg
)
assert
.
Len
(
t
,
opts
,
len
(
test
.
expectedOpts
),
"TestCase[%d]: %s"
,
i
,
test
.
msg
)
for
_
,
opt
:=
range
test
.
expectedOpts
{
...
...
@@ -109,43 +90,36 @@ func TestGetContainerSecurityOpts(t *testing.T) {
}
}
// TestGetSandboxSecurityOpts tests the logic of generating sandbox security options from sandbox annotations.
func
TestGetSandboxSecurityOpts
(
t
*
testing
.
T
)
{
makeConfig
:=
func
(
annotations
map
[
string
]
string
)
*
runtimeapi
.
PodSandboxConfig
{
return
makeSandboxConfigWithLabelsAndAnnotations
(
"pod"
,
"ns"
,
"1234"
,
1
,
nil
,
annotations
)
// TestGetApparmorSecurityOpts tests the logic of generating container apparmor options from sandbox annotations.
// The actual profile loading logic is tested in dockertools.
// TODO: Migrate the corresponding test to dockershim.
func
TestGetApparmorSecurityOpts
(
t
*
testing
.
T
)
{
makeConfig
:=
func
(
profile
string
)
*
runtimeapi
.
LinuxContainerSecurityContext
{
return
&
runtimeapi
.
LinuxContainerSecurityContext
{
ApparmorProfile
:
profile
,
}
}
tests
:=
[]
struct
{
msg
string
config
*
runtimeapi
.
PodSandboxConfig
config
*
runtimeapi
.
LinuxContainerSecurityContext
expectedOpts
[]
string
}{{
msg
:
"No security annotations"
,
config
:
makeConfig
(
nil
),
expectedOpts
:
[]
string
{
"seccomp=unconfined"
},
},
{
msg
:
"Seccomp default"
,
config
:
makeConfig
(
map
[
string
]
string
{
v1
.
SeccompPodAnnotationKey
:
"docker/default"
,
}),
msg
:
"No AppArmor options"
,
config
:
makeConfig
(
""
),
expectedOpts
:
nil
,
},
{
msg
:
"Seccomp unconfined"
,
config
:
makeConfig
(
map
[
string
]
string
{
v1
.
SeccompPodAnnotationKey
:
"unconfined"
,
}),
expectedOpts
:
[]
string
{
"seccomp=unconfined"
},
msg
:
"AppArmor runtime/default"
,
config
:
makeConfig
(
"runtime/default"
),
expectedOpts
:
[]
string
{},
},
{
msg
:
"Seccomp pod and container profile"
,
config
:
makeConfig
(
map
[
string
]
string
{
v1
.
SeccompContainerAnnotationKeyPrefix
+
"test-container"
:
"unconfined"
,
v1
.
SeccompPodAnnotationKey
:
"docker/default"
,
}),
expectedOpts
:
nil
,
msg
:
"AppArmor local profile"
,
config
:
makeConfig
(
apparmor
.
ProfileNamePrefix
+
"foo"
),
expectedOpts
:
[]
string
{
"apparmor=foo"
},
}}
for
i
,
test
:=
range
tests
{
opts
,
err
:=
get
SandboxSecurityOpts
(
test
.
config
,
"test/seccomp/profile/root"
,
'='
)
opts
,
err
:=
get
ApparmorSecurityOpts
(
test
.
config
,
'='
)
assert
.
NoError
(
t
,
err
,
"TestCase[%d]: %s"
,
i
,
test
.
msg
)
assert
.
Len
(
t
,
opts
,
len
(
test
.
expectedOpts
),
"TestCase[%d]: %s"
,
i
,
test
.
msg
)
for
_
,
opt
:=
range
test
.
expectedOpts
{
...
...
pkg/kubelet/dockershim/security_context.go
View file @
ac76766a
...
...
@@ -31,9 +31,9 @@ import (
)
// applySandboxSecurityContext updates docker sandbox options according to security context.
func
applySandboxSecurityContext
(
lc
*
runtimeapi
.
LinuxPodSandboxConfig
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
,
network
*
knetwork
.
PluginManager
,
separator
rune
)
{
func
applySandboxSecurityContext
(
lc
*
runtimeapi
.
LinuxPodSandboxConfig
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
,
network
*
knetwork
.
PluginManager
,
separator
rune
)
error
{
if
lc
==
nil
{
return
return
nil
}
var
sc
*
runtimeapi
.
LinuxContainerSecurityContext
...
...
@@ -48,20 +48,25 @@ func applySandboxSecurityContext(lc *runtimeapi.LinuxPodSandboxConfig, config *d
}
modifyContainerConfig
(
sc
,
config
)
modifyHostConfig
(
sc
,
hc
,
separator
)
if
err
:=
modifyHostConfig
(
sc
,
hc
,
separator
);
err
!=
nil
{
return
err
}
modifySandboxNamespaceOptions
(
sc
.
GetNamespaceOptions
(),
hc
,
network
)
return
nil
}
// applyContainerSecurityContext updates docker container options according to security context.
func
applyContainerSecurityContext
(
lc
*
runtimeapi
.
LinuxContainerConfig
,
sandboxID
string
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
,
separator
rune
)
{
func
applyContainerSecurityContext
(
lc
*
runtimeapi
.
LinuxContainerConfig
,
sandboxID
string
,
config
*
dockercontainer
.
Config
,
hc
*
dockercontainer
.
HostConfig
,
separator
rune
)
error
{
if
lc
==
nil
{
return
return
nil
}
modifyContainerConfig
(
lc
.
SecurityContext
,
config
)
modifyHostConfig
(
lc
.
SecurityContext
,
hc
,
separator
)
if
err
:=
modifyHostConfig
(
lc
.
SecurityContext
,
hc
,
separator
);
err
!=
nil
{
return
err
}
modifyContainerNamespaceOptions
(
lc
.
SecurityContext
.
GetNamespaceOptions
(),
sandboxID
,
hc
)
return
return
nil
}
// modifyContainerConfig applies container security context config to dockercontainer.Config.
...
...
@@ -78,9 +83,9 @@ func modifyContainerConfig(sc *runtimeapi.LinuxContainerSecurityContext, config
}
// modifyHostConfig applies security context config to dockercontainer.HostConfig.
func
modifyHostConfig
(
sc
*
runtimeapi
.
LinuxContainerSecurityContext
,
hostConfig
*
dockercontainer
.
HostConfig
,
separator
rune
)
{
func
modifyHostConfig
(
sc
*
runtimeapi
.
LinuxContainerSecurityContext
,
hostConfig
*
dockercontainer
.
HostConfig
,
separator
rune
)
error
{
if
sc
==
nil
{
return
return
nil
}
// Apply supplemental groups.
...
...
@@ -107,6 +112,15 @@ func modifyHostConfig(sc *runtimeapi.LinuxContainerSecurityContext, hostConfig *
separator
,
)
}
// Apply apparmor options.
apparmorSecurityOpts
,
err
:=
getApparmorSecurityOpts
(
sc
,
separator
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to generate apparmor security options: %v"
,
err
)
}
hostConfig
.
SecurityOpt
=
append
(
hostConfig
.
SecurityOpt
,
apparmorSecurityOpts
...
)
return
nil
}
// modifySandboxNamespaceOptions apply namespace options for sandbox
...
...
pkg/kubelet/dockertools/docker_manager.go
View file @
ac76766a
...
...
@@ -1260,13 +1260,13 @@ func GetSeccompOpts(annotations map[string]string, ctrName, profileRoot string)
// Get the docker security options for AppArmor.
func
(
dm
*
DockerManager
)
getAppArmorOpts
(
pod
*
v1
.
Pod
,
ctrName
string
)
([]
dockerOpt
,
error
)
{
return
GetAppArmorOpts
(
pod
.
Annotations
,
ctrName
)
profile
:=
apparmor
.
GetProfileNameFromPodAnnotations
(
pod
.
Annotations
,
ctrName
)
return
GetAppArmorOpts
(
profile
)
}
// Temporarily export this function to share with dockershim.
// TODO: clean this up.
func
GetAppArmorOpts
(
annotations
map
[
string
]
string
,
ctrName
string
)
([]
dockerOpt
,
error
)
{
profile
:=
apparmor
.
GetProfileNameFromPodAnnotations
(
annotations
,
ctrName
)
func
GetAppArmorOpts
(
profile
string
)
([]
dockerOpt
,
error
)
{
if
profile
==
""
||
profile
==
apparmor
.
ProfileRuntimeDefault
{
// The docker applies the default profile by default.
return
nil
,
nil
...
...
pkg/kubelet/kuberuntime/BUILD
View file @
ac76766a
...
...
@@ -45,6 +45,7 @@ go_library(
"//pkg/kubelet/types:go_default_library",
"//pkg/kubelet/util/cache:go_default_library",
"//pkg/kubelet/util/format:go_default_library",
"//pkg/security/apparmor:go_default_library",
"//pkg/securitycontext:go_default_library",
"//pkg/util/parsers:go_default_library",
"//pkg/util/selinux:go_default_library",
...
...
pkg/kubelet/kuberuntime/security_context.go
View file @
ac76766a
...
...
@@ -21,6 +21,7 @@ import (
"k8s.io/kubernetes/pkg/api/v1"
runtimeapi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/securitycontext"
)
...
...
@@ -32,6 +33,9 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po
synthesized
=
&
runtimeapi
.
LinuxContainerSecurityContext
{}
}
// set ApparmorProfile.
synthesized
.
ApparmorProfile
=
apparmor
.
GetProfileNameFromPodAnnotations
(
pod
.
Annotations
,
container
.
Name
)
// set RunAsUser.
if
synthesized
.
RunAsUser
==
nil
{
if
uid
!=
nil
{
...
...
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