Add a dockershim package
Add a new docker integration with kubelet using the new runtime API. This change adds the package with some skeletons, and implements some of the basic operations.
This commit is contained in:
		| @@ -22,9 +22,8 @@ import ( | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // RuntimeService interface defines the interfaces that should be implemented | ||||
| // by a container runtime. | ||||
| // Thread safety is required from implementations of this interface. | ||||
| // RuntimeService interface should be implemented by a container runtime. | ||||
| // The methods should be thread-safe. | ||||
| type RuntimeService interface { | ||||
| 	// Version returns the runtime name, runtime version and runtime API version | ||||
| 	Version(apiVersion string) (*runtimeApi.VersionResponse, error) | ||||
| @@ -33,40 +32,39 @@ type RuntimeService interface { | ||||
| 	CreatePodSandbox(config *runtimeApi.PodSandboxConfig) (string, error) | ||||
| 	// StopPodSandbox stops the sandbox. If there are any running containers in the | ||||
| 	// sandbox, they should be force terminated. | ||||
| 	StopPodSandbox(podSandBoxID string) error | ||||
| 	// DeletePodSandbox deletes the sandbox. If there are any running containers in the | ||||
| 	// sandbox, they should be force deleted. | ||||
| 	DeletePodSandbox(podSandBoxID string) error | ||||
| 	StopPodSandbox(podSandboxID string) error | ||||
| 	// DeletePodSandbox deletes the sandbox. If there are running containers in the | ||||
| 	// sandbox, they should be forcibly deleted. | ||||
| 	DeletePodSandbox(podSandboxID string) error | ||||
| 	// PodSandboxStatus returns the Status of the PodSandbox. | ||||
| 	PodSandboxStatus(podSandBoxID string) (*runtimeApi.PodSandboxStatus, error) | ||||
| 	// ListPodSandbox returns a list of SandBox. | ||||
| 	PodSandboxStatus(podSandboxID string) (*runtimeApi.PodSandboxStatus, error) | ||||
| 	// ListPodSandbox returns a list of Sandbox. | ||||
| 	ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error) | ||||
| 	// CreateContainer creates a new container in specified PodSandbox | ||||
| 	CreateContainer(podSandBoxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) | ||||
| 	// CreateContainer creates a new container in specified PodSandbox. | ||||
| 	CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) | ||||
| 	// StartContainer starts the container. | ||||
| 	StartContainer(rawContainerID string) error | ||||
| 	// StopContainer stops a running container with a grace period (i.e., timeout). | ||||
| 	StopContainer(rawContainerID string, timeout int64) error | ||||
| 	// RemoveContainer removes the container. If the container is running, the container | ||||
| 	// should be force removed. | ||||
| 	// RemoveContainer removes the container. | ||||
| 	RemoveContainer(rawContainerID string) error | ||||
| 	// ListContainers lists all containers by filters. | ||||
| 	ListContainers(filter *runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error) | ||||
| 	// ContainerStatus returns the container status. | ||||
| 	// ContainerStatus returns the status of the container. | ||||
| 	ContainerStatus(rawContainerID string) (*runtimeApi.ContainerStatus, error) | ||||
| 	// Exec execute a command in the container. | ||||
| 	// Exec executes a command in the container. | ||||
| 	Exec(rawContainerID string, cmd []string, tty bool, stdin io.Reader, stdout, stderr io.WriteCloser) error | ||||
| } | ||||
|  | ||||
| // ImageManagerService interface defines the interfaces that should be implemented | ||||
| // by a container image manager. | ||||
| // Thread safety is required from implementations of this interface. | ||||
| // ImageManagerService interface should be implemented by a container image | ||||
| // manager. | ||||
| // The methods should be thread-safe. | ||||
| type ImageManagerService interface { | ||||
| 	// ListImages lists existing images. | ||||
| 	// ListImages lists the existing images. | ||||
| 	ListImages(filter *runtimeApi.ImageFilter) ([]*runtimeApi.Image, error) | ||||
| 	// ImageStatus returns the status of the image. | ||||
| 	ImageStatus(image *runtimeApi.ImageSpec) (*runtimeApi.Image, error) | ||||
| 	// PullImage pulls a image with authentication config. | ||||
| 	// PullImage pulls an image with the authentication config. | ||||
| 	PullImage(image *runtimeApi.ImageSpec, auth *runtimeApi.AuthConfig) error | ||||
| 	// RemoveImage removes the image. | ||||
| 	RemoveImage(image *runtimeApi.ImageSpec) error | ||||
|   | ||||
							
								
								
									
										91
									
								
								pkg/kubelet/dockershim/convert.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								pkg/kubelet/dockershim/convert.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	dockertypes "github.com/docker/engine-api/types" | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // This file contains helper functions to convert docker API types to runtime | ||||
| // API types, or vice versa. | ||||
|  | ||||
| const ( | ||||
| 	// Status of a container returned by docker ListContainers | ||||
| 	statusRunningPrefix = "Up" | ||||
| 	statusCreatedPrefix = "Created" | ||||
| 	statusExitedPrefix  = "Exited" | ||||
| ) | ||||
|  | ||||
| func toRuntimeAPIImage(image *dockertypes.Image) (*runtimeApi.Image, error) { | ||||
| 	if image == nil { | ||||
| 		return nil, fmt.Errorf("unable to convert a nil pointer to a runtime API image") | ||||
| 	} | ||||
|  | ||||
| 	size := uint64(image.VirtualSize) | ||||
| 	return &runtimeApi.Image{ | ||||
| 		Id:          &image.ID, | ||||
| 		RepoTags:    image.RepoTags, | ||||
| 		RepoDigests: image.RepoDigests, | ||||
| 		Size_:       &size, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func toRuntimeAPIContainer(c *dockertypes.Container) *runtimeApi.Container { | ||||
| 	state := toRuntimeAPIContainerState(c.Status) | ||||
| 	return &runtimeApi.Container{ | ||||
| 		Id:       &c.ID, | ||||
| 		Name:     &c.Names[0], | ||||
| 		Image:    &runtimeApi.ImageSpec{Image: &c.Image}, | ||||
| 		ImageRef: &c.ImageID, | ||||
| 		State:    &state, | ||||
| 		Labels:   c.Labels, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func toDockerContainerStatus(state runtimeApi.ContainerState) string { | ||||
| 	switch state { | ||||
| 	case runtimeApi.ContainerState_CREATED: | ||||
| 		return "created" | ||||
| 	case runtimeApi.ContainerState_RUNNING: | ||||
| 		return "running" | ||||
| 	case runtimeApi.ContainerState_EXITED: | ||||
| 		return "exited" | ||||
| 	case runtimeApi.ContainerState_UNKNOWN: | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		return "unknown" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func toRuntimeAPIContainerState(state string) runtimeApi.ContainerState { | ||||
| 	// Parse the state string in dockertypes.Container. This could break when | ||||
| 	// we upgrade docker. | ||||
| 	switch { | ||||
| 	case strings.HasPrefix(state, statusRunningPrefix): | ||||
| 		return runtimeApi.ContainerState_RUNNING | ||||
| 	case strings.HasPrefix(state, statusExitedPrefix): | ||||
| 		return runtimeApi.ContainerState_EXITED | ||||
| 	case strings.HasPrefix(state, statusCreatedPrefix): | ||||
| 		return runtimeApi.ContainerState_CREATED | ||||
| 	default: | ||||
| 		return runtimeApi.ContainerState_UNKNOWN | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										41
									
								
								pkg/kubelet/dockershim/convert_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								pkg/kubelet/dockershim/convert_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
| 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" | ||||
|  | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| func TestConvertDockerStatusToRuntimeAPIState(t *testing.T) { | ||||
| 	testCases := []struct { | ||||
| 		input    string | ||||
| 		expected runtimeApi.ContainerState | ||||
| 	}{ | ||||
| 		{input: "Up 5 hours", expected: runtimeApi.ContainerState_RUNNING}, | ||||
| 		{input: "Exited (0) 2 hours ago", expected: runtimeApi.ContainerState_EXITED}, | ||||
| 		{input: "Created", expected: runtimeApi.ContainerState_CREATED}, | ||||
| 		{input: "Random string", expected: runtimeApi.ContainerState_UNKNOWN}, | ||||
| 	} | ||||
|  | ||||
| 	for i, test := range testCases { | ||||
| 		if actual := toRuntimeAPIContainerState(test.input); actual != test.expected { | ||||
| 			t.Errorf("Test[%d]: expected %q, got %q", i, test.expected, actual) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										18
									
								
								pkg/kubelet/dockershim/doc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								pkg/kubelet/dockershim/doc.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| /* | ||||
| 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. | ||||
| */ | ||||
|  | ||||
| // Docker integration using pkg/kubelet/api/v1alpha1/runtime/api.pb.go. | ||||
| package dockershim | ||||
							
								
								
									
										203
									
								
								pkg/kubelet/dockershim/docker_container.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								pkg/kubelet/dockershim/docker_container.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	dockertypes "github.com/docker/engine-api/types" | ||||
| 	dockercontainer "github.com/docker/engine-api/types/container" | ||||
| 	dockerfilters "github.com/docker/engine-api/types/filters" | ||||
| 	dockerstrslice "github.com/docker/engine-api/types/strslice" | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // ListContainers lists all containers matching the filter. | ||||
| func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*runtimeApi.Container, error) { | ||||
| 	opts := dockertypes.ContainerListOptions{All: true} | ||||
|  | ||||
| 	opts.Filter = dockerfilters.NewArgs() | ||||
| 	if filter != nil { | ||||
| 		if filter.Name != nil { | ||||
| 			opts.Filter.Add("name", filter.GetName()) | ||||
| 		} | ||||
| 		if filter.Id != nil { | ||||
| 			opts.Filter.Add("id", filter.GetId()) | ||||
| 		} | ||||
| 		if filter.State != nil { | ||||
| 			opts.Filter.Add("status", toDockerContainerStatus(filter.GetState())) | ||||
| 		} | ||||
| 		if filter.PodSandboxId != nil { | ||||
| 			// TODO: implement this after sandbox functions are implemented. | ||||
| 		} | ||||
|  | ||||
| 		if filter.LabelSelector != nil { | ||||
| 			for k, v := range filter.LabelSelector { | ||||
| 				opts.Filter.Add("label", fmt.Sprintf("%s=%s", k, v)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	containers, err := ds.client.ListContainers(opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Convert docker to runtime api containers. | ||||
| 	result := []*runtimeApi.Container{} | ||||
| 	for _, c := range containers { | ||||
| 		result = append(result, toRuntimeAPIContainer(&c)) | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| // CreateContainer creates a new container in the given PodSandbox | ||||
| // Note: docker doesn't use LogPath yet. | ||||
| // TODO: check if the default values returned by the runtime API are ok. | ||||
| func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) { | ||||
| 	if config == nil { | ||||
| 		return "", fmt.Errorf("container config is nil") | ||||
| 	} | ||||
| 	if sandboxConfig == nil { | ||||
| 		return "", fmt.Errorf("sandbox config is nil for container %q", config.GetName()) | ||||
| 	} | ||||
|  | ||||
| 	// Merge annotations and labels because docker supports only labels. | ||||
| 	// TODO: add a prefix to annotations so that we can distinguish labels and | ||||
| 	// annotations when reading back them from the docker container. | ||||
| 	// TODO: should we apply docker-specific labels? | ||||
| 	labels := config.GetLabels() | ||||
| 	for k, v := range config.GetAnnotations() { | ||||
| 		if _, ok := labels[k]; !ok { | ||||
| 			// Only write to labels if the key doesn't exist. | ||||
| 			labels[k] = v | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	image := "" | ||||
| 	if iSpec := config.GetImage(); iSpec != nil { | ||||
| 		image = iSpec.GetImage() | ||||
| 	} | ||||
| 	createConfig := dockertypes.ContainerCreateConfig{ | ||||
| 		Name: config.GetName(), | ||||
| 		Config: &dockercontainer.Config{ | ||||
| 			// TODO: set User. | ||||
| 			Hostname:   sandboxConfig.GetHostname(), | ||||
| 			Entrypoint: dockerstrslice.StrSlice(config.GetCommand()), | ||||
| 			Cmd:        dockerstrslice.StrSlice(config.GetArgs()), | ||||
| 			Env:        generateEnvList(config.GetEnvs()), | ||||
| 			Image:      image, | ||||
| 			WorkingDir: config.GetWorkingDir(), | ||||
| 			Labels:     labels, | ||||
| 			// Interactive containers: | ||||
| 			OpenStdin: config.GetStdin(), | ||||
| 			StdinOnce: config.GetStdinOnce(), | ||||
| 			Tty:       config.GetTty(), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	// Fill the HostConfig. | ||||
| 	hc := &dockercontainer.HostConfig{ | ||||
| 		Binds:          generateMountBindings(config.GetMounts()), | ||||
| 		ReadonlyRootfs: config.GetReadonlyRootfs(), | ||||
| 		Privileged:     config.GetPrivileged(), | ||||
| 	} | ||||
|  | ||||
| 	// Apply options derived from the sandbox config. | ||||
| 	if lc := sandboxConfig.GetLinux(); lc != nil { | ||||
| 		// Apply Cgroup options. | ||||
| 		// TODO: Check if this works with per-pod cgroups. | ||||
| 		hc.CgroupParent = lc.GetCgroupParent() | ||||
|  | ||||
| 		// Apply namespace options. | ||||
| 		sandboxNSMode := fmt.Sprintf("container:%v", podSandboxID) | ||||
| 		hc.NetworkMode = dockercontainer.NetworkMode(sandboxNSMode) | ||||
| 		hc.IpcMode = dockercontainer.IpcMode(sandboxNSMode) | ||||
| 		hc.UTSMode = "" | ||||
| 		hc.PidMode = "" | ||||
|  | ||||
| 		nsOpts := lc.GetNamespaceOptions() | ||||
| 		if nsOpts != nil { | ||||
| 			if nsOpts.GetHostNetwork() { | ||||
| 				hc.UTSMode = namespaceModeHost | ||||
| 			} | ||||
| 			if nsOpts.GetHostPid() { | ||||
| 				hc.PidMode = namespaceModeHost | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Apply Linux-specific options if applicable. | ||||
| 	if lc := config.GetLinux(); lc != nil { | ||||
| 		// Apply resource options. | ||||
| 		// TODO: Check if the units are correct. | ||||
| 		// TODO: Can we assume the defaults are sane? | ||||
| 		rOpts := lc.GetResources() | ||||
| 		if rOpts != nil { | ||||
| 			hc.Resources = dockercontainer.Resources{ | ||||
| 				Memory:     rOpts.GetMemoryLimitInBytes(), | ||||
| 				MemorySwap: -1, // Always disable memory swap. | ||||
| 				CPUShares:  rOpts.GetCpuShares(), | ||||
| 				CPUQuota:   rOpts.GetCpuQuota(), | ||||
| 				CPUPeriod:  rOpts.GetCpuPeriod(), | ||||
| 				// TODO: Need to set devices. | ||||
| 			} | ||||
| 			hc.OomScoreAdj = int(rOpts.GetOomScoreAdj()) | ||||
| 		} | ||||
| 		// Note: ShmSize is handled in kube_docker_client.go | ||||
| 	} | ||||
|  | ||||
| 	// 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. | ||||
| 	hc.SecurityOpt = []string{fmt.Sprintf("%s=%s", "seccomp", defaultSeccompProfile)} | ||||
| 	// TODO: Add or drop capabilities. | ||||
|  | ||||
| 	createConfig.HostConfig = hc | ||||
| 	createResp, err := ds.client.CreateContainer(createConfig) | ||||
| 	if createResp != nil { | ||||
| 		return createResp.ID, err | ||||
| 	} | ||||
| 	return "", err | ||||
| } | ||||
|  | ||||
| // StartContainer starts the container. | ||||
| func (ds *dockerService) StartContainer(rawContainerID string) error { | ||||
| 	return ds.client.StartContainer(rawContainerID) | ||||
| } | ||||
|  | ||||
| // StopContainer stops a running container with a grace period (i.e., timeout). | ||||
| func (ds *dockerService) StopContainer(rawContainerID string, timeout int64) error { | ||||
| 	return ds.client.StopContainer(rawContainerID, int(timeout)) | ||||
| } | ||||
|  | ||||
| // RemoveContainer removes the container. | ||||
| // TODO: If a container is still running, should we forcibly remove it? | ||||
| func (ds *dockerService) RemoveContainer(rawContainerID string) error { | ||||
| 	return ds.client.RemoveContainer(rawContainerID, dockertypes.ContainerRemoveOptions{RemoveVolumes: true}) | ||||
| } | ||||
|  | ||||
| // ContainerStatus returns the container status. | ||||
| // TODO: Implement the function. | ||||
| func (ds *dockerService) ContainerStatus(rawContainerID string) (*runtimeApi.ContainerStatus, error) { | ||||
| 	return nil, fmt.Errorf("not implemented") | ||||
| } | ||||
|  | ||||
| // Exec execute a command in the container. | ||||
| // TODO: Implement the function. | ||||
| func (ds *dockerService) Exec(rawContainerID string, cmd []string, tty bool, stdin io.Reader, stdout, stderr io.WriteCloser) error { | ||||
| 	return fmt.Errorf("not implemented") | ||||
| } | ||||
							
								
								
									
										85
									
								
								pkg/kubelet/dockershim/docker_image.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								pkg/kubelet/dockershim/docker_image.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	dockertypes "github.com/docker/engine-api/types" | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // This file implements methods in ImageManagerService. | ||||
|  | ||||
| // ListImages lists existing images. | ||||
| func (ds *dockerService) ListImages(filter *runtimeApi.ImageFilter) ([]*runtimeApi.Image, error) { | ||||
| 	opts := dockertypes.ImageListOptions{} | ||||
| 	if filter != nil { | ||||
| 		if imgSpec := filter.GetImage(); imgSpec != nil { | ||||
| 			opts.MatchName = imgSpec.GetImage() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	images, err := ds.client.ListImages(opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	result := []*runtimeApi.Image{} | ||||
| 	for _, i := range images { | ||||
| 		apiImage, err := toRuntimeAPIImage(&i) | ||||
| 		if err != nil { | ||||
| 			// TODO: log an error message? | ||||
| 			continue | ||||
| 		} | ||||
| 		result = append(result, apiImage) | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| // ImageStatus returns the status of the image. | ||||
| func (ds *dockerService) ImageStatus(image *runtimeApi.ImageSpec) (*runtimeApi.Image, error) { | ||||
| 	images, err := ds.ListImages(&runtimeApi.ImageFilter{Image: image}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if len(images) != 1 { | ||||
| 		return nil, fmt.Errorf("ImageStatus returned more than one image: %+v", images) | ||||
| 	} | ||||
| 	return images[0], nil | ||||
| } | ||||
|  | ||||
| // PullImage pulls a image with authentication config. | ||||
| func (ds *dockerService) PullImage(image *runtimeApi.ImageSpec, auth *runtimeApi.AuthConfig) error { | ||||
| 	// TODO: add default tags for images or should this be done by kubelet? | ||||
| 	return ds.client.PullImage(image.GetImage(), | ||||
| 		dockertypes.AuthConfig{ | ||||
| 			Username:      auth.GetUsername(), | ||||
| 			Password:      auth.GetPassword(), | ||||
| 			ServerAddress: auth.GetServerAddress(), | ||||
| 			IdentityToken: auth.GetIdentityToken(), | ||||
| 			RegistryToken: auth.GetRegistryToken(), | ||||
| 		}, | ||||
| 		dockertypes.ImagePullOptions{}, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // RemoveImage removes the image. | ||||
| func (ds *dockerService) RemoveImage(image *runtimeApi.ImageSpec) error { | ||||
| 	_, err := ds.client.RemoveImage(image.GetImage(), dockertypes.ImageRemoveOptions{PruneChildren: true}) | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										51
									
								
								pkg/kubelet/dockershim/docker_sandbox.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								pkg/kubelet/dockershim/docker_sandbox.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // CreatePodSandbox creates a pod-level sandbox. | ||||
| // The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899 | ||||
| func (ds *dockerService) CreatePodSandbox(config *runtimeApi.PodSandboxConfig) (string, error) { | ||||
| 	return "", fmt.Errorf("Not implemented") | ||||
| } | ||||
|  | ||||
| // StopPodSandbox stops the sandbox. If there are any running containers in the | ||||
| // sandbox, they should be force terminated. | ||||
| func (ds *dockerService) StopPodSandbox(podSandboxID string) error { | ||||
| 	return fmt.Errorf("Not implemented") | ||||
| } | ||||
|  | ||||
| // DeletePodSandbox deletes the sandbox. If there are running containers in the | ||||
| // sandbox, they should be forcibly deleted. | ||||
| func (ds *dockerService) DeletePodSandbox(podSandboxID string) error { | ||||
| 	return fmt.Errorf("Not implemented") | ||||
| } | ||||
|  | ||||
| // PodSandboxStatus returns the Status of the PodSandbox. | ||||
| func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeApi.PodSandboxStatus, error) { | ||||
| 	return nil, fmt.Errorf("Not implemented") | ||||
| } | ||||
|  | ||||
| // ListPodSandbox returns a list of Sandbox. | ||||
| func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error) { | ||||
| 	return nil, fmt.Errorf("Not implemented") | ||||
| } | ||||
							
								
								
									
										78
									
								
								pkg/kubelet/dockershim/docker_service.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								pkg/kubelet/dockershim/docker_service.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | ||||
| 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	dockerRuntimeName = "docker" | ||||
| 	kubeAPIVersion    = "0.1.0" | ||||
|  | ||||
| 	// String used to detect docker host mode for various namespaces (e.g. | ||||
| 	// networking). Must match the value returned by docker inspect -f | ||||
| 	// '{{.HostConfig.NetworkMode}}'. | ||||
| 	namespaceModeHost = "host" | ||||
|  | ||||
| 	defaultSeccompProfile = "unconfined" | ||||
| ) | ||||
|  | ||||
| func NewDockerSevice(client dockertools.DockerInterface) DockerLegacyService { | ||||
| 	return &dockerService{ | ||||
| 		client: dockertools.NewInstrumentedDockerInterface(client), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // DockerLegacyService is an interface that embeds both the new | ||||
| // RuntimeService and ImageService interfaces, while including legacy methods | ||||
| // for backward compatibility. | ||||
| type DockerLegacyService interface { | ||||
| 	kubecontainer.RuntimeService | ||||
| 	kubecontainer.ImageManagerService | ||||
|  | ||||
| 	// Supporting legacy methods for docker. | ||||
| 	GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) | ||||
| 	kubecontainer.ContainerAttacher | ||||
| 	PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error | ||||
| } | ||||
|  | ||||
| type dockerService struct { | ||||
| 	client dockertools.DockerInterface | ||||
| } | ||||
|  | ||||
| // Version returns the runtime name, runtime version and runtime API version | ||||
| func (ds *dockerService) Version(apiVersion string) (*runtimeApi.VersionResponse, error) { | ||||
| 	v, err := ds.client.Version() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("docker: failed to get docker version: %v", err) | ||||
| 	} | ||||
| 	runtimeAPIVersion := kubeAPIVersion | ||||
| 	name := dockerRuntimeName | ||||
| 	return &runtimeApi.VersionResponse{ | ||||
| 		Version:           &runtimeAPIVersion, | ||||
| 		RuntimeName:       &name, | ||||
| 		RuntimeVersion:    &v.Version, | ||||
| 		RuntimeApiVersion: &v.APIVersion, | ||||
| 	}, nil | ||||
| } | ||||
							
								
								
									
										78
									
								
								pkg/kubelet/dockershim/helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								pkg/kubelet/dockershim/helpers.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	dockerapiversion "github.com/docker/engine-api/types/versions" | ||||
| 	runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||
| ) | ||||
|  | ||||
| // apiVersion implements kubecontainer.Version interface by implementing | ||||
| // Compare() and String(). It uses the compare function of engine-api to | ||||
| // compare docker apiversions. | ||||
| type apiVersion string | ||||
|  | ||||
| func (v apiVersion) String() string { | ||||
| 	return string(v) | ||||
| } | ||||
|  | ||||
| func (v apiVersion) Compare(other string) (int, error) { | ||||
| 	if dockerapiversion.LessThan(string(v), other) { | ||||
| 		return -1, nil | ||||
| 	} else if dockerapiversion.GreaterThan(string(v), other) { | ||||
| 		return 1, nil | ||||
| 	} | ||||
| 	return 0, nil | ||||
| } | ||||
|  | ||||
| // generateEnvList converts KeyValue list to a list of strings, in the form of | ||||
| // '<key>=<value>', which can be understood by docker. | ||||
| func generateEnvList(envs []*runtimeApi.KeyValue) (result []string) { | ||||
| 	for _, env := range envs { | ||||
| 		result = append(result, fmt.Sprintf("%s=%s", env.GetKey(), env.GetValue())) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // generateMountBindings converts the mount list to a list of strings that | ||||
| // can be understood by docker. | ||||
| // Each element in the string is in the form of: | ||||
| // '<HostPath>:<ContainerPath>', or | ||||
| // '<HostPath>:<ContainerPath>:ro', if the path is read only, or | ||||
| // '<HostPath>:<ContainerPath>:Z', if the volume requires SELinux | ||||
| // relabeling and the pod provides an SELinux label | ||||
| func generateMountBindings(mounts []*runtimeApi.Mount) (result []string) { | ||||
| 	// TODO: resolve podHasSELinuxLabel | ||||
| 	for _, m := range mounts { | ||||
| 		bind := fmt.Sprintf("%s:%s", m.GetHostPath(), m.GetContainerPath()) | ||||
| 		readOnly := m.GetReadonly() | ||||
| 		if readOnly { | ||||
| 			bind += ":ro" | ||||
| 		} | ||||
| 		if m.GetSelinuxRelabel() { | ||||
| 			if readOnly { | ||||
| 				bind += ",Z" | ||||
| 			} else { | ||||
| 				bind += ":Z" | ||||
| 			} | ||||
| 		} | ||||
| 		result = append(result, bind) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										43
									
								
								pkg/kubelet/dockershim/legacy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								pkg/kubelet/dockershim/legacy.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* | ||||
| 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 ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | ||||
| 	"k8s.io/kubernetes/pkg/util/term" | ||||
| ) | ||||
|  | ||||
| // This file implements the functions that are needed for backward | ||||
| // compatibility. Therefore, it imports various kubernetes packages | ||||
| // directly. | ||||
|  | ||||
| // TODO: implement the methods in this file. | ||||
| func (ds *dockerService) AttachContainer(id kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) (err error) { | ||||
| 	return fmt.Errorf("not implemented") | ||||
| } | ||||
|  | ||||
| func (ds *dockerService) GetContainerLogs(pod *api.Pod, containerID kubecontainer.ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) { | ||||
| 	return fmt.Errorf("not implemented") | ||||
| } | ||||
|  | ||||
| func (ds *dockerService) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error { | ||||
| 	return fmt.Errorf("not implemented") | ||||
| } | ||||
| @@ -225,7 +225,7 @@ func NewDockerManager( | ||||
| 	seccompProfileRoot string, | ||||
| 	options ...kubecontainer.Option) *DockerManager { | ||||
| 	// Wrap the docker client with instrumentedDockerInterface | ||||
| 	client = newInstrumentedDockerInterface(client) | ||||
| 	client = NewInstrumentedDockerInterface(client) | ||||
|  | ||||
| 	// Work out the location of the Docker runtime, defaulting to /var/lib/docker | ||||
| 	// if there are any problems. | ||||
|   | ||||
| @@ -30,7 +30,7 @@ type instrumentedDockerInterface struct { | ||||
| } | ||||
|  | ||||
| // Creates an instrumented DockerInterface from an existing DockerInterface. | ||||
| func newInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterface { | ||||
| func NewInstrumentedDockerInterface(dockerClient DockerInterface) DockerInterface { | ||||
| 	return instrumentedDockerInterface{ | ||||
| 		client: dockerClient, | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Yu-Ju Hong
					Yu-Ju Hong