mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-14 06:15:45 +00:00
Refactor CreateContainer.
This commit is contained in:
parent
da07fa9dd5
commit
ba4a5ed39e
@ -60,7 +60,7 @@ const (
|
|||||||
type DockerInterface interface {
|
type DockerInterface interface {
|
||||||
ListContainers(options dockertypes.ContainerListOptions) ([]dockertypes.Container, error)
|
ListContainers(options dockertypes.ContainerListOptions) ([]dockertypes.Container, error)
|
||||||
InspectContainer(id string) (*dockertypes.ContainerJSON, error)
|
InspectContainer(id string) (*dockertypes.ContainerJSON, error)
|
||||||
CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
|
CreateContainer(dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error)
|
||||||
StartContainer(id string, hostConfig *docker.HostConfig) error
|
StartContainer(id string, hostConfig *docker.HostConfig) error
|
||||||
StopContainer(id string, timeout uint) error
|
StopContainer(id string, timeout uint) error
|
||||||
RemoveContainer(opts docker.RemoveContainerOptions) error
|
RemoveContainer(opts docker.RemoveContainerOptions) error
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
|
dockernat "github.com/docker/go-connections/nat"
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||||
@ -744,37 +745,37 @@ func TestMakePortsAndBindings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct expected bindings
|
// Construct expected bindings
|
||||||
expectPortBindings := map[string][]docker.PortBinding{
|
expectPortBindings := map[string][]dockernat.PortBinding{
|
||||||
"80/tcp": {
|
"80/tcp": {
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "8080",
|
HostPort: "8080",
|
||||||
HostIP: "127.0.0.1",
|
HostIP: "127.0.0.1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"443/tcp": {
|
"443/tcp": {
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "443",
|
HostPort: "443",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
},
|
},
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "446",
|
HostPort: "446",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"443/udp": {
|
"443/udp": {
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "446",
|
HostPort: "446",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"444/udp": {
|
"444/udp": {
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "444",
|
HostPort: "444",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"445/tcp": {
|
"445/tcp": {
|
||||||
docker.PortBinding{
|
dockernat.PortBinding{
|
||||||
HostPort: "445",
|
HostPort: "445",
|
||||||
HostIP: "",
|
HostIP: "",
|
||||||
},
|
},
|
||||||
|
@ -305,7 +305,7 @@ func (f *FakeDockerClient) normalSleep(mean, stdDev, cutOffMillis int) {
|
|||||||
|
|
||||||
// CreateContainer is a test-spy implementation of DockerInterface.CreateContainer.
|
// CreateContainer is a test-spy implementation of DockerInterface.CreateContainer.
|
||||||
// It adds an entry "create" to the internal method call record.
|
// It adds an entry "create" to the internal method call record.
|
||||||
func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*docker.Container, error) {
|
func (f *FakeDockerClient) CreateContainer(c dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
f.called = append(f.called, "create")
|
f.called = append(f.called, "create")
|
||||||
@ -315,28 +315,21 @@ func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*do
|
|||||||
// This is not a very good fake. We'll just add this container's name to the list.
|
// This is not a very good fake. We'll just add this container's name to the list.
|
||||||
// Docker likes to add a '/', so copy that behavior.
|
// Docker likes to add a '/', so copy that behavior.
|
||||||
name := "/" + c.Name
|
name := "/" + c.Name
|
||||||
|
id := name
|
||||||
f.Created = append(f.Created, name)
|
f.Created = append(f.Created, name)
|
||||||
// The newest container should be in front, because we assume so in GetPodStatus()
|
// The newest container should be in front, because we assume so in GetPodStatus()
|
||||||
f.RunningContainerList = append([]dockertypes.Container{
|
f.RunningContainerList = append([]dockertypes.Container{
|
||||||
{ID: name, Names: []string{name}, Image: c.Config.Image, Labels: c.Config.Labels},
|
{ID: name, Names: []string{name}, Image: c.Config.Image, Labels: c.Config.Labels},
|
||||||
}, f.RunningContainerList...)
|
}, f.RunningContainerList...)
|
||||||
// TODO(random-liu): Remove this convertion when we refactor CreateContainer
|
f.ContainerMap[name] = convertFakeContainer(&FakeContainer{ID: id, Name: name, Config: c.Config, HostConfig: c.HostConfig})
|
||||||
config := &dockercontainer.Config{}
|
|
||||||
convertType(c.Config, config)
|
|
||||||
hostConfig := &dockercontainer.HostConfig{}
|
|
||||||
convertType(c.HostConfig, hostConfig)
|
|
||||||
container := convertFakeContainer(&FakeContainer{ID: name, Name: name, Config: config, HostConfig: hostConfig})
|
|
||||||
containerCopy := *container
|
|
||||||
f.ContainerMap[name] = &containerCopy
|
|
||||||
f.normalSleep(100, 25, 25)
|
f.normalSleep(100, 25, 25)
|
||||||
// TODO(random-liu): This will be refactored soon, we could do this because only the returned id is used.
|
return &dockertypes.ContainerCreateResponse{ID: id}, nil
|
||||||
return &docker.Container{ID: container.ID}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
|
// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
|
||||||
// It adds an entry "start" to the internal method call record.
|
// It adds an entry "start" to the internal method call record.
|
||||||
// The HostConfig at StartContainer will be deprecated from docker 1.10. Now in
|
// The HostConfig at StartContainer will be deprecated from docker 1.10. Now in
|
||||||
// docker manager the HostConfig is set when CreateContainer().
|
// docker manager the HostConfig is set when ContainerCreate().
|
||||||
// TODO(random-liu): Remove the HostConfig here when it is completely removed in
|
// TODO(random-liu): Remove the HostConfig here when it is completely removed in
|
||||||
// docker 1.12.
|
// docker 1.12.
|
||||||
func (f *FakeDockerClient) StartContainer(id string, _ *docker.HostConfig) error {
|
func (f *FakeDockerClient) StartContainer(id string, _ *docker.HostConfig) error {
|
||||||
@ -543,3 +536,8 @@ func (f *FakeDockerPuller) IsImagePresent(name string) (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dockerTimestampToString converts the timestamp to string
|
||||||
|
func dockerTimestampToString(t time.Time) string {
|
||||||
|
return t.Format(time.RFC3339Nano)
|
||||||
|
}
|
||||||
|
@ -67,7 +67,7 @@ func (in instrumentedDockerInterface) InspectContainer(id string) (*dockertypes.
|
|||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (in instrumentedDockerInterface) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) {
|
func (in instrumentedDockerInterface) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
|
||||||
const operation = "create_container"
|
const operation = "create_container"
|
||||||
defer recordOperation(operation, time.Now())
|
defer recordOperation(operation, time.Now())
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
dockerapi "github.com/docker/engine-api/client"
|
dockerapi "github.com/docker/engine-api/client"
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
dockercontainer "github.com/docker/engine-api/types/container"
|
|
||||||
dockerfilters "github.com/docker/engine-api/types/filters"
|
dockerfilters "github.com/docker/engine-api/types/filters"
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -125,24 +124,12 @@ func (d *kubeDockerClient) InspectContainer(id string) (*dockertypes.ContainerJS
|
|||||||
return &containerJSON, nil
|
return &containerJSON, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) CreateContainer(opts docker.CreateContainerOptions) (*docker.Container, error) {
|
func (d *kubeDockerClient) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
|
||||||
config := &dockercontainer.Config{}
|
createResp, err := d.client.ContainerCreate(getDefaultContext(), opts.Config, opts.HostConfig, opts.NetworkingConfig, opts.Name)
|
||||||
if err := convertType(opts.Config, config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
hostConfig := &dockercontainer.HostConfig{}
|
|
||||||
if err := convertType(opts.HostConfig, hostConfig); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err := d.client.ContainerCreate(getDefaultContext(), config, hostConfig, nil, opts.Name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
container := &docker.Container{}
|
return &createResp, nil
|
||||||
if err := convertType(&resp, container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return container, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(random-liu): The HostConfig at container start is deprecated, will remove this in the following refactoring.
|
// TODO(random-liu): The HostConfig at container start is deprecated, will remove this in the following refactoring.
|
||||||
@ -384,11 +371,6 @@ func parseDockerTimestamp(s string) (time.Time, error) {
|
|||||||
return time.Parse(time.RFC3339Nano, s)
|
return time.Parse(time.RFC3339Nano, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dockerTimestampToString converts the timestamp to string
|
|
||||||
func dockerTimestampToString(t time.Time) string {
|
|
||||||
return t.Format(time.RFC3339Nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
// containerNotFoundError is the error returned by InspectContainer when container not found. We
|
// containerNotFoundError is the error returned by InspectContainer when container not found. We
|
||||||
// add this error type for testability. We don't use the original error returned by engine-api
|
// add this error type for testability. We don't use the original error returned by engine-api
|
||||||
// because dockertypes.containerNotFoundError is private, we can't create and inject it in our test.
|
// because dockertypes.containerNotFoundError is private, we can't create and inject it in our test.
|
||||||
|
@ -33,6 +33,9 @@ import (
|
|||||||
|
|
||||||
"github.com/coreos/go-semver/semver"
|
"github.com/coreos/go-semver/semver"
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
|
dockerstrslice "github.com/docker/engine-api/types/strslice"
|
||||||
|
dockernat "github.com/docker/go-connections/nat"
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
@ -477,9 +480,9 @@ func makeMountBindings(mounts []kubecontainer.Mount, podHasSELinuxLabel bool) (r
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.Port]struct{}, map[docker.Port][]docker.PortBinding) {
|
func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[dockernat.Port]struct{}, map[dockernat.Port][]dockernat.PortBinding) {
|
||||||
exposedPorts := map[docker.Port]struct{}{}
|
exposedPorts := map[dockernat.Port]struct{}{}
|
||||||
portBindings := map[docker.Port][]docker.PortBinding{}
|
portBindings := map[dockernat.Port][]dockernat.PortBinding{}
|
||||||
for _, port := range portMappings {
|
for _, port := range portMappings {
|
||||||
exteriorPort := port.HostPort
|
exteriorPort := port.HostPort
|
||||||
if exteriorPort == 0 {
|
if exteriorPort == 0 {
|
||||||
@ -500,10 +503,10 @@ func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.
|
|||||||
protocol = "/tcp"
|
protocol = "/tcp"
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerPort := docker.Port(strconv.Itoa(interiorPort) + protocol)
|
dockerPort := dockernat.Port(strconv.Itoa(interiorPort) + protocol)
|
||||||
exposedPorts[dockerPort] = struct{}{}
|
exposedPorts[dockerPort] = struct{}{}
|
||||||
|
|
||||||
hostBinding := docker.PortBinding{
|
hostBinding := dockernat.PortBinding{
|
||||||
HostPort: strconv.Itoa(exteriorPort),
|
HostPort: strconv.Itoa(exteriorPort),
|
||||||
HostIP: port.HostIP,
|
HostIP: port.HostIP,
|
||||||
}
|
}
|
||||||
@ -514,7 +517,7 @@ func makePortsAndBindings(portMappings []kubecontainer.PortMapping) (map[docker.
|
|||||||
portBindings[dockerPort] = append(existedBindings, hostBinding)
|
portBindings[dockerPort] = append(existedBindings, hostBinding)
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, it's fresh new port binding
|
// Otherwise, it's fresh new port binding
|
||||||
portBindings[dockerPort] = []docker.PortBinding{
|
portBindings[dockerPort] = []dockernat.PortBinding{
|
||||||
hostBinding,
|
hostBinding,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,17 +602,18 @@ func (dm *DockerManager) runContainer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hc := &docker.HostConfig{
|
hc := &dockercontainer.HostConfig{
|
||||||
Binds: binds,
|
Binds: binds,
|
||||||
NetworkMode: netMode,
|
NetworkMode: dockercontainer.NetworkMode(netMode),
|
||||||
IpcMode: ipcMode,
|
IpcMode: dockercontainer.IpcMode(ipcMode),
|
||||||
UTSMode: utsMode,
|
UTSMode: dockercontainer.UTSMode(utsMode),
|
||||||
PidMode: pidMode,
|
PidMode: dockercontainer.PidMode(pidMode),
|
||||||
ReadonlyRootfs: readOnlyRootFilesystem(container),
|
ReadonlyRootfs: readOnlyRootFilesystem(container),
|
||||||
// Memory and CPU are set here for newer versions of Docker (1.6+).
|
Resources: dockercontainer.Resources{
|
||||||
Memory: memoryLimit,
|
Memory: memoryLimit,
|
||||||
MemorySwap: -1,
|
MemorySwap: -1,
|
||||||
CPUShares: cpuShares,
|
CPUShares: cpuShares,
|
||||||
|
},
|
||||||
SecurityOpt: securityOpts,
|
SecurityOpt: securityOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,15 +637,11 @@ func (dm *DockerManager) runContainer(
|
|||||||
hc.CgroupParent = opts.CgroupParent
|
hc.CgroupParent = opts.CgroupParent
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerOpts := docker.CreateContainerOptions{
|
dockerOpts := dockertypes.ContainerCreateConfig{
|
||||||
Name: containerName,
|
Name: containerName,
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Env: makeEnvList(opts.Envs),
|
Env: makeEnvList(opts.Envs),
|
||||||
Image: container.Image,
|
Image: container.Image,
|
||||||
// Memory and CPU are set here for older versions of Docker (pre-1.6).
|
|
||||||
Memory: memoryLimit,
|
|
||||||
MemorySwap: -1,
|
|
||||||
CPUShares: cpuShares,
|
|
||||||
WorkingDir: container.WorkingDir,
|
WorkingDir: container.WorkingDir,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
// Interactive containers:
|
// Interactive containers:
|
||||||
@ -657,36 +657,39 @@ func (dm *DockerManager) runContainer(
|
|||||||
setInfraContainerNetworkConfig(pod, netMode, opts, dockerOpts)
|
setInfraContainerNetworkConfig(pod, netMode, opts, dockerOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
setEntrypointAndCommand(container, opts, &dockerOpts)
|
setEntrypointAndCommand(container, opts, dockerOpts)
|
||||||
|
|
||||||
glog.V(3).Infof("Container %v/%v/%v: setting entrypoint \"%v\" and command \"%v\"", pod.Namespace, pod.Name, container.Name, dockerOpts.Config.Entrypoint, dockerOpts.Config.Cmd)
|
glog.V(3).Infof("Container %v/%v/%v: setting entrypoint \"%v\" and command \"%v\"", pod.Namespace, pod.Name, container.Name, dockerOpts.Config.Entrypoint, dockerOpts.Config.Cmd)
|
||||||
|
|
||||||
securityContextProvider := securitycontext.NewSimpleSecurityContextProvider()
|
securityContextProvider := securitycontext.NewSimpleSecurityContextProvider()
|
||||||
securityContextProvider.ModifyContainerConfig(pod, container, dockerOpts.Config)
|
securityContextProvider.ModifyContainerConfig(pod, container, dockerOpts.Config)
|
||||||
securityContextProvider.ModifyHostConfig(pod, container, dockerOpts.HostConfig)
|
securityContextProvider.ModifyHostConfig(pod, container, dockerOpts.HostConfig)
|
||||||
dockerContainer, err := dm.client.CreateContainer(dockerOpts)
|
createResp, err := dm.client.CreateContainer(dockerOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToCreateContainer, "Failed to create docker container with error: %v", err)
|
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToCreateContainer, "Failed to create docker container with error: %v", err)
|
||||||
return kubecontainer.ContainerID{}, err
|
return kubecontainer.ContainerID{}, err
|
||||||
}
|
}
|
||||||
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
|
if len(createResp.Warnings) != 0 {
|
||||||
|
glog.V(2).Infof("Container %q of pod %q created with warnings: %v", container.Name, format.Pod(pod), createResp.Warnings)
|
||||||
|
}
|
||||||
|
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
|
||||||
|
|
||||||
if err = dm.client.StartContainer(dockerContainer.ID, nil); err != nil {
|
if err = dm.client.StartContainer(createResp.ID, nil); err != nil {
|
||||||
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToStartContainer,
|
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToStartContainer,
|
||||||
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(dockerContainer.ID, 12), err)
|
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(createResp.ID, 12), err)
|
||||||
return kubecontainer.ContainerID{}, err
|
return kubecontainer.ContainerID{}, err
|
||||||
}
|
}
|
||||||
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.StartedContainer, "Started container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
|
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.StartedContainer, "Started container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
|
||||||
|
|
||||||
return kubecontainer.DockerID(dockerContainer.ID).ContainerID(), nil
|
return kubecontainer.DockerID(createResp.ID).ContainerID(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setInfraContainerNetworkConfig sets the network configuration for the infra-container. We only set network configuration for infra-container, all
|
// setInfraContainerNetworkConfig sets the network configuration for the infra-container. We only set network configuration for infra-container, all
|
||||||
// the user containers will share the same network namespace with infra-container.
|
// the user containers will share the same network namespace with infra-container.
|
||||||
func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecontainer.RunContainerOptions, dockerOpts docker.CreateContainerOptions) {
|
func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecontainer.RunContainerOptions, dockerOpts dockertypes.ContainerCreateConfig) {
|
||||||
exposedPorts, portBindings := makePortsAndBindings(opts.PortMappings)
|
exposedPorts, portBindings := makePortsAndBindings(opts.PortMappings)
|
||||||
dockerOpts.Config.ExposedPorts = exposedPorts
|
dockerOpts.Config.ExposedPorts = exposedPorts
|
||||||
dockerOpts.HostConfig.PortBindings = portBindings
|
dockerOpts.HostConfig.PortBindings = dockernat.PortMap(portBindings)
|
||||||
|
|
||||||
if netMode != namespaceModeHost {
|
if netMode != namespaceModeHost {
|
||||||
dockerOpts.Config.Hostname = opts.Hostname
|
dockerOpts.Config.Hostname = opts.Hostname
|
||||||
@ -699,11 +702,11 @@ func setInfraContainerNetworkConfig(pod *api.Pod, netMode string, opts *kubecont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setEntrypointAndCommand(container *api.Container, opts *kubecontainer.RunContainerOptions, dockerOpts *docker.CreateContainerOptions) {
|
func setEntrypointAndCommand(container *api.Container, opts *kubecontainer.RunContainerOptions, dockerOpts dockertypes.ContainerCreateConfig) {
|
||||||
command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs)
|
command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs)
|
||||||
|
|
||||||
dockerOpts.Config.Entrypoint = command
|
dockerOpts.Config.Entrypoint = dockerstrslice.StrSlice(command)
|
||||||
dockerOpts.Config.Cmd = args
|
dockerOpts.Config.Cmd = dockerstrslice.StrSlice(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper function to get the KubeletContainerName and hash from a docker
|
// A helper function to get the KubeletContainerName and hash from a docker
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
|
|
||||||
dockertypes "github.com/docker/engine-api/types"
|
dockertypes "github.com/docker/engine-api/types"
|
||||||
dockercontainer "github.com/docker/engine-api/types/container"
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
|
dockerstrslice "github.com/docker/engine-api/types/strslice"
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
docker "github.com/fsouza/go-dockerclient"
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -164,13 +165,13 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
container *api.Container
|
container *api.Container
|
||||||
envs []kubecontainer.EnvVar
|
envs []kubecontainer.EnvVar
|
||||||
expected *docker.CreateContainerOptions
|
expected *dockertypes.ContainerCreateConfig
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "none",
|
name: "none",
|
||||||
container: &api.Container{},
|
container: &api.Container{},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{},
|
Config: &dockercontainer.Config{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -178,9 +179,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
container: &api.Container{
|
container: &api.Container{
|
||||||
Command: []string{"foo", "bar"},
|
Command: []string{"foo", "bar"},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Entrypoint: []string{"foo", "bar"},
|
Entrypoint: dockerstrslice.StrSlice([]string{"foo", "bar"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -199,9 +200,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
Value: "boo",
|
Value: "boo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Entrypoint: []string{"foo", "zoo", "boo"},
|
Entrypoint: dockerstrslice.StrSlice([]string{"foo", "zoo", "boo"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -210,8 +211,8 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
container: &api.Container{
|
container: &api.Container{
|
||||||
Args: []string{"foo", "bar"},
|
Args: []string{"foo", "bar"},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Cmd: []string{"foo", "bar"},
|
Cmd: []string{"foo", "bar"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -231,9 +232,9 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
Value: "trap",
|
Value: "trap",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Cmd: []string{"zap", "hap", "trap"},
|
Cmd: dockerstrslice.StrSlice([]string{"zap", "hap", "trap"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -243,10 +244,10 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
Command: []string{"foo"},
|
Command: []string{"foo"},
|
||||||
Args: []string{"bar", "baz"},
|
Args: []string{"bar", "baz"},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Entrypoint: []string{"foo"},
|
Entrypoint: dockerstrslice.StrSlice([]string{"foo"}),
|
||||||
Cmd: []string{"bar", "baz"},
|
Cmd: dockerstrslice.StrSlice([]string{"bar", "baz"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -270,10 +271,10 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
Value: "roo",
|
Value: "roo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &docker.CreateContainerOptions{
|
expected: &dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{
|
Config: &dockercontainer.Config{
|
||||||
Entrypoint: []string{"boo--zoo", "foo", "roo"},
|
Entrypoint: dockerstrslice.StrSlice([]string{"boo--zoo", "foo", "roo"}),
|
||||||
Cmd: []string{"foo", "zoo", "boo"},
|
Cmd: dockerstrslice.StrSlice([]string{"foo", "zoo", "boo"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -284,8 +285,8 @@ func TestSetEntrypointAndCommand(t *testing.T) {
|
|||||||
Envs: tc.envs,
|
Envs: tc.envs,
|
||||||
}
|
}
|
||||||
|
|
||||||
actualOpts := &docker.CreateContainerOptions{
|
actualOpts := dockertypes.ContainerCreateConfig{
|
||||||
Config: &docker.Config{},
|
Config: &dockercontainer.Config{},
|
||||||
}
|
}
|
||||||
setEntrypointAndCommand(tc.container, opts, actualOpts)
|
setEntrypointAndCommand(tc.container, opts, actualOpts)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ package securitycontext
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidSecurityContextWithContainerDefaults creates a valid security context provider based on
|
// ValidSecurityContextWithContainerDefaults creates a valid security context provider based on
|
||||||
@ -39,7 +39,7 @@ func NewFakeSecurityContextProvider() SecurityContextProvider {
|
|||||||
|
|
||||||
type FakeSecurityContextProvider struct{}
|
type FakeSecurityContextProvider struct{}
|
||||||
|
|
||||||
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) {
|
func (p FakeSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
|
||||||
}
|
}
|
||||||
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig) {
|
func (p FakeSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig) {
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/leaky"
|
"k8s.io/kubernetes/pkg/kubelet/leaky"
|
||||||
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewSimpleSecurityContextProvider creates a new SimpleSecurityContextProvider.
|
// NewSimpleSecurityContextProvider creates a new SimpleSecurityContextProvider.
|
||||||
@ -37,7 +37,7 @@ type SimpleSecurityContextProvider struct{}
|
|||||||
// ModifyContainerConfig is called before the Docker createContainer call.
|
// ModifyContainerConfig is called before the Docker createContainer call.
|
||||||
// The security context provider can make changes to the Config with which
|
// The security context provider can make changes to the Config with which
|
||||||
// the container is created.
|
// the container is created.
|
||||||
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) {
|
func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config) {
|
||||||
effectiveSC := DetermineEffectiveSecurityContext(pod, container)
|
effectiveSC := DetermineEffectiveSecurityContext(pod, container)
|
||||||
if effectiveSC == nil {
|
if effectiveSC == nil {
|
||||||
return
|
return
|
||||||
@ -50,7 +50,7 @@ func (p SimpleSecurityContextProvider) ModifyContainerConfig(pod *api.Pod, conta
|
|||||||
// ModifyHostConfig is called before the Docker runContainer call.
|
// ModifyHostConfig is called before the Docker runContainer call.
|
||||||
// The security context provider can make changes to the HostConfig, affecting
|
// The security context provider can make changes to the HostConfig, affecting
|
||||||
// security options, whether the container is privileged, volume binds, etc.
|
// security options, whether the container is privileged, volume binds, etc.
|
||||||
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig) {
|
func (p SimpleSecurityContextProvider) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig) {
|
||||||
// Apply pod security context
|
// Apply pod security context
|
||||||
if container.Name != leaky.PodInfraContainerName && pod.Spec.SecurityContext != nil {
|
if container.Name != leaky.PodInfraContainerName && pod.Spec.SecurityContext != nil {
|
||||||
// TODO: We skip application of supplemental groups to the
|
// TODO: We skip application of supplemental groups to the
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||||
)
|
)
|
||||||
@ -35,28 +35,28 @@ func TestModifyContainerConfig(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
podSc *api.PodSecurityContext
|
podSc *api.PodSecurityContext
|
||||||
sc *api.SecurityContext
|
sc *api.SecurityContext
|
||||||
expected *docker.Config
|
expected *dockercontainer.Config
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "container.SecurityContext.RunAsUser set",
|
name: "container.SecurityContext.RunAsUser set",
|
||||||
sc: &api.SecurityContext{
|
sc: &api.SecurityContext{
|
||||||
RunAsUser: &uid,
|
RunAsUser: &uid,
|
||||||
},
|
},
|
||||||
expected: &docker.Config{
|
expected: &dockercontainer.Config{
|
||||||
User: strconv.FormatInt(uid, 10),
|
User: strconv.FormatInt(uid, 10),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no RunAsUser value set",
|
name: "no RunAsUser value set",
|
||||||
sc: &api.SecurityContext{},
|
sc: &api.SecurityContext{},
|
||||||
expected: &docker.Config{},
|
expected: &dockercontainer.Config{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pod.Spec.SecurityContext.RunAsUser set",
|
name: "pod.Spec.SecurityContext.RunAsUser set",
|
||||||
podSc: &api.PodSecurityContext{
|
podSc: &api.PodSecurityContext{
|
||||||
RunAsUser: &uid,
|
RunAsUser: &uid,
|
||||||
},
|
},
|
||||||
expected: &docker.Config{
|
expected: &dockercontainer.Config{
|
||||||
User: strconv.FormatInt(uid, 10),
|
User: strconv.FormatInt(uid, 10),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -68,7 +68,7 @@ func TestModifyContainerConfig(t *testing.T) {
|
|||||||
sc: &api.SecurityContext{
|
sc: &api.SecurityContext{
|
||||||
RunAsUser: &overrideUid,
|
RunAsUser: &overrideUid,
|
||||||
},
|
},
|
||||||
expected: &docker.Config{
|
expected: &dockercontainer.Config{
|
||||||
User: strconv.FormatInt(overrideUid, 10),
|
User: strconv.FormatInt(overrideUid, 10),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -79,7 +79,7 @@ func TestModifyContainerConfig(t *testing.T) {
|
|||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
|
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
|
||||||
dummyContainer.SecurityContext = tc.sc
|
dummyContainer.SecurityContext = tc.sc
|
||||||
dockerCfg := &docker.Config{}
|
dockerCfg := &dockercontainer.Config{}
|
||||||
|
|
||||||
provider.ModifyContainerConfig(pod, dummyContainer, dockerCfg)
|
provider.ModifyContainerConfig(pod, dummyContainer, dockerCfg)
|
||||||
|
|
||||||
@ -93,16 +93,16 @@ func TestModifyHostConfig(t *testing.T) {
|
|||||||
priv := true
|
priv := true
|
||||||
setPrivSC := &api.SecurityContext{}
|
setPrivSC := &api.SecurityContext{}
|
||||||
setPrivSC.Privileged = &priv
|
setPrivSC.Privileged = &priv
|
||||||
setPrivHC := &docker.HostConfig{
|
setPrivHC := &dockercontainer.HostConfig{
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
setCapsHC := &docker.HostConfig{
|
setCapsHC := &dockercontainer.HostConfig{
|
||||||
CapAdd: []string{"addCapA", "addCapB"},
|
CapAdd: []string{"addCapA", "addCapB"},
|
||||||
CapDrop: []string{"dropCapA", "dropCapB"},
|
CapDrop: []string{"dropCapA", "dropCapB"},
|
||||||
}
|
}
|
||||||
|
|
||||||
setSELinuxHC := &docker.HostConfig{}
|
setSELinuxHC := &dockercontainer.HostConfig{}
|
||||||
setSELinuxHC.SecurityOpt = []string{
|
setSELinuxHC.SecurityOpt = []string{
|
||||||
fmt.Sprintf("%s:%s", dockerLabelUser, "user"),
|
fmt.Sprintf("%s:%s", dockerLabelUser, "user"),
|
||||||
fmt.Sprintf("%s:%s", dockerLabelRole, "role"),
|
fmt.Sprintf("%s:%s", dockerLabelRole, "role"),
|
||||||
@ -117,7 +117,7 @@ func TestModifyHostConfig(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
podSc *api.PodSecurityContext
|
podSc *api.PodSecurityContext
|
||||||
sc *api.SecurityContext
|
sc *api.SecurityContext
|
||||||
expected *docker.HostConfig
|
expected *dockercontainer.HostConfig
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "fully set container.SecurityContext",
|
name: "fully set container.SecurityContext",
|
||||||
@ -164,7 +164,7 @@ func TestModifyHostConfig(t *testing.T) {
|
|||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
|
pod := &api.Pod{Spec: api.PodSpec{SecurityContext: tc.podSc}}
|
||||||
dummyContainer.SecurityContext = tc.sc
|
dummyContainer.SecurityContext = tc.sc
|
||||||
dockerCfg := &docker.HostConfig{}
|
dockerCfg := &dockercontainer.HostConfig{}
|
||||||
|
|
||||||
provider.ModifyHostConfig(pod, dummyContainer, dockerCfg)
|
provider.ModifyHostConfig(pod, dummyContainer, dockerCfg)
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
securityContext *api.PodSecurityContext
|
securityContext *api.PodSecurityContext
|
||||||
expected *docker.HostConfig
|
expected *dockercontainer.HostConfig
|
||||||
}{
|
}{
|
||||||
"nil": {
|
"nil": {
|
||||||
securityContext: nil,
|
securityContext: nil,
|
||||||
@ -219,7 +219,7 @@ func TestModifyHostConfigPodSecurityContext(t *testing.T) {
|
|||||||
|
|
||||||
for k, v := range testCases {
|
for k, v := range testCases {
|
||||||
dummyPod.Spec.SecurityContext = v.securityContext
|
dummyPod.Spec.SecurityContext = v.securityContext
|
||||||
dockerCfg := &docker.HostConfig{}
|
dockerCfg := &dockercontainer.HostConfig{}
|
||||||
provider.ModifyHostConfig(dummyPod, dummyContainer, dockerCfg)
|
provider.ModifyHostConfig(dummyPod, dummyContainer, dockerCfg)
|
||||||
if !reflect.DeepEqual(v.expected, dockerCfg) {
|
if !reflect.DeepEqual(v.expected, dockerCfg) {
|
||||||
t.Errorf("unexpected modification of host config for %s. Expected: %#v Got: %#v", k, v.expected, dockerCfg)
|
t.Errorf("unexpected modification of host config for %s. Expected: %#v Got: %#v", k, v.expected, dockerCfg)
|
||||||
@ -301,8 +301,8 @@ func inputSELinuxOptions() *api.SELinuxOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func fullValidHostConfig() *docker.HostConfig {
|
func fullValidHostConfig() *dockercontainer.HostConfig {
|
||||||
return &docker.HostConfig{
|
return &dockercontainer.HostConfig{
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
CapAdd: []string{"addCapA", "addCapB"},
|
CapAdd: []string{"addCapA", "addCapB"},
|
||||||
CapDrop: []string{"dropCapA", "dropCapB"},
|
CapDrop: []string{"dropCapA", "dropCapB"},
|
||||||
|
@ -19,21 +19,21 @@ package securitycontext
|
|||||||
import (
|
import (
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
|
||||||
docker "github.com/fsouza/go-dockerclient"
|
dockercontainer "github.com/docker/engine-api/types/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecurityContextProvider interface {
|
type SecurityContextProvider interface {
|
||||||
// ModifyContainerConfig is called before the Docker createContainer call.
|
// ModifyContainerConfig is called before the Docker createContainer call.
|
||||||
// The security context provider can make changes to the Config with which
|
// The security context provider can make changes to the Config with which
|
||||||
// the container is created.
|
// the container is created.
|
||||||
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config)
|
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *dockercontainer.Config)
|
||||||
|
|
||||||
// ModifyHostConfig is called before the Docker createContainer call.
|
// ModifyHostConfig is called before the Docker createContainer call.
|
||||||
// The security context provider can make changes to the HostConfig, affecting
|
// The security context provider can make changes to the HostConfig, affecting
|
||||||
// security options, whether the container is privileged, volume binds, etc.
|
// security options, whether the container is privileged, volume binds, etc.
|
||||||
// An error is returned if it's not possible to secure the container as requested
|
// An error is returned if it's not possible to secure the container as requested
|
||||||
// with a security context.
|
// with a security context.
|
||||||
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig)
|
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *dockercontainer.HostConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Loading…
Reference in New Issue
Block a user