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
0fbe6a82
Commit
0fbe6a82
authored
Aug 02, 2016
by
Kubernetes Submit Queue
Committed by
GitHub
Aug 02, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #29700 from yujuhong/dshim3
Automatic merge from submit-queue dockershim: Implement PodSandboxMethods Only the last three commits are new.
parents
a3f77970
5960d87d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
434 additions
and
26 deletions
+434
-26
convert.go
pkg/kubelet/dockershim/convert.go
+23
-0
docker_container.go
pkg/kubelet/dockershim/docker_container.go
+12
-16
docker_sandbox.go
pkg/kubelet/dockershim/docker_sandbox.go
+216
-6
docker_sandbox_test.go
pkg/kubelet/dockershim/docker_sandbox_test.go
+58
-0
docker_service.go
pkg/kubelet/dockershim/docker_service.go
+10
-0
docker_service_test.go
pkg/kubelet/dockershim/docker_service_test.go
+3
-4
helpers.go
pkg/kubelet/dockershim/helpers.go
+99
-0
fake_docker_client.go
pkg/kubelet/dockertools/fake_docker_client.go
+13
-0
No files found.
pkg/kubelet/dockershim/convert.go
View file @
0fbe6a82
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"strings"
"strings"
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"
)
)
...
@@ -89,3 +90,25 @@ func toRuntimeAPIContainerState(state string) runtimeApi.ContainerState {
...
@@ -89,3 +90,25 @@ func toRuntimeAPIContainerState(state string) runtimeApi.ContainerState {
return
runtimeApi
.
ContainerState_UNKNOWN
return
runtimeApi
.
ContainerState_UNKNOWN
}
}
}
}
func
toRuntimeAPISandboxState
(
state
string
)
runtimeApi
.
PodSandBoxState
{
// Parse the state string in dockertypes.Container. This could break when
// we upgrade docker.
switch
{
case
strings
.
HasPrefix
(
state
,
statusRunningPrefix
)
:
return
runtimeApi
.
PodSandBoxState_READY
default
:
return
runtimeApi
.
PodSandBoxState_NOTREADY
}
}
func
toRuntimeAPISandbox
(
c
*
dockertypes
.
Container
)
*
runtimeApi
.
PodSandbox
{
state
:=
toRuntimeAPISandboxState
(
c
.
Status
)
return
&
runtimeApi
.
PodSandbox
{
Id
:
&
c
.
ID
,
Name
:
&
c
.
Names
[
0
],
State
:
&
state
,
CreatedAt
:
&
c
.
Created
,
// TODO: Why do we need CreateAt timestamp for sandboxes?
Labels
:
c
.
Labels
,
// TODO: Need to disthinguish annotaions and labels.
}
}
pkg/kubelet/dockershim/docker_container.go
View file @
0fbe6a82
...
@@ -35,15 +35,17 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
...
@@ -35,15 +35,17 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
opts
:=
dockertypes
.
ContainerListOptions
{
All
:
true
}
opts
:=
dockertypes
.
ContainerListOptions
{
All
:
true
}
opts
.
Filter
=
dockerfilters
.
NewArgs
()
opts
.
Filter
=
dockerfilters
.
NewArgs
()
f
:=
newDockerFilter
(
&
opts
.
Filter
)
if
filter
!=
nil
{
if
filter
!=
nil
{
if
filter
.
Name
!=
nil
{
if
filter
.
Name
!=
nil
{
opts
.
Filter
.
Add
(
"name"
,
filter
.
GetName
())
f
.
Add
(
"name"
,
filter
.
GetName
())
}
}
if
filter
.
Id
!=
nil
{
if
filter
.
Id
!=
nil
{
opts
.
Filter
.
Add
(
"id"
,
filter
.
GetId
())
f
.
Add
(
"id"
,
filter
.
GetId
())
}
}
if
filter
.
State
!=
nil
{
if
filter
.
State
!=
nil
{
opts
.
Filter
.
Add
(
"status"
,
toDockerContainerStatus
(
filter
.
GetState
()))
f
.
Add
(
"status"
,
toDockerContainerStatus
(
filter
.
GetState
()))
}
}
if
filter
.
PodSandboxId
!=
nil
{
if
filter
.
PodSandboxId
!=
nil
{
// TODO: implement this after sandbox functions are implemented.
// TODO: implement this after sandbox functions are implemented.
...
@@ -51,9 +53,11 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
...
@@ -51,9 +53,11 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
if
filter
.
LabelSelector
!=
nil
{
if
filter
.
LabelSelector
!=
nil
{
for
k
,
v
:=
range
filter
.
LabelSelector
{
for
k
,
v
:=
range
filter
.
LabelSelector
{
opts
.
Filter
.
Add
(
"label"
,
fmt
.
Sprintf
(
"%s=%s"
,
k
,
v
)
)
f
.
AddLabel
(
k
,
v
)
}
}
}
}
// Filter out sandbox containers.
f
.
AddLabel
(
containerTypeLabelKey
,
containerTypeLabelContainer
)
}
}
containers
,
err
:=
ds
.
client
.
ListContainers
(
opts
)
containers
,
err
:=
ds
.
client
.
ListContainers
(
opts
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -81,14 +85,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
...
@@ -81,14 +85,9 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
// Merge annotations and labels because docker supports only labels.
// Merge annotations and labels because docker supports only labels.
// TODO: add a prefix to annotations so that we can distinguish labels and
// TODO: add a prefix to annotations so that we can distinguish labels and
// annotations when reading back them from the docker container.
// annotations when reading back them from the docker container.
// TODO: should we apply docker-specific labels?
labels
:=
makeLabels
(
config
.
GetLabels
(),
config
.
GetAnnotations
())
labels
:=
config
.
GetLabels
()
// Apply a the container type label.
for
k
,
v
:=
range
config
.
GetAnnotations
()
{
labels
[
containerTypeLabelKey
]
=
containerTypeLabelContainer
if
_
,
ok
:=
labels
[
k
];
!
ok
{
// Only write to labels if the key doesn't exist.
labels
[
k
]
=
v
}
}
image
:=
""
image
:=
""
if
iSpec
:=
config
.
GetImage
();
iSpec
!=
nil
{
if
iSpec
:=
config
.
GetImage
();
iSpec
!=
nil
{
...
@@ -163,10 +162,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
...
@@ -163,10 +162,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
// Note: ShmSize is handled in kube_docker_client.go
// Note: ShmSize is handled in kube_docker_client.go
}
}
// TODO: Seccomp support. Need to figure out how to pass seccomp options
hc
.
SecurityOpt
=
[]
string
{
getSeccompOpts
()}
// through the runtime API (annotations?).See dockerManager.getSecurityOpts()
// for the details. Always set the default seccomp profile for now.
hc
.
SecurityOpt
=
[]
string
{
fmt
.
Sprintf
(
"%s=%s"
,
"seccomp"
,
defaultSeccompProfile
)}
// TODO: Add or drop capabilities.
// TODO: Add or drop capabilities.
createConfig
.
HostConfig
=
hc
createConfig
.
HostConfig
=
hc
...
...
pkg/kubelet/dockershim/docker_sandbox.go
View file @
0fbe6a82
...
@@ -19,33 +19,243 @@ package dockershim
...
@@ -19,33 +19,243 @@ package dockershim
import
(
import
(
"fmt"
"fmt"
dockertypes
"github.com/docker/engine-api/types"
dockercontainer
"github.com/docker/engine-api/types/container"
dockerfilters
"github.com/docker/engine-api/types/filters"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
)
const
(
defaultSandboxImage
=
"gcr.io/google_containers/pause-amd64:3.0"
// Various default sandbox resources requests/limits.
defaultSandboxCPUshares
int64
=
2
defaultSandboxOOMScore
int
=
-
999
// Termination grace period
defaultSandboxGracePeriod
int
=
10
)
// CreatePodSandbox creates a pod-level sandbox.
// CreatePodSandbox creates a pod-level sandbox.
// The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899
// The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899
// For docker, PodSandbox is implemented by a container holding the network
// namespace for the pod.
// Note: docker doesn't use LogDirectory (yet).
func
(
ds
*
dockerService
)
CreatePodSandbox
(
config
*
runtimeApi
.
PodSandboxConfig
)
(
string
,
error
)
{
func
(
ds
*
dockerService
)
CreatePodSandbox
(
config
*
runtimeApi
.
PodSandboxConfig
)
(
string
,
error
)
{
return
""
,
fmt
.
Errorf
(
"Not implemented"
)
// Step 1: Pull the image for the sandbox.
// TODO: How should we handle pulling custom pod infra container image
// (with credentials)?
image
:=
defaultSandboxImage
if
err
:=
ds
.
client
.
PullImage
(
image
,
dockertypes
.
AuthConfig
{},
dockertypes
.
ImagePullOptions
{});
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"unable to pull image for the sandbox container: %v"
,
err
)
}
// Step 2: Create the sandbox container.
createConfig
:=
makeSandboxDockerConfig
(
config
,
image
)
createResp
,
err
:=
ds
.
client
.
CreateContainer
(
*
createConfig
)
if
err
!=
nil
||
createResp
==
nil
{
return
""
,
fmt
.
Errorf
(
"failed to create a sandbox for pod %q: %v"
,
config
.
GetName
(),
err
)
}
// Step 3: Start the sandbox container.
// Assume kubelet's garbage collector would remove the sandbox later, if
// startContainer failed.
err
=
ds
.
StartContainer
(
createResp
.
ID
)
return
createResp
.
ID
,
err
}
}
// StopPodSandbox stops the sandbox. If there are any running containers in the
// StopPodSandbox stops the sandbox. If there are any running containers in the
// sandbox, they should be force terminated.
// sandbox, they should be force terminated.
func
(
ds
*
dockerService
)
StopPodSandbox
(
podSandboxID
string
)
error
{
func
(
ds
*
dockerService
)
StopPodSandbox
(
podSandboxID
string
)
error
{
return
fmt
.
Errorf
(
"Not implemented"
)
return
ds
.
client
.
StopContainer
(
podSandboxID
,
defaultSandboxGracePeriod
)
// TODO: Stop all running containers in the sandbox.
}
}
// DeletePodSandbox deletes the sandbox. If there are running containers in the
// DeletePodSandbox deletes the sandbox. If there are running containers in the
// sandbox, they should be forcibly deleted.
// sandbox, they should be forcibly deleted.
func
(
ds
*
dockerService
)
DeletePodSandbox
(
podSandboxID
string
)
error
{
func
(
ds
*
dockerService
)
DeletePodSandbox
(
podSandboxID
string
)
error
{
return
fmt
.
Errorf
(
"Not implemented"
)
return
ds
.
client
.
RemoveContainer
(
podSandboxID
,
dockertypes
.
ContainerRemoveOptions
{
RemoveVolumes
:
true
})
// TODO: remove all containers in the sandbox.
}
}
// PodSandboxStatus returns the
S
tatus of the PodSandbox.
// PodSandboxStatus returns the
s
tatus of the PodSandbox.
func
(
ds
*
dockerService
)
PodSandboxStatus
(
podSandboxID
string
)
(
*
runtimeApi
.
PodSandboxStatus
,
error
)
{
func
(
ds
*
dockerService
)
PodSandboxStatus
(
podSandboxID
string
)
(
*
runtimeApi
.
PodSandboxStatus
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"Not implemented"
)
// Inspect the container.
r
,
err
:=
ds
.
client
.
InspectContainer
(
podSandboxID
)
if
err
!=
nil
{
return
nil
,
err
}
// Parse the timstamps.
createdAt
,
_
,
_
,
err
:=
getContainerTimestamps
(
r
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to parse timestamp for container %q: %v"
,
podSandboxID
,
err
)
}
ct
:=
createdAt
.
Unix
()
// Translate container to sandbox state.
state
:=
runtimeApi
.
PodSandBoxState_NOTREADY
if
r
.
State
.
Running
{
state
=
runtimeApi
.
PodSandBoxState_READY
}
// TODO: We can't really get the IP address from the network plugin, which
// is handled by kubelet as of now. Should we amend the interface? How is
// this handled in the new remote runtime integration?
// See DockerManager.determineContainerIP() for more details.
// For now, just assume that there is no network plugin.
// Related issue: https://github.com/kubernetes/kubernetes/issues/28667
var
IP
string
if
r
.
NetworkSettings
!=
nil
{
IP
=
r
.
NetworkSettings
.
IPAddress
// Fall back to IPv6 address if no IPv4 address is present
if
IP
==
""
{
IP
=
r
.
NetworkSettings
.
GlobalIPv6Address
}
}
network
:=
&
runtimeApi
.
PodSandboxNetworkStatus
{
Ip
:
&
IP
}
netNS
:=
getNetworkNamespace
(
r
)
return
&
runtimeApi
.
PodSandboxStatus
{
Id
:
&
r
.
ID
,
Name
:
&
r
.
Name
,
State
:
&
state
,
CreatedAt
:
&
ct
,
// TODO: We write annotations as labels on the docker containers. All
// these annotations will be read back as labels. Need to fix this.
// Also filter out labels only relevant to this shim.
Labels
:
r
.
Config
.
Labels
,
Network
:
network
,
Linux
:
&
runtimeApi
.
LinuxPodSandboxStatus
{
Namespaces
:
&
runtimeApi
.
Namespace
{
Network
:
&
netNS
}},
},
nil
}
}
// ListPodSandbox returns a list of Sandbox.
// ListPodSandbox returns a list of Sandbox.
func
(
ds
*
dockerService
)
ListPodSandbox
(
filter
*
runtimeApi
.
PodSandboxFilter
)
([]
*
runtimeApi
.
PodSandbox
,
error
)
{
func
(
ds
*
dockerService
)
ListPodSandbox
(
filter
*
runtimeApi
.
PodSandboxFilter
)
([]
*
runtimeApi
.
PodSandbox
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"Not implemented"
)
// By default, list all containers whether they are running or not.
opts
:=
dockertypes
.
ContainerListOptions
{
All
:
true
}
filterOutReadySandboxes
:=
false
opts
.
Filter
=
dockerfilters
.
NewArgs
()
f
:=
newDockerFilter
(
&
opts
.
Filter
)
if
filter
!=
nil
{
if
filter
.
Name
!=
nil
{
f
.
Add
(
"name"
,
filter
.
GetName
())
}
if
filter
.
Id
!=
nil
{
f
.
Add
(
"id"
,
filter
.
GetId
())
}
if
filter
.
State
!=
nil
{
if
filter
.
GetState
()
==
runtimeApi
.
PodSandBoxState_READY
{
// Only list running containers.
opts
.
All
=
false
}
else
{
// runtimeApi.PodSandBoxState_NOTREADY can mean the
// container is in any of the non-running state (e.g., created,
// exited). We can't tell docker to filter out running
// containers directly, so we'll need to filter them out
// ourselves after getting the results.
filterOutReadySandboxes
=
true
}
}
if
filter
.
LabelSelector
!=
nil
{
for
k
,
v
:=
range
filter
.
LabelSelector
{
f
.
AddLabel
(
k
,
v
)
}
}
// Filter out sandbox containers.
f
.
AddLabel
(
containerTypeLabelKey
,
containerTypeLabelSandbox
)
}
containers
,
err
:=
ds
.
client
.
ListContainers
(
opts
)
if
err
!=
nil
{
return
nil
,
err
}
// Convert docker containers to runtime api sandboxes.
result
:=
[]
*
runtimeApi
.
PodSandbox
{}
for
_
,
c
:=
range
containers
{
s
:=
toRuntimeAPISandbox
(
&
c
)
if
filterOutReadySandboxes
&&
s
.
GetState
()
==
runtimeApi
.
PodSandBoxState_READY
{
continue
}
result
=
append
(
result
,
s
)
}
return
result
,
nil
}
func
makeSandboxDockerConfig
(
c
*
runtimeApi
.
PodSandboxConfig
,
image
string
)
*
dockertypes
.
ContainerCreateConfig
{
// Merge annotations and labels because docker supports only labels.
labels
:=
makeLabels
(
c
.
GetLabels
(),
c
.
GetAnnotations
())
// Apply a label to distinguish sandboxes from regular containers.
labels
[
containerTypeLabelKey
]
=
containerTypeLabelSandbox
hc
:=
&
dockercontainer
.
HostConfig
{}
createConfig
:=
&
dockertypes
.
ContainerCreateConfig
{
Name
:
c
.
GetName
(),
Config
:
&
dockercontainer
.
Config
{
Hostname
:
c
.
GetHostname
(),
// TODO: Handle environment variables.
Image
:
image
,
Labels
:
labels
,
},
HostConfig
:
hc
,
}
// Apply linux-specific options.
if
lc
:=
c
.
GetLinux
();
lc
!=
nil
{
// Apply Cgroup options.
// TODO: Check if this works with per-pod cgroups.
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.
exposedPorts
,
portBindings
:=
makePortsAndBindings
(
c
.
GetPortMappings
())
createConfig
.
Config
.
ExposedPorts
=
exposedPorts
hc
.
PortBindings
=
portBindings
// Set DNS options.
if
dnsOpts
:=
c
.
GetDnsOptions
();
dnsOpts
!=
nil
{
hc
.
DNS
=
dnsOpts
.
GetServers
()
hc
.
DNSSearch
=
dnsOpts
.
GetSearches
()
}
// Apply resource options.
setSandboxResources
(
c
.
GetResources
(),
hc
)
// Set security options.
hc
.
SecurityOpt
=
[]
string
{
getSeccompOpts
()}
return
createConfig
}
func
setSandboxResources
(
_
*
runtimeApi
.
PodSandboxResources
,
hc
*
dockercontainer
.
HostConfig
)
{
// Ignore the resource requests and limits for now and just use the docker
// defaults.
// TODO: apply resource limits based on the configuration.
hc
.
Resources
=
dockercontainer
.
Resources
{
MemorySwap
:
-
1
,
// Always disable memory swap.
CPUShares
:
defaultSandboxCPUshares
,
// Use docker's default cpu quota/period.
}
hc
.
OomScoreAdj
=
defaultSandboxOOMScore
}
}
pkg/kubelet/dockershim/docker_sandbox_test.go
0 → 100644
View file @
0fbe6a82
/*
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
(
"testing"
dockertypes
"github.com/docker/engine-api/types"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
func
TestCreateSandbox
(
t
*
testing
.
T
)
{
ds
,
fakeDocker
:=
newTestDockerSevice
()
name
:=
"FOO"
// We don't really want to test k8s name format and parsing,
// but FakeDockerClient parses the name internally during AssertCreated().
// TODO: fix this.
fullName
:=
"k8s_"
+
name
+
".abcde_foo_new_12345678_0"
config
:=
&
runtimeApi
.
PodSandboxConfig
{
Name
:
&
fullName
}
id
,
err
:=
ds
.
CreatePodSandbox
(
config
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
err
:=
fakeDocker
.
AssertCreated
([]
string
{
name
});
err
!=
nil
{
t
.
Errorf
(
"%v"
,
err
)
}
if
err
:=
fakeDocker
.
AssertStarted
([]
string
{
id
});
err
!=
nil
{
t
.
Errorf
(
"%v"
,
err
)
}
// List running containers and verify that there is one (and only one)
// running container that we just created.
containers
,
err
:=
fakeDocker
.
ListContainers
(
dockertypes
.
ContainerListOptions
{
All
:
false
})
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
len
(
containers
)
!=
1
{
t
.
Errorf
(
"More than one running containers: %+v"
,
containers
)
}
if
containers
[
0
]
.
ID
!=
id
{
t
.
Errorf
(
"Expected id %q, got %v"
,
id
,
containers
[
0
]
.
ID
)
}
}
pkg/kubelet/dockershim/docker_service.go
View file @
0fbe6a82
...
@@ -36,7 +36,17 @@ const (
...
@@ -36,7 +36,17 @@ const (
// '{{.HostConfig.NetworkMode}}'.
// '{{.HostConfig.NetworkMode}}'.
namespaceModeHost
=
"host"
namespaceModeHost
=
"host"
dockerNetNSFmt
=
"/proc/%v/ns/net"
defaultSeccompProfile
=
"unconfined"
defaultSeccompProfile
=
"unconfined"
// Internal docker labels used to identify whether a container is a sandbox
// or a regular container.
// TODO: This is not backward compatible with older containers. We will
// need to add filtering based on names.
containerTypeLabelKey
=
"io.kubernetes.docker.type"
containerTypeLabelSandbox
=
"podsandbox"
containerTypeLabelContainer
=
"container"
)
)
func
NewDockerSevice
(
client
dockertools
.
DockerInterface
)
DockerLegacyService
{
func
NewDockerSevice
(
client
dockertools
.
DockerInterface
)
DockerLegacyService
{
...
...
pkg/kubelet/dockershim/docker_service_test.go
View file @
0fbe6a82
...
@@ -20,8 +20,7 @@ import (
...
@@ -20,8 +20,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/kubelet/dockertools"
)
)
func
newFakeDockerSevice
()
*
dockerService
{
func
newTestDockerSevice
()
(
*
dockerService
,
*
dockertools
.
FakeDockerClient
)
{
return
&
dockerService
{
c
:=
dockertools
.
NewFakeDockerClient
()
client
:
dockertools
.
NewFakeDockerClient
(),
return
&
dockerService
{
client
:
c
},
c
}
}
}
pkg/kubelet/dockershim/helpers.go
View file @
0fbe6a82
...
@@ -18,8 +18,15 @@ package dockershim
...
@@ -18,8 +18,15 @@ package dockershim
import
(
import
(
"fmt"
"fmt"
"strconv"
"strings"
dockertypes
"github.com/docker/engine-api/types"
dockerfilters
"github.com/docker/engine-api/types/filters"
dockerapiversion
"github.com/docker/engine-api/types/versions"
dockerapiversion
"github.com/docker/engine-api/types/versions"
dockernat
"github.com/docker/go-connections/nat"
"github.com/golang/glog"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
runtimeApi
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
)
...
@@ -50,6 +57,23 @@ func generateEnvList(envs []*runtimeApi.KeyValue) (result []string) {
...
@@ -50,6 +57,23 @@ func generateEnvList(envs []*runtimeApi.KeyValue) (result []string) {
return
return
}
}
// Merge annotations and labels because docker supports only labels.
// TODO: Need to be able to distinguish annotations from labels; otherwise, we
// couldn't restore the information when reading the labels back from docker.
func
makeLabels
(
labels
,
annotations
map
[
string
]
string
)
map
[
string
]
string
{
merged
:=
make
(
map
[
string
]
string
)
for
k
,
v
:=
range
labels
{
merged
[
k
]
=
v
}
for
k
,
v
:=
range
annotations
{
if
_
,
ok
:=
merged
[
k
];
!
ok
{
// Don't overwrite the key if it already exists.
merged
[
k
]
=
v
}
}
return
merged
}
// generateMountBindings converts the mount list to a list of strings that
// generateMountBindings converts the mount list to a list of strings that
// can be understood by docker.
// can be understood by docker.
// Each element in the string is in the form of:
// Each element in the string is in the form of:
...
@@ -76,3 +100,78 @@ func generateMountBindings(mounts []*runtimeApi.Mount) (result []string) {
...
@@ -76,3 +100,78 @@ func generateMountBindings(mounts []*runtimeApi.Mount) (result []string) {
}
}
return
return
}
}
func
makePortsAndBindings
(
pm
[]
*
runtimeApi
.
PortMapping
)
(
map
[
dockernat
.
Port
]
struct
{},
map
[
dockernat
.
Port
][]
dockernat
.
PortBinding
)
{
exposedPorts
:=
map
[
dockernat
.
Port
]
struct
{}{}
portBindings
:=
map
[
dockernat
.
Port
][]
dockernat
.
PortBinding
{}
for
_
,
port
:=
range
pm
{
exteriorPort
:=
port
.
GetHostPort
()
if
exteriorPort
==
0
{
// No need to do port binding when HostPort is not specified
continue
}
interiorPort
:=
port
.
GetContainerPort
()
// Some of this port stuff is under-documented voodoo.
// See http://stackoverflow.com/questions/20428302/binding-a-port-to-a-host-interface-using-the-rest-api
var
protocol
string
switch
strings
.
ToUpper
(
string
(
port
.
GetProtocol
()))
{
case
"UDP"
:
protocol
=
"/udp"
case
"TCP"
:
protocol
=
"/tcp"
default
:
glog
.
Warningf
(
"Unknown protocol %q: defaulting to TCP"
,
port
.
Protocol
)
protocol
=
"/tcp"
}
dockerPort
:=
dockernat
.
Port
(
strconv
.
Itoa
(
int
(
interiorPort
))
+
protocol
)
exposedPorts
[
dockerPort
]
=
struct
{}{}
hostBinding
:=
dockernat
.
PortBinding
{
HostPort
:
strconv
.
Itoa
(
int
(
exteriorPort
)),
HostIP
:
port
.
GetHostIp
(),
}
// Allow multiple host ports bind to same docker port
if
existedBindings
,
ok
:=
portBindings
[
dockerPort
];
ok
{
// If a docker port already map to a host port, just append the host ports
portBindings
[
dockerPort
]
=
append
(
existedBindings
,
hostBinding
)
}
else
{
// Otherwise, it's fresh new port binding
portBindings
[
dockerPort
]
=
[]
dockernat
.
PortBinding
{
hostBinding
,
}
}
}
return
exposedPorts
,
portBindings
}
// TODO: Seccomp support. Need to figure out how to pass seccomp options
// through the runtime API (annotations?).See dockerManager.getSecurityOpts()
// for the details. Always set the default seccomp profile for now.
// Also need to support syntax for different docker versions.
func
getSeccompOpts
()
string
{
return
fmt
.
Sprintf
(
"%s=%s"
,
"seccomp"
,
defaultSeccompProfile
)
}
func
getNetworkNamespace
(
c
*
dockertypes
.
ContainerJSON
)
string
{
return
fmt
.
Sprintf
(
dockerNetNSFmt
,
c
.
State
.
Pid
)
}
// dockerFilter wraps around dockerfilters.Args and provides methods to modify
// the filter easily.
type
dockerFilter
struct
{
f
*
dockerfilters
.
Args
}
func
newDockerFilter
(
args
*
dockerfilters
.
Args
)
*
dockerFilter
{
return
&
dockerFilter
{
f
:
args
}
}
func
(
f
*
dockerFilter
)
Add
(
key
,
value
string
)
{
f
.
Add
(
key
,
value
)
}
func
(
f
*
dockerFilter
)
AddLabel
(
key
,
value
string
)
{
f
.
Add
(
"label"
,
fmt
.
Sprintf
(
"%s=%s"
,
key
,
value
))
}
pkg/kubelet/dockertools/fake_docker_client.go
View file @
0fbe6a82
...
@@ -51,6 +51,7 @@ type FakeDockerClient struct {
...
@@ -51,6 +51,7 @@ type FakeDockerClient struct {
// Created, Stopped and Removed all container docker ID
// Created, Stopped and Removed all container docker ID
Created
[]
string
Created
[]
string
Started
[]
string
Stopped
[]
string
Stopped
[]
string
Removed
[]
string
Removed
[]
string
VersionInfo
dockertypes
.
Version
VersionInfo
dockertypes
.
Version
...
@@ -229,6 +230,17 @@ func (f *FakeDockerClient) AssertCreated(created []string) error {
...
@@ -229,6 +230,17 @@ func (f *FakeDockerClient) AssertCreated(created []string) error {
return
nil
return
nil
}
}
func
(
f
*
FakeDockerClient
)
AssertStarted
(
started
[]
string
)
error
{
f
.
Lock
()
defer
f
.
Unlock
()
sort
.
StringSlice
(
started
)
.
Sort
()
sort
.
StringSlice
(
f
.
Started
)
.
Sort
()
if
!
reflect
.
DeepEqual
(
started
,
f
.
Started
)
{
return
fmt
.
Errorf
(
"expected %#v, got %#v"
,
started
,
f
.
Started
)
}
return
nil
}
func
(
f
*
FakeDockerClient
)
AssertStopped
(
stopped
[]
string
)
error
{
func
(
f
*
FakeDockerClient
)
AssertStopped
(
stopped
[]
string
)
error
{
f
.
Lock
()
f
.
Lock
()
defer
f
.
Unlock
()
defer
f
.
Unlock
()
...
@@ -339,6 +351,7 @@ func (f *FakeDockerClient) StartContainer(id string) error {
...
@@ -339,6 +351,7 @@ func (f *FakeDockerClient) StartContainer(id string) error {
if
err
:=
f
.
popError
(
"start"
);
err
!=
nil
{
if
err
:=
f
.
popError
(
"start"
);
err
!=
nil
{
return
err
return
err
}
}
f
.
Started
=
append
(
f
.
Started
,
id
)
container
,
ok
:=
f
.
ContainerMap
[
id
]
container
,
ok
:=
f
.
ContainerMap
[
id
]
if
!
ok
{
if
!
ok
{
container
=
convertFakeContainer
(
&
FakeContainer
{
ID
:
id
,
Name
:
id
})
container
=
convertFakeContainer
(
&
FakeContainer
{
ID
:
id
,
Name
:
id
})
...
...
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