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
cc656ae6
Commit
cc656ae6
authored
Jan 08, 2016
by
Yifan Gu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rkt: Refactor setIsolators.
Replace manually creating isolators with isolator constructors. Also add support for supplementary group IDs.
parent
9ac13f66
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
115 additions
and
108 deletions
+115
-108
cap.go
pkg/kubelet/rkt/cap.go
+4
-22
rkt.go
pkg/kubelet/rkt/rkt.go
+108
-83
provider.go
pkg/securitycontext/provider.go
+3
-3
No files found.
pkg/kubelet/rkt/cap.go
View file @
cc656ae6
...
@@ -16,13 +16,6 @@ limitations under the License.
...
@@ -16,13 +16,6 @@ limitations under the License.
package
rkt
package
rkt
import
(
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
)
// TODO(yifan): Export this to higher level package.
// TODO(yifan): Export this to higher level package.
const
(
const
(
CAP_CHOWN
=
iota
CAP_CHOWN
=
iota
...
@@ -107,22 +100,11 @@ var capabilityList = map[int]string{
...
@@ -107,22 +100,11 @@ var capabilityList = map[int]string{
CAP_AUDIT_READ
:
"CAP_AUDIT_READ"
,
CAP_AUDIT_READ
:
"CAP_AUDIT_READ"
,
}
}
//
getA
llCapabilities returns the capability list with all capabilities.
//
a
llCapabilities returns the capability list with all capabilities.
func
getAllCapabilities
()
string
{
func
allCapabilities
()
[]
string
{
var
capabilities
[]
string
var
capabilities
[]
string
for
_
,
cap
:=
range
capabilityList
{
for
_
,
cap
:=
range
capabilityList
{
capabilities
=
append
(
capabilities
,
fmt
.
Sprintf
(
"%q"
,
cap
))
capabilities
=
append
(
capabilities
,
cap
)
}
return
strings
.
Join
(
capabilities
,
","
)
}
// TODO(yifan): This assumes that api.Capability has the form of
// "CAP_SYS_ADMIN". We need to have a formal definition for
// capabilities.
func
getCapabilities
(
caps
[]
api
.
Capability
)
string
{
var
capList
[]
string
for
_
,
cap
:=
range
caps
{
capList
=
append
(
capList
,
fmt
.
Sprintf
(
"%q"
,
cap
))
}
}
return
strings
.
Join
(
capList
,
","
)
return
capabilities
}
}
pkg/kubelet/rkt/rkt.go
View file @
cc656ae6
...
@@ -225,76 +225,42 @@ func makePodServiceFileName(uid types.UID) string {
...
@@ -225,76 +225,42 @@ func makePodServiceFileName(uid types.UID) string {
return
fmt
.
Sprintf
(
"%s_%s.service"
,
kubernetesUnitPrefix
,
uid
)
return
fmt
.
Sprintf
(
"%s_%s.service"
,
kubernetesUnitPrefix
,
uid
)
}
}
type
resource
struct
{
// setIsolators sets the apps' isolators according to the security context and resource spec.
limit
string
func
setIsolators
(
app
*
appctypes
.
App
,
c
*
api
.
Container
,
ctx
*
api
.
SecurityContext
)
error
{
request
string
var
isolators
[]
appctypes
.
Isolator
}
// rawValue converts a string to *json.RawMessage
func
rawValue
(
value
string
)
*
json
.
RawMessage
{
msg
:=
json
.
RawMessage
(
value
)
return
&
msg
}
// rawValue converts the request, limit to *json.RawMessage
func
rawRequestLimit
(
request
,
limit
string
)
*
json
.
RawMessage
{
if
request
==
""
{
request
=
limit
}
if
limit
==
""
{
limit
=
request
}
return
rawValue
(
fmt
.
Sprintf
(
`{"request":%q,"limit":%q}`
,
request
,
limit
))
}
// setIsolators overrides the isolators of the pod manifest if necessary.
// Capabilities isolators.
// TODO need an apply config in security context for rkt
if
ctx
!=
nil
{
func
setIsolators
(
app
*
appctypes
.
App
,
c
*
api
.
Container
)
error
{
var
addCaps
,
dropCaps
[]
string
hasCapRequests
:=
securitycontext
.
HasCapabilitiesRequest
(
c
)
if
hasCapRequests
||
len
(
c
.
Resources
.
Limits
)
>
0
||
len
(
c
.
Resources
.
Requests
)
>
0
{
app
.
Isolators
=
[]
appctypes
.
Isolator
{}
}
// Retained capabilities/privileged.
privileged
:=
false
if
c
.
SecurityContext
!=
nil
&&
c
.
SecurityContext
.
Privileged
!=
nil
{
privileged
=
*
c
.
SecurityContext
.
Privileged
}
var
addCaps
string
if
ctx
.
Capabilities
!=
nil
{
if
privileged
{
addCaps
,
dropCaps
=
securitycontext
.
MakeCapabilities
(
ctx
.
Capabilities
.
Add
,
ctx
.
Capabilities
.
Drop
)
addCaps
=
getAllCapabilities
()
}
else
{
if
hasCapRequests
{
addCaps
=
getCapabilities
(
c
.
SecurityContext
.
Capabilities
.
Add
)
}
}
}
if
ctx
.
Privileged
!=
nil
&&
*
ctx
.
Privileged
{
if
len
(
addCaps
)
>
0
{
addCaps
,
dropCaps
=
allCapabilities
(),
[]
string
{}
// TODO(yifan): Replace with constructor, see:
}
// https://github.com/appc/spec/issues/268
if
len
(
addCaps
)
>
0
{
isolator
:=
appctypes
.
Isolator
{
set
,
err
:=
appctypes
.
NewLinuxCapabilitiesRetainSet
(
addCaps
...
)
Name
:
"os/linux/capabilities-retain-set"
,
if
err
!=
nil
{
ValueRaw
:
rawValue
(
fmt
.
Sprintf
(
`{"set":[%s]}`
,
addCaps
)),
return
err
}
isolators
=
append
(
isolators
,
set
.
AsIsolator
())
}
if
len
(
dropCaps
)
>
0
{
set
,
err
:=
appctypes
.
NewLinuxCapabilitiesRevokeSet
(
dropCaps
...
)
if
err
!=
nil
{
return
err
}
isolators
=
append
(
isolators
,
set
.
AsIsolator
())
}
}
app
.
Isolators
=
append
(
app
.
Isolators
,
isolator
)
}
}
// Removed capabilities.
// Resources isolators.
var
dropCaps
string
type
resource
struct
{
if
hasCapRequests
{
limit
string
dropCaps
=
getCapabilities
(
c
.
SecurityContext
.
Capabilities
.
Drop
)
request
string
}
if
len
(
dropCaps
)
>
0
{
// TODO(yifan): Replace with constructor, see:
// https://github.com/appc/spec/issues/268
isolator
:=
appctypes
.
Isolator
{
Name
:
"os/linux/capabilities-remove-set"
,
ValueRaw
:
rawValue
(
fmt
.
Sprintf
(
`{"set":[%s]}`
,
dropCaps
)),
}
app
.
Isolators
=
append
(
app
.
Isolators
,
isolator
)
}
}
// Resources.
resources
:=
make
(
map
[
api
.
ResourceName
]
resource
)
resources
:=
make
(
map
[
api
.
ResourceName
]
resource
)
for
name
,
quantity
:=
range
c
.
Resources
.
Limits
{
for
name
,
quantity
:=
range
c
.
Resources
.
Limits
{
resources
[
name
]
=
resource
{
limit
:
quantity
.
String
()}
resources
[
name
]
=
resource
{
limit
:
quantity
.
String
()}
...
@@ -307,27 +273,59 @@ func setIsolators(app *appctypes.App, c *api.Container) error {
...
@@ -307,27 +273,59 @@ func setIsolators(app *appctypes.App, c *api.Container) error {
r
.
request
=
quantity
.
String
()
r
.
request
=
quantity
.
String
()
resources
[
name
]
=
r
resources
[
name
]
=
r
}
}
var
acName
appctypes
.
ACIdentifier
for
name
,
res
:=
range
resources
{
for
name
,
res
:=
range
resources
{
switch
name
{
switch
name
{
case
api
.
ResourceCPU
:
case
api
.
ResourceCPU
:
acName
=
"resource/cpu"
cpu
,
err
:=
appctypes
.
NewResourceCPUIsolator
(
res
.
request
,
res
.
limit
)
if
err
!=
nil
{
return
err
}
isolators
=
append
(
isolators
,
cpu
.
AsIsolator
())
case
api
.
ResourceMemory
:
case
api
.
ResourceMemory
:
acName
=
"resource/memory"
memory
,
err
:=
appctypes
.
NewResourceMemoryIsolator
(
res
.
request
,
res
.
limit
)
if
err
!=
nil
{
return
err
}
isolators
=
append
(
isolators
,
memory
.
AsIsolator
())
default
:
default
:
return
fmt
.
Errorf
(
"resource type not supported: %v"
,
name
)
return
fmt
.
Errorf
(
"resource type not supported: %v"
,
name
)
}
}
// TODO(yifan): Replace with constructor, see:
// https://github.com/appc/spec/issues/268
isolator
:=
appctypes
.
Isolator
{
Name
:
acName
,
ValueRaw
:
rawRequestLimit
(
res
.
request
,
res
.
limit
),
}
app
.
Isolators
=
append
(
app
.
Isolators
,
isolator
)
}
}
mergeIsolators
(
app
,
isolators
)
return
nil
return
nil
}
}
// mergeIsolators replaces the app.Isolators with isolators.
func
mergeIsolators
(
app
*
appctypes
.
App
,
isolators
[]
appctypes
.
Isolator
)
{
for
_
,
is
:=
range
isolators
{
found
:=
false
for
j
,
js
:=
range
app
.
Isolators
{
if
is
.
Name
.
Equals
(
js
.
Name
)
{
switch
is
.
Name
{
case
appctypes
.
LinuxCapabilitiesRetainSetName
:
// TODO(yifan): More fine grain merge for capability set instead of override.
fallthrough
case
appctypes
.
LinuxCapabilitiesRevokeSetName
:
fallthrough
case
appctypes
.
ResourceCPUName
:
fallthrough
case
appctypes
.
ResourceMemoryName
:
app
.
Isolators
[
j
]
=
is
default
:
panic
(
fmt
.
Sprintf
(
"unexpected isolator name: %v"
,
is
.
Name
))
}
found
=
true
break
}
}
if
!
found
{
app
.
Isolators
=
append
(
app
.
Isolators
,
is
)
}
}
}
// mergeEnv merges the optEnv with the image's environments.
// mergeEnv merges the optEnv with the image's environments.
// The environments defined in the image will be overridden by
// The environments defined in the image will be overridden by
// the ones with the same name in optEnv.
// the ones with the same name in optEnv.
...
@@ -392,11 +390,33 @@ func mergePortMappings(app *appctypes.App, optPortMappings []kubecontainer.PortM
...
@@ -392,11 +390,33 @@ func mergePortMappings(app *appctypes.App, optPortMappings []kubecontainer.PortM
}
}
}
}
// setApp overrides the app's fields if any of them are specified in the
func
verifyNonRoot
(
app
*
appctypes
.
App
,
ctx
*
api
.
SecurityContext
)
error
{
// container's spec.
if
ctx
!=
nil
&&
ctx
.
RunAsNonRoot
!=
nil
&&
*
ctx
.
RunAsNonRoot
{
func
setApp
(
app
*
appctypes
.
App
,
c
*
api
.
Container
,
opts
*
kubecontainer
.
RunContainerOptions
)
error
{
if
ctx
.
RunAsUser
!=
nil
&&
*
ctx
.
RunAsUser
==
0
{
// Override the exec.
return
fmt
.
Errorf
(
"container's runAsUser breaks non-root policy"
)
}
if
ctx
.
RunAsUser
==
nil
&&
app
.
User
==
"0"
{
return
fmt
.
Errorf
(
"container has no runAsUser and image will run as root"
)
}
}
return
nil
}
func
setSupplementaryGIDs
(
app
*
appctypes
.
App
,
podCtx
*
api
.
PodSecurityContext
)
{
if
podCtx
!=
nil
{
app
.
SupplementaryGIDs
=
app
.
SupplementaryGIDs
[
:
0
]
for
_
,
v
:=
range
podCtx
.
SupplementalGroups
{
app
.
SupplementaryGIDs
=
append
(
app
.
SupplementaryGIDs
,
int
(
v
))
}
if
podCtx
.
FSGroup
!=
nil
{
app
.
SupplementaryGIDs
=
append
(
app
.
SupplementaryGIDs
,
int
(
*
podCtx
.
FSGroup
))
}
}
}
// setApp merges the container spec with the image's manifest.
func
setApp
(
app
*
appctypes
.
App
,
c
*
api
.
Container
,
opts
*
kubecontainer
.
RunContainerOptions
,
ctx
*
api
.
SecurityContext
,
podCtx
*
api
.
PodSecurityContext
)
error
{
// Override the exec.
if
len
(
c
.
Command
)
>
0
{
if
len
(
c
.
Command
)
>
0
{
app
.
Exec
=
c
.
Command
app
.
Exec
=
c
.
Command
}
}
...
@@ -404,11 +424,16 @@ func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContain
...
@@ -404,11 +424,16 @@ func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContain
app
.
Exec
=
append
(
app
.
Exec
,
c
.
Args
...
)
app
.
Exec
=
append
(
app
.
Exec
,
c
.
Args
...
)
}
}
// TODO(yifan): Use non-root user in the future, see:
// Set UID and GIDs.
// https://github.com/coreos/rkt/issues/820
if
err
:=
verifyNonRoot
(
app
,
ctx
);
err
!=
nil
{
app
.
User
,
app
.
Group
=
"0"
,
"0"
return
err
}
if
ctx
!=
nil
&&
ctx
.
RunAsUser
!=
nil
{
app
.
User
=
strconv
.
Itoa
(
int
(
*
ctx
.
RunAsUser
))
}
setSupplementaryGIDs
(
app
,
podCtx
)
//
Override the
working directory.
//
Set
working directory.
if
len
(
c
.
WorkingDir
)
>
0
{
if
len
(
c
.
WorkingDir
)
>
0
{
app
.
WorkingDirectory
=
c
.
WorkingDir
app
.
WorkingDirectory
=
c
.
WorkingDir
}
}
...
@@ -419,8 +444,7 @@ func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContain
...
@@ -419,8 +444,7 @@ func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContain
mergeEnv
(
app
,
opts
.
Envs
)
mergeEnv
(
app
,
opts
.
Envs
)
mergePortMappings
(
app
,
opts
.
PortMappings
)
mergePortMappings
(
app
,
opts
.
PortMappings
)
// Override isolators.
return
setIsolators
(
app
,
c
,
ctx
)
return
setIsolators
(
app
,
c
)
}
}
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
...
@@ -525,7 +549,8 @@ func (r *Runtime) newAppcRuntimeApp(pod *api.Pod, c api.Container, pullSecrets [
...
@@ -525,7 +549,8 @@ func (r *Runtime) newAppcRuntimeApp(pod *api.Pod, c api.Container, pullSecrets [
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
if
err
:=
setApp
(
imgManifest
.
App
,
&
c
,
opts
);
err
!=
nil
{
ctx
:=
securitycontext
.
DetermineEffectiveSecurityContext
(
pod
,
&
c
)
if
err
:=
setApp
(
imgManifest
.
App
,
&
c
,
opts
,
ctx
,
pod
.
Spec
.
SecurityContext
);
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
...
...
pkg/securitycontext/provider.go
View file @
cc656ae6
...
@@ -83,7 +83,7 @@ func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container
...
@@ -83,7 +83,7 @@ func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container
}
}
if
effectiveSC
.
Capabilities
!=
nil
{
if
effectiveSC
.
Capabilities
!=
nil
{
add
,
drop
:=
makeCapabilit
es
(
effectiveSC
.
Capabilities
.
Add
,
effectiveSC
.
Capabilities
.
Drop
)
add
,
drop
:=
MakeCapabiliti
es
(
effectiveSC
.
Capabilities
.
Add
,
effectiveSC
.
Capabilities
.
Drop
)
hostConfig
.
CapAdd
=
add
hostConfig
.
CapAdd
=
add
hostConfig
.
CapDrop
=
drop
hostConfig
.
CapDrop
=
drop
}
}
...
@@ -105,8 +105,8 @@ func modifySecurityOption(config []string, name, value string) []string {
...
@@ -105,8 +105,8 @@ func modifySecurityOption(config []string, name, value string) []string {
return
config
return
config
}
}
//
makeCapabilit
es creates string slices from Capability slices
//
MakeCapabiliti
es creates string slices from Capability slices
func
makeCapabilit
es
(
capAdd
[]
api
.
Capability
,
capDrop
[]
api
.
Capability
)
([]
string
,
[]
string
)
{
func
MakeCapabiliti
es
(
capAdd
[]
api
.
Capability
,
capDrop
[]
api
.
Capability
)
([]
string
,
[]
string
)
{
var
(
var
(
addCaps
[]
string
addCaps
[]
string
dropCaps
[]
string
dropCaps
[]
string
...
...
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