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
262c34e7
Commit
262c34e7
authored
Apr 30, 2015
by
Victor Marmol
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7543 from yifan-gu/pod_manifest
kubelet/rkt: Add routines for converting kubelet pod to rkt pod.
parents
aa810e4e
7e8afc7c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
380 additions
and
4 deletions
+380
-4
cap.go
pkg/kubelet/rkt/cap.go
+128
-0
rkt.go
pkg/kubelet/rkt/rkt.go
+252
-4
No files found.
pkg/kubelet/rkt/cap.go
0 → 100644
View file @
262c34e7
/*
Copyright 2015 Google Inc. All rights reserved.
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
rkt
import
(
"fmt"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
// TODO(yifan): Export this to higher level package.
const
(
CAP_CHOWN
=
iota
CAP_DAC_OVERRIDE
CAP_DAC_READ_SEARCH
CAP_FOWNER
CAP_FSETID
CAP_KILL
CAP_SETGID
CAP_SETUID
CAP_SETPCAP
CAP_LINUX_IMMUTABLE
CAP_NET_BIND_SERVICE
CAP_NET_BROADCAST
CAP_NET_ADMIN
CAP_NET_RAW
CAP_IPC_LOCK
CAP_IPC_OWNER
CAP_SYS_MODULE
CAP_SYS_RAWIO
CAP_SYS_CHROOT
CAP_SYS_PTRACE
CAP_SYS_PACCT
CAP_SYS_ADMIN
CAP_SYS_BOOT
CAP_SYS_NICE
CAP_SYS_RESOURCE
CAP_SYS_TIME
CAP_SYS_TTY_CONFIG
CAP_MKNOD
CAP_LEASE
CAP_AUDIT_WRITE
CAP_AUDIT_CONTROL
CAP_SETFCAP
CAP_MAC_OVERRIDE
CAP_MAC_ADMIN
CAP_SYSLOG
CAP_WAKE_ALARM
CAP_BLOCK_SUSPEND
CAP_AUDIT_READ
)
// TODO(yifan): Export this to higher level package.
var
capabilityList
=
map
[
int
]
string
{
CAP_CHOWN
:
"CAP_CHOWN"
,
CAP_DAC_OVERRIDE
:
"CAP_DAC_OVERRIDE"
,
CAP_DAC_READ_SEARCH
:
"CAP_DAC_READ_SEARCH"
,
CAP_FOWNER
:
"CAP_FOWNER"
,
CAP_FSETID
:
"CAP_FSETID"
,
CAP_KILL
:
"CAP_KILL"
,
CAP_SETGID
:
"CAP_SETGID"
,
CAP_SETUID
:
"CAP_SETUID"
,
CAP_SETPCAP
:
"CAP_SETPCAP"
,
CAP_LINUX_IMMUTABLE
:
"CAP_LINUX_IMMUTABLE"
,
CAP_NET_BIND_SERVICE
:
"CAP_NET_BIND_SERVICE"
,
CAP_NET_BROADCAST
:
"CAP_NET_BROADCAST"
,
CAP_NET_ADMIN
:
"CAP_NET_ADMIN"
,
CAP_NET_RAW
:
"CAP_NET_RAW"
,
CAP_IPC_LOCK
:
"CAP_IPC_LOCK"
,
CAP_IPC_OWNER
:
"CAP_IPC_OWNER"
,
CAP_SYS_MODULE
:
"CAP_SYS_MODULE"
,
CAP_SYS_RAWIO
:
"CAP_SYS_RAWIO"
,
CAP_SYS_CHROOT
:
"CAP_SYS_CHROOT"
,
CAP_SYS_PTRACE
:
"CAP_SYS_PTRACE"
,
CAP_SYS_PACCT
:
"CAP_SYS_PACCT"
,
CAP_SYS_ADMIN
:
"CAP_SYS_ADMIN"
,
CAP_SYS_BOOT
:
"CAP_SYS_BOOT"
,
CAP_SYS_NICE
:
"CAP_SYS_NICE"
,
CAP_SYS_RESOURCE
:
"CAP_SYS_RESOURCE"
,
CAP_SYS_TIME
:
"CAP_SYS_TIME"
,
CAP_SYS_TTY_CONFIG
:
"CAP_SYS_TTY_CONFIG"
,
CAP_MKNOD
:
"CAP_MKNOD"
,
CAP_LEASE
:
"CAP_LEASE"
,
CAP_AUDIT_WRITE
:
"CAP_AUDIT_WRITE"
,
CAP_AUDIT_CONTROL
:
"CAP_AUDIT_CONTROL"
,
CAP_SETFCAP
:
"CAP_SETFCAP"
,
CAP_MAC_OVERRIDE
:
"CAP_MAC_OVERRIDE"
,
CAP_MAC_ADMIN
:
"CAP_MAC_ADMIN"
,
CAP_SYSLOG
:
"CAP_SYSLOG"
,
CAP_WAKE_ALARM
:
"CAP_WAKE_ALARM"
,
CAP_BLOCK_SUSPEND
:
"CAP_BLOCK_SUSPEND"
,
CAP_AUDIT_READ
:
"CAP_AUDIT_READ"
,
}
// getAllCapabilities returns the capability list with all capabilities.
func
getAllCapabilities
()
string
{
var
capabilities
[]
string
for
_
,
cap
:=
range
capabilityList
{
capabilities
=
append
(
capabilities
,
fmt
.
Sprintf
(
"%q"
,
cap
))
}
return
strings
.
Join
(
capabilities
,
","
)
}
// TODO(yifan): This assumes that api.CapabilityType has the form of
// "CAP_SYS_ADMIN". We need to have a formal definition for
// capabilities.
func
getCapabilities
(
caps
[]
api
.
CapabilityType
)
string
{
var
capList
[]
string
for
_
,
cap
:=
range
caps
{
capList
=
append
(
capList
,
fmt
.
Sprintf
(
"%q"
,
cap
))
}
return
strings
.
Join
(
capList
,
","
)
}
pkg/kubelet/rkt/rkt.go
View file @
262c34e7
...
...
@@ -17,13 +17,20 @@ limitations under the License.
package
rkt
import
(
"encoding/json"
"fmt"
"os/exec"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
appcschema
"github.com/appc/spec/schema"
appctypes
"github.com/appc/spec/schema/types"
"github.com/coreos/go-systemd/dbus"
"github.com/coreos/rkt/store"
"github.com/golang/glog"
)
...
...
@@ -77,15 +84,13 @@ func New(config *Config) (*Runtime, error) {
systemd
,
err
:=
dbus
.
New
()
if
err
!=
nil
{
glog
.
Errorf
(
"rkt: Cannot connect to dbus: %v"
,
err
)
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"cannot connect to dbus: %v"
,
err
)
}
// Test if rkt binary is in $PATH.
absPath
,
err
:=
exec
.
LookPath
(
rktBinName
)
if
err
!=
nil
{
glog
.
Errorf
(
"rkt: Cannot find rkt binary: %v"
,
err
)
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"cannot find rkt binary: %v"
,
err
)
}
rkt
:=
&
Runtime
{
...
...
@@ -134,3 +139,246 @@ func makePodServiceFileName(uid types.UID) string {
// TODO(yifan): Revisit this later, decide whether we want to use UID.
return
fmt
.
Sprintf
(
"%s_%s.service"
,
kubernetesUnitPrefix
,
uid
)
}
type
resource
struct
{
limit
string
request
string
}
// rawValue converts a string to *json.RawMessage
func
rawValue
(
value
string
)
*
json
.
RawMessage
{
msg
:=
json
.
RawMessage
(
value
)
return
&
msg
}
// setIsolators overrides the isolators of the pod manifest if necessary.
func
setIsolators
(
app
*
appctypes
.
App
,
c
*
api
.
Container
)
error
{
if
len
(
c
.
Capabilities
.
Add
)
>
0
||
len
(
c
.
Capabilities
.
Drop
)
>
0
||
len
(
c
.
Resources
.
Limits
)
>
0
||
len
(
c
.
Resources
.
Requests
)
>
0
{
app
.
Isolators
=
[]
appctypes
.
Isolator
{}
}
// Retained capabilities/privileged.
privileged
:=
false
if
capabilities
.
Get
()
.
AllowPrivileged
{
privileged
=
c
.
Privileged
}
else
if
c
.
Privileged
{
return
fmt
.
Errorf
(
"privileged is disallowed globally"
)
}
var
addCaps
string
if
privileged
{
addCaps
=
getAllCapabilities
()
}
else
{
addCaps
=
getCapabilities
(
c
.
Capabilities
.
Add
)
}
if
len
(
addCaps
)
>
0
{
// TODO(yifan): Replace with constructor, see:
// https://github.com/appc/spec/issues/268
isolator
:=
appctypes
.
Isolator
{
Name
:
"os/linux/capabilities-retain-set"
,
ValueRaw
:
rawValue
(
fmt
.
Sprintf
(
`{"set":[%s]}`
,
addCaps
)),
}
app
.
Isolators
=
append
(
app
.
Isolators
,
isolator
)
}
// Removed capabilities.
dropCaps
:=
getCapabilities
(
c
.
Capabilities
.
Drop
)
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
)
for
name
,
quantity
:=
range
c
.
Resources
.
Limits
{
resources
[
name
]
=
resource
{
limit
:
quantity
.
String
()}
}
for
name
,
quantity
:=
range
c
.
Resources
.
Requests
{
r
,
ok
:=
resources
[
name
]
if
!
ok
{
r
=
resource
{}
}
r
.
request
=
quantity
.
String
()
resources
[
name
]
=
r
}
var
acName
appctypes
.
ACName
for
name
,
res
:=
range
resources
{
switch
name
{
case
api
.
ResourceCPU
:
acName
=
"resource/cpu"
case
api
.
ResourceMemory
:
acName
=
"resource/memory"
default
:
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
:
rawValue
(
fmt
.
Sprintf
(
`{"request":%q,"limit":%q}`
,
res
.
request
,
res
.
limit
)),
}
app
.
Isolators
=
append
(
app
.
Isolators
,
isolator
)
}
return
nil
}
// setApp overrides the app's fields if any of them are specified in the
// container's spec.
func
setApp
(
app
*
appctypes
.
App
,
c
*
api
.
Container
)
error
{
// Override the exec.
// TOOD(yifan): Revisit this for the overriding rule.
if
len
(
c
.
Command
)
>
0
||
len
(
c
.
Args
)
>
0
{
app
.
Exec
=
append
(
c
.
Command
,
c
.
Args
...
)
}
// TODO(yifan): Use non-root user in the future, see:
// https://github.com/coreos/rkt/issues/820
app
.
User
,
app
.
Group
=
"0"
,
"0"
// Override the working directory.
if
len
(
c
.
WorkingDir
)
>
0
{
app
.
WorkingDirectory
=
c
.
WorkingDir
}
// Override the environment.
// TODO(yifan): Use RunContainerOptions.
if
len
(
c
.
Env
)
>
0
{
app
.
Environment
=
[]
appctypes
.
EnvironmentVariable
{}
}
for
_
,
env
:=
range
c
.
Env
{
app
.
Environment
=
append
(
app
.
Environment
,
appctypes
.
EnvironmentVariable
{
Name
:
env
.
Name
,
Value
:
env
.
Value
,
})
}
// Override the mount points.
if
len
(
c
.
VolumeMounts
)
>
0
{
app
.
MountPoints
=
[]
appctypes
.
MountPoint
{}
}
for
_
,
m
:=
range
c
.
VolumeMounts
{
mountPointName
,
err
:=
appctypes
.
NewACName
(
m
.
Name
)
if
err
!=
nil
{
return
err
}
app
.
MountPoints
=
append
(
app
.
MountPoints
,
appctypes
.
MountPoint
{
Name
:
*
mountPointName
,
Path
:
m
.
MountPath
,
ReadOnly
:
m
.
ReadOnly
,
})
}
// Override the ports.
if
len
(
c
.
Ports
)
>
0
{
app
.
Ports
=
[]
appctypes
.
Port
{}
}
for
_
,
p
:=
range
c
.
Ports
{
portName
,
err
:=
appctypes
.
NewACName
(
p
.
Name
)
if
err
!=
nil
{
return
err
}
app
.
Ports
=
append
(
app
.
Ports
,
appctypes
.
Port
{
Name
:
*
portName
,
Protocol
:
string
(
p
.
Protocol
),
Port
:
uint
(
p
.
ContainerPort
),
})
}
// Override isolators.
return
setIsolators
(
app
,
c
)
}
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
// TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions().
func
(
r
*
Runtime
)
makePodManifest
(
pod
*
api
.
Pod
,
volumeMap
map
[
string
]
volume
.
Volume
)
(
*
appcschema
.
PodManifest
,
error
)
{
manifest
:=
appcschema
.
BlankPodManifest
()
// Get the image manifests, assume they are already in the cas,
// and extract the app field from the image and to be the 'base app'.
//
// We do this is because we will fully replace the image manifest's app
// with the pod manifest's app in rkt runtime. See below:
//
// https://github.com/coreos/rkt/issues/723.
//
s
,
err
:=
store
.
NewStore
(
rktDataDir
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot open store: %v"
,
err
)
}
for
_
,
c
:=
range
pod
.
Spec
.
Containers
{
// Assume we are running docker images for now, see #7203.
imageID
,
err
:=
r
.
getImageID
(
c
.
Image
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot get image ID for %q: %v"
,
c
.
Image
,
err
)
}
hash
,
err
:=
appctypes
.
NewHash
(
imageID
)
if
err
!=
nil
{
return
nil
,
err
}
im
,
err
:=
s
.
GetImageManifest
(
hash
.
String
())
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot get image manifest: %v"
,
err
)
}
// Override the image manifest's app and store it in the pod manifest.
app
:=
im
.
App
if
err
:=
setApp
(
app
,
&
c
);
err
!=
nil
{
return
nil
,
err
}
manifest
.
Apps
=
append
(
manifest
.
Apps
,
appcschema
.
RuntimeApp
{
Name
:
im
.
Name
,
Image
:
appcschema
.
RuntimeImage
{
ID
:
*
hash
},
App
:
app
,
})
}
// Set global volumes.
for
name
,
volume
:=
range
volumeMap
{
volName
,
err
:=
appctypes
.
NewACName
(
name
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot use the volume's name %q as ACName: %v"
,
name
,
err
)
}
manifest
.
Volumes
=
append
(
manifest
.
Volumes
,
appctypes
.
Volume
{
Name
:
*
volName
,
Kind
:
"host"
,
Source
:
volume
.
GetPath
(),
})
}
// Set global ports.
for
_
,
c
:=
range
pod
.
Spec
.
Containers
{
for
_
,
port
:=
range
c
.
Ports
{
portName
,
err
:=
appctypes
.
NewACName
(
port
.
Name
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"cannot use the port's name %q as ACName: %v"
,
port
.
Name
,
err
)
}
manifest
.
Ports
=
append
(
manifest
.
Ports
,
appctypes
.
ExposedPort
{
Name
:
*
portName
,
HostPort
:
uint
(
port
.
HostPort
),
})
}
}
// TODO(yifan): Set pod-level isolators once it's supported in kubernetes.
return
manifest
,
nil
}
// TODO(yifan): Replace with 'rkt images'.
func
(
r
*
Runtime
)
getImageID
(
imageName
string
)
(
string
,
error
)
{
output
,
err
:=
r
.
runCommand
(
"fetch"
,
imageName
)
if
err
!=
nil
{
return
""
,
err
}
if
len
(
output
)
==
0
{
return
""
,
fmt
.
Errorf
(
"no result from rkt fetch"
)
}
last
:=
output
[
len
(
output
)
-
1
]
if
!
strings
.
HasPrefix
(
last
,
"sha512-"
)
{
return
""
,
fmt
.
Errorf
(
"unexpected result: %q"
,
last
)
}
return
last
,
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