Kubelet: pass pod name/namespace/uid to runtimes

This commit is contained in:
Pengfei Ni 2016-08-17 16:04:25 +08:00
parent 9de9405be7
commit 9bfa37f2ae
15 changed files with 617 additions and 420 deletions

View File

@ -33,12 +33,8 @@ var (
)
type FakePodSandbox struct {
// PodSandbox contains minimal information about a sandbox.
runtimeApi.PodSandbox
// Annotations is an unstructured key value map that may be set by external
// tools to store and retrieve arbitrary metadata.
Annotations map[string]string
// PodSandboxStatus contains the runtime information for a sandbox.
runtimeApi.PodSandboxStatus
}
type FakeContainer struct {
@ -75,7 +71,7 @@ func (r *FakeRuntimeService) SetFakeContainers(containers []*FakeContainer) {
r.Containers = make(map[string]*FakeContainer)
for _, c := range containers {
containerID := c.GetName()
containerID := c.GetId()
r.Containers[containerID] = c
}
@ -110,19 +106,19 @@ func (r *FakeRuntimeService) CreatePodSandbox(config *runtimeApi.PodSandboxConfi
r.Called = append(r.Called, "CreatePodSandbox")
// PodSandboxID should be randomized for real container runtime, but here just use
// sandbox's name for easily making fake sandboxes.
podSandboxID := config.GetName()
// fixed name from BuildSandboxName() for easily making fake sandboxes.
podSandboxID := BuildSandboxName(config.Metadata)
createdAt := time.Now().Unix()
readyState := runtimeApi.PodSandBoxState_READY
r.Sandboxes[podSandboxID] = &FakePodSandbox{
PodSandbox: runtimeApi.PodSandbox{
Id: &podSandboxID,
Name: config.Name,
State: &readyState,
CreatedAt: &createdAt,
Labels: config.Labels,
PodSandboxStatus: runtimeApi.PodSandboxStatus{
Id: &podSandboxID,
Metadata: config.Metadata,
State: &readyState,
CreatedAt: &createdAt,
Labels: config.Labels,
Annotations: config.Annotations,
},
Annotations: config.Annotations,
}
return podSandboxID, nil
@ -169,7 +165,7 @@ func (r *FakeRuntimeService) PodSandboxStatus(podSandboxID string) (*runtimeApi.
return &runtimeApi.PodSandboxStatus{
Id: &podSandboxID,
Name: s.Name,
Metadata: s.Metadata,
CreatedAt: s.CreatedAt,
State: s.State,
Network: &runtimeApi.PodSandboxNetworkStatus{
@ -192,7 +188,7 @@ func (r *FakeRuntimeService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter)
if filter.Id != nil && filter.GetId() != id {
continue
}
if filter.Name != nil && filter.GetName() != s.GetName() {
if filter.Name != nil && filter.GetName() != s.Metadata.GetName() {
continue
}
if filter.State != nil && filter.GetState() != s.GetState() {
@ -205,7 +201,7 @@ func (r *FakeRuntimeService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter)
result = append(result, &runtimeApi.PodSandbox{
Id: s.Id,
Name: s.Name,
Metadata: s.Metadata,
State: s.State,
CreatedAt: s.CreatedAt,
Labels: s.Labels,
@ -222,15 +218,15 @@ func (r *FakeRuntimeService) CreateContainer(podSandboxID string, config *runtim
r.Called = append(r.Called, "CreateContainer")
// ContainerID should be randomized for real container runtime, but here just use
// container's name for easily making fake containers.
containerID := config.GetName()
// fixed BuildContainerName() for easily making fake containers.
containerID := BuildContainerName(config.Metadata)
createdAt := time.Now().Unix()
createdState := runtimeApi.ContainerState_CREATED
imageRef := config.Image.GetImage()
r.Containers[containerID] = &FakeContainer{
ContainerStatus: runtimeApi.ContainerStatus{
Id: &containerID,
Name: config.Name,
Metadata: config.Metadata,
Image: config.Image,
ImageRef: &imageRef,
CreatedAt: &createdAt,
@ -308,7 +304,7 @@ func (r *FakeRuntimeService) ListContainers(filter *runtimeApi.ContainerFilter)
if filter.Id != nil && filter.GetId() != s.GetId() {
continue
}
if filter.Name != nil && filter.GetName() != s.GetName() {
if filter.Name != nil && filter.GetName() != s.Metadata.GetName() {
continue
}
if filter.PodSandboxId != nil && filter.GetPodSandboxId() != s.SandboxID {
@ -324,7 +320,7 @@ func (r *FakeRuntimeService) ListContainers(filter *runtimeApi.ContainerFilter)
result = append(result, &runtimeApi.Container{
Id: s.Id,
Name: s.Name,
Metadata: s.Metadata,
State: s.State,
Image: s.Image,
ImageRef: s.ImageRef,
@ -348,7 +344,7 @@ func (r *FakeRuntimeService) ContainerStatus(containerID string) (*runtimeApi.Co
return &runtimeApi.ContainerStatus{
Id: c.Id,
Name: c.Name,
Metadata: c.Metadata,
State: c.State,
CreatedAt: c.CreatedAt,
Image: c.Image,

View File

@ -16,6 +16,20 @@ limitations under the License.
package testing
import (
"fmt"
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
func BuildContainerName(metadata *runtimeApi.ContainerMetadata) string {
return fmt.Sprintf("%s_%d", metadata.GetName(), metadata.GetAttempt())
}
func BuildSandboxName(metadata *runtimeApi.PodSandboxMetadata) string {
return fmt.Sprintf("%s_%s_%s_%d", metadata.GetName(), metadata.GetNamespace(), metadata.GetUid(), metadata.GetAttempt())
}
func filterInLabels(filter, labels map[string]string) bool {
for k, v := range filter {
if value, ok := labels[k]; ok {

File diff suppressed because it is too large Load Diff

View File

@ -134,11 +134,29 @@ message LinuxPodSandboxConfig {
optional NamespaceOption namespace_options = 2;
}
// PodSandboxMetadata holds all necessary information for building the sandbox name.
// The container runtime is encouraged to expose the metadata associated with the
// PodSandbox in its user interface for better user experience. E.g., runtime can
// construct a unique PodSandboxName based on the metadata.
message PodSandboxMetadata {
// The pod name of the sandbox. Same as the pod name in the PodSpec.
optional string name = 1;
// The pod uid of the sandbox. Same as the pod UID in the PodSpec.
optional string uid = 2;
// The pod namespace of the sandbox. Same as the pod namespace in the PodSpec.
optional string namespace = 3;
// The attempt number of creating the sandbox.
optional uint32 attempt = 4;
}
// PodSandboxConfig holds all the required and optional fields for creating a
// sandbox.
message PodSandboxConfig {
// The name of the sandbox.
optional string name = 1;
// The metadata of the sandbox. This information will uniquely identify
// the sandbox, and the runtime should leverage this to ensure correct
// operation. The runtime may also use this information to improve UX, such
// as by constructing a readable name.
optional PodSandboxMetadata metadata = 1;
// The hostname of the sandbox.
optional string hostname = 2;
// Path to the directory on the host in which container log files are
@ -228,8 +246,8 @@ enum PodSandBoxState {
message PodSandboxStatus {
// ID of the sandbox.
optional string id = 1;
// Name of the sandbox
optional string name = 2;
// Metadata of the sandbox.
optional PodSandboxMetadata metadata = 2;
// State of the sandbox.
optional PodSandBoxState state = 3;
// Creation timestamp of the sandbox
@ -275,8 +293,8 @@ message ListPodSandboxRequest {
message PodSandbox {
// The id of the PodSandbox
optional string id = 1;
// The name of the PodSandbox
optional string name = 2;
// Metadata of the sandbox
optional PodSandboxMetadata metadata = 2;
// The state of the PodSandbox
optional PodSandBoxState state = 3;
// Creation timestamps of the sandbox
@ -358,9 +376,26 @@ message LinuxUser {
repeated int64 additional_gids = 3;
}
message ContainerConfig {
// Name of the container.
// ContainerMetadata holds all necessary information for building the container
// name. The container runtime is encouraged to expose the metadata in its user
// interface for better user experience. E.g., runtime can construct a unique
// container name based on the metadata. Note that (name, attempt) is unique
// within a sandbox for the entire lifetime of the sandbox.
message ContainerMetadata {
// The name of the container. Same as the container name in the PodSpec.
optional string name = 1;
// The attempt number of creating the container.
optional uint32 attempt = 2;
}
// ContainerConfig holds all the required and optional fields for creating a
// container.
message ContainerConfig {
// The metadata of the container. This information will uniquely identify
// the container, and the runtime should leverage this to ensure correct
// operation. The runtime may also use this information to improve UX, such
// as by constructing a readable name.
optional ContainerMetadata metadata = 1 ;
// Image to use.
optional ImageSpec image = 2;
// Command to execute (i.e., entrypoint for docker)
@ -484,8 +519,8 @@ message Container {
// The ID of the container, used by the container runtime to identify
// a container.
optional string id = 1;
// The name of the container
optional string name = 2;
// The metadata of the container.
optional ContainerMetadata metadata = 2;
// The spec of the image
optional ImageSpec image = 3;
// Reference to the image in use. For most runtimes, this should be an
@ -514,8 +549,8 @@ message ContainerStatusRequest {
message ContainerStatus {
// ID of the container.
optional string id = 1;
// Name of the container.
optional string name = 2;
// Metadata of the container.
optional ContainerMetadata metadata = 2;
// Status of the container.
optional ContainerState state = 3;
// Creation time of the container.

View File

@ -51,9 +51,13 @@ func toRuntimeAPIImage(image *dockertypes.Image) (*runtimeApi.Image, error) {
func toRuntimeAPIContainer(c *dockertypes.Container) *runtimeApi.Container {
state := toRuntimeAPIContainerState(c.Status)
_, _, _, containerName, attempt, _ := parseContainerName(c.Names[0])
return &runtimeApi.Container{
Id: &c.ID,
Name: &c.Names[0],
Id: &c.ID,
Metadata: &runtimeApi.ContainerMetadata{
Name: &containerName,
Attempt: &attempt,
},
Image: &runtimeApi.ImageSpec{Image: &c.Image},
ImageRef: &c.ImageID,
State: &state,
@ -104,9 +108,15 @@ func toRuntimeAPISandboxState(state string) runtimeApi.PodSandBoxState {
func toRuntimeAPISandbox(c *dockertypes.Container) *runtimeApi.PodSandbox {
state := toRuntimeAPISandboxState(c.Status)
podName, podNamespace, podUID, attempt, _ := parseSandboxName(c.Names[0])
return &runtimeApi.PodSandbox{
Id: &c.ID,
Name: &c.Names[0],
Id: &c.ID,
Metadata: &runtimeApi.PodSandboxMetadata{
Name: &podName,
Namespace: &podNamespace,
Uid: &podUID,
Attempt: &attempt,
},
State: &state,
CreatedAt: &c.Created, // TODO: Why do we need CreateAt timestamp for sandboxes?
Labels: c.Labels, // TODO: Need to disthinguish annotaions and labels.

View File

@ -38,9 +38,6 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
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())
}
@ -66,6 +63,13 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]*
// Convert docker to runtime api containers.
result := []*runtimeApi.Container{}
for _, c := range containers {
if len(filter.GetName()) > 0 {
_, _, _, containerName, _, err := parseContainerName(c.Names[0])
if err != nil || containerName != filter.GetName() {
continue
}
}
result = append(result, toRuntimeAPIContainer(&c))
}
return result, nil
@ -79,7 +83,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
return "", fmt.Errorf("container config is nil")
}
if sandboxConfig == nil {
return "", fmt.Errorf("sandbox config is nil for container %q", config.GetName())
return "", fmt.Errorf("sandbox config is nil for container %q", config.Metadata.GetName())
}
// Merge annotations and labels because docker supports only labels.
@ -94,7 +98,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi
image = iSpec.GetImage()
}
createConfig := dockertypes.ContainerCreateConfig{
Name: config.GetName(),
Name: buildContainerName(sandboxConfig, config),
Config: &dockercontainer.Config{
// TODO: set User.
Hostname: sandboxConfig.GetHostname(),
@ -274,9 +278,17 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai
ct, st, ft := createdAt.Unix(), startedAt.Unix(), finishedAt.Unix()
exitCode := int32(r.State.ExitCode)
_, _, _, containerName, attempt, err := parseContainerName(r.Name)
if err != nil {
return nil, err
}
return &runtimeApi.ContainerStatus{
Id: &r.ID,
Name: &r.Name,
Id: &r.ID,
Metadata: &runtimeApi.ContainerMetadata{
Name: &containerName,
Attempt: &attempt,
},
Image: &runtimeApi.ImageSpec{Image: &r.Config.Image},
ImageRef: &r.Image,
Mounts: mounts,

View File

@ -55,7 +55,7 @@ func (ds *dockerService) CreatePodSandbox(config *runtimeApi.PodSandboxConfig) (
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)
return "", fmt.Errorf("failed to create a sandbox for pod %q: %v", config.Metadata.GetName(), err)
}
// Step 3: Start the sandbox container.
@ -117,11 +117,21 @@ func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeApi.PodS
network := &runtimeApi.PodSandboxNetworkStatus{Ip: &IP}
netNS := getNetworkNamespace(r)
podName, podNamespace, podUID, attempt, err := parseSandboxName(r.Name)
if err != nil {
return nil, err
}
return &runtimeApi.PodSandboxStatus{
Id: &r.ID,
Name: &r.Name,
State: &state,
CreatedAt: &ct,
Metadata: &runtimeApi.PodSandboxMetadata{
Name: &podName,
Namespace: &podNamespace,
Uid: &podUID,
Attempt: &attempt,
},
// 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.
@ -140,9 +150,6 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]
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())
}
@ -176,6 +183,13 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]
// Convert docker containers to runtime api sandboxes.
result := []*runtimeApi.PodSandbox{}
for _, c := range containers {
if len(filter.GetName()) > 0 {
sandboxName, _, _, _, err := parseSandboxName(c.Names[0])
if err != nil || sandboxName != filter.GetName() {
continue
}
}
s := toRuntimeAPISandbox(&c)
if filterOutReadySandboxes && s.GetState() == runtimeApi.PodSandBoxState_READY {
continue
@ -193,7 +207,7 @@ func makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig, image string) *dock
hc := &dockercontainer.HostConfig{}
createConfig := &dockertypes.ContainerCreateConfig{
Name: c.GetName(),
Name: buildSandboxName(c),
Config: &dockercontainer.Config{
Hostname: c.GetHostname(),
// TODO: Handle environment variables.

View File

@ -27,18 +27,19 @@ import (
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}
namespace := "BAR"
uid := "1"
config := &runtimeApi.PodSandboxConfig{
Metadata: &runtimeApi.PodSandboxMetadata{
Name: &name,
Namespace: &namespace,
Uid: &uid,
},
}
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)
}

View File

@ -18,6 +18,7 @@ package dockershim
import (
"fmt"
"math/rand"
"strconv"
"strings"
@ -30,6 +31,13 @@ import (
runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
const (
// kubePrefix is used to identify the containers/sandboxes on the node managed by kubelet
kubePrefix = "k8s"
// kubeSandboxNamePrefix is used to keep sandbox name consistent with old podInfraContainer name
kubeSandboxNamePrefix = "POD"
)
// apiVersion implements kubecontainer.Version interface by implementing
// Compare() and String(). It uses the compare function of engine-api to
// compare docker apiversions.
@ -158,6 +166,71 @@ func getNetworkNamespace(c *dockertypes.ContainerJSON) string {
return fmt.Sprintf(dockerNetNSFmt, c.State.Pid)
}
// buildKubeGenericName creates a name which can be reversed to identify container/sandbox name.
// This function returns the unique name.
func buildKubeGenericName(sandboxConfig *runtimeApi.PodSandboxConfig, containerName string) string {
stableName := fmt.Sprintf("%s_%s_%s_%s_%s",
kubePrefix,
containerName,
sandboxConfig.Metadata.GetName(),
sandboxConfig.Metadata.GetNamespace(),
sandboxConfig.Metadata.GetUid(),
)
UID := fmt.Sprintf("%08x", rand.Uint32())
return fmt.Sprintf("%s_%s", stableName, UID)
}
// buildSandboxName creates a name which can be reversed to identify sandbox full name.
func buildSandboxName(sandboxConfig *runtimeApi.PodSandboxConfig) string {
sandboxName := fmt.Sprintf("%s.%d", kubeSandboxNamePrefix, sandboxConfig.Metadata.GetAttempt())
return buildKubeGenericName(sandboxConfig, sandboxName)
}
// parseSandboxName unpacks a sandbox full name, returning the pod name, namespace, uid and attempt.
func parseSandboxName(name string) (string, string, string, uint32, error) {
podName, podNamespace, podUID, _, attempt, err := parseContainerName(name)
if err != nil {
return "", "", "", 0, err
}
return podName, podNamespace, podUID, attempt, nil
}
// buildContainerName creates a name which can be reversed to identify container name.
// This function returns stable name, unique name and an unique id.
func buildContainerName(sandboxConfig *runtimeApi.PodSandboxConfig, containerConfig *runtimeApi.ContainerConfig) string {
containerName := fmt.Sprintf("%s.%d", containerConfig.Metadata.GetName(), containerConfig.Metadata.GetAttempt())
return buildKubeGenericName(sandboxConfig, containerName)
}
// parseContainerName unpacks a container name, returning the pod name, namespace, UID,
// container name and attempt.
func parseContainerName(name string) (podName, podNamespace, podUID, containerName string, attempt uint32, err error) {
parts := strings.Split(name, "_")
if len(parts) == 0 || parts[0] != kubePrefix {
err = fmt.Errorf("failed to parse container name %q into parts", name)
return "", "", "", "", 0, err
}
if len(parts) < 6 {
glog.Warningf("Found a container with the %q prefix, but too few fields (%d): %q", kubePrefix, len(parts), name)
err = fmt.Errorf("container name %q has fewer parts than expected %v", name, parts)
return "", "", "", "", 0, err
}
nameParts := strings.Split(parts[1], ".")
containerName = nameParts[0]
if len(nameParts) > 1 {
attemptNumber, err := strconv.ParseUint(nameParts[1], 10, 32)
if err != nil {
glog.Warningf("invalid container attempt %q in container %q", nameParts[1], name)
}
attempt = uint32(attemptNumber)
}
return parts[2], parts[3], parts[4], containerName, attempt, nil
}
// dockerFilter wraps around dockerfilters.Args and provides methods to modify
// the filter easily.
type dockerFilter struct {

View File

@ -18,9 +18,6 @@ package kuberuntime
import (
"fmt"
"math/rand"
"strconv"
"strings"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
@ -29,11 +26,6 @@ import (
)
const (
// kubePrefix is used to identify the containers/sandboxes on the node managed by kubelet
kubePrefix = "k8s"
// kubeSandboxNamePrefix is used to keep sandbox name consistent with old podInfraContainer name
kubeSandboxNamePrefix = "POD"
// Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc
minShares = 2
sharesPerCPU = 1024
@ -56,69 +48,6 @@ func (b containersByID) Len() int { return len(b) }
func (b containersByID) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (b containersByID) Less(i, j int) bool { return b[i].ID.ID < b[j].ID.ID }
// buildSandboxName creates a name which can be reversed to identify sandbox full name
func buildSandboxName(pod *api.Pod) string {
_, sandboxName, _ := buildKubeGenericName(pod, kubeSandboxNamePrefix)
return sandboxName
}
// parseSandboxName unpacks a sandbox full name, returning the pod name, namespace and uid
func parseSandboxName(name string) (string, string, string, error) {
podName, podNamespace, podUID, _, _, err := parseContainerName(name)
if err != nil {
return "", "", "", err
}
return podName, podNamespace, podUID, nil
}
// buildContainerName creates a name which can be reversed to identify container name.
// This function returns stable name, unique name and an unique id.
func buildContainerName(pod *api.Pod, container *api.Container) (string, string, string) {
// kubelet uses hash to determine whether an existing container matches the desired spec.
containerName := container.Name + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16)
return buildKubeGenericName(pod, containerName)
}
// buildKubeGenericName creates a name which can be reversed to identify container/sandbox name.
// This function returns stable name, unique name and an unique id.
func buildKubeGenericName(pod *api.Pod, containerName string) (string, string, string) {
stableName := fmt.Sprintf("%s_%s_%s_%s_%s",
kubePrefix,
containerName,
pod.Name,
pod.Namespace,
string(pod.UID),
)
UID := fmt.Sprintf("%08x", rand.Uint32())
return stableName, fmt.Sprintf("%s_%s", stableName, UID), UID
}
// parseContainerName unpacks a container name, returning the pod name, namespace, UID and container name
func parseContainerName(name string) (podName, podNamespace, podUID, containerName string, hash uint64, err error) {
parts := strings.Split(name, "_")
if len(parts) == 0 || parts[0] != kubePrefix {
err = fmt.Errorf("failed to parse container name %q into parts", name)
return "", "", "", "", 0, err
}
if len(parts) < 6 {
glog.Warningf("Found a container with the %q prefix, but too few fields (%d): %q", kubePrefix, len(parts), name)
err = fmt.Errorf("container name %q has fewer parts than expected %v", name, parts)
return "", "", "", "", 0, err
}
nameParts := strings.Split(parts[1], ".")
containerName = nameParts[0]
if len(nameParts) > 1 {
hash, err = strconv.ParseUint(nameParts[1], 16, 32)
if err != nil {
glog.Warningf("Invalid container hash %q in container %q", nameParts[1], name)
}
}
return parts[2], parts[3], parts[4], containerName, hash, nil
}
// toKubeContainerState converts runtimeApi.ContainerState to kubecontainer.ContainerState.
func toKubeContainerState(state runtimeApi.ContainerState) kubecontainer.ContainerState {
switch state {

View File

@ -19,6 +19,7 @@ package kuberuntime
import (
"fmt"
"io"
"math/rand"
"os"
"path"
@ -42,19 +43,22 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *api.Conta
return nil, err
}
_, containerName, cid := buildContainerName(pod, container)
command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs)
containerLogsPath := getContainerLogsPath(containerName, pod.UID)
containerLogsPath := getContainerLogsPath(container.Name, pod.UID)
podHasSELinuxLabel := pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil
restartCountUint32 := uint32(restartCount)
config := &runtimeApi.ContainerConfig{
Name: &containerName,
Metadata: &runtimeApi.ContainerMetadata{
Name: &container.Name,
Attempt: &restartCountUint32,
},
Image: &runtimeApi.ImageSpec{Image: &container.Image},
Command: command,
Args: args,
WorkingDir: &container.WorkingDir,
Labels: newContainerLabels(container, pod),
Annotations: newContainerAnnotations(container, pod, restartCount),
Mounts: makeMounts(cid, opts, container, podHasSELinuxLabel),
Mounts: makeMounts(opts, container, podHasSELinuxLabel),
LogPath: &containerLogsPath,
Stdin: &container.Stdin,
StdinOnce: &container.StdinOnce,
@ -150,7 +154,7 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *api.
}
// makeMounts generates container volume mounts for kubelet runtime api.
func makeMounts(cid string, opts *kubecontainer.RunContainerOptions, container *api.Container, podHasSELinuxLabel bool) []*runtimeApi.Mount {
func makeMounts(opts *kubecontainer.RunContainerOptions, container *api.Container, podHasSELinuxLabel bool) []*runtimeApi.Mount {
volumeMounts := []*runtimeApi.Mount{}
for idx := range opts.Mounts {
@ -173,8 +177,9 @@ func makeMounts(cid string, opts *kubecontainer.RunContainerOptions, container *
// mount the file before actually starting the container.
if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 {
// Because the PodContainerDir contains pod uid and container name which is unique enough,
// here we just add an unique container id to make the path unique for different instances
// here we just add a random id to make the path unique for different instances
// of the same container.
cid := makeUID()
containerLogPath := path.Join(opts.PodContainerDir, cid)
fs, err := os.Create(containerLogPath)
if err != nil {
@ -222,6 +227,11 @@ func (m *kubeGenericRuntimeManager) getContainersHelper(filter *runtimeApi.Conta
return resp, err
}
// makeUID returns a randomly generated string.
func makeUID() string {
return fmt.Sprintf("%08x", rand.Uint32())
}
// AttachContainer attaches to the container's console
func (m *kubeGenericRuntimeManager) AttachContainer(id kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) (err error) {
return fmt.Errorf("not implemented")

View File

@ -229,12 +229,11 @@ func (m *kubeGenericRuntimeManager) GetPods(all bool) ([]*kubecontainer.Pod, err
return nil, err
}
for _, s := range sandboxes {
name, namespace, uid, _ := parseSandboxName(s.GetName())
podUID := kubetypes.UID(uid)
podUID := kubetypes.UID(s.Metadata.GetUid())
pods[podUID] = &kubecontainer.Pod{
ID: podUID,
Name: name,
Namespace: namespace,
Name: s.Metadata.GetName(),
Namespace: s.Metadata.GetNamespace(),
}
}

View File

@ -69,22 +69,21 @@ func makeAndSetFakePod(m *kubeGenericRuntimeManager, fakeRuntime *apitest.FakeRu
}
func makeFakePodSandbox(m *kubeGenericRuntimeManager, pod *api.Pod) (*apitest.FakePodSandbox, error) {
config, err := m.generatePodSandboxConfig(pod, "")
config, err := m.generatePodSandboxConfig(pod, "", 0)
if err != nil {
return nil, err
}
podSandboxID := config.GetName()
podSandboxID := apitest.BuildSandboxName(config.Metadata)
readyState := runtimeApi.PodSandBoxState_READY
return &apitest.FakePodSandbox{
PodSandbox: runtimeApi.PodSandbox{
PodSandboxStatus: runtimeApi.PodSandboxStatus{
Id: &podSandboxID,
Name: config.Name,
Metadata: config.Metadata,
State: &readyState,
CreatedAt: &fakeCreatedAt,
Labels: config.Labels,
},
Annotations: config.Annotations,
}, nil
}
@ -94,13 +93,14 @@ func makeFakeContainer(m *kubeGenericRuntimeManager, pod *api.Pod, container api
return nil, err
}
containerID := containerConfig.GetName()
containerID := apitest.BuildContainerName(containerConfig.Metadata)
podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata)
runningState := runtimeApi.ContainerState_RUNNING
imageRef := containerConfig.Image.GetImage()
return &apitest.FakeContainer{
ContainerStatus: runtimeApi.ContainerStatus{
Id: &containerID,
Name: containerConfig.Name,
Metadata: containerConfig.Metadata,
Image: containerConfig.Image,
ImageRef: &imageRef,
CreatedAt: &fakeCreatedAt,
@ -108,12 +108,12 @@ func makeFakeContainer(m *kubeGenericRuntimeManager, pod *api.Pod, container api
Labels: containerConfig.Labels,
Annotations: containerConfig.Annotations,
},
SandboxID: sandboxConfig.GetName(),
SandboxID: podSandboxID,
}, nil
}
func makeFakeContainers(m *kubeGenericRuntimeManager, pod *api.Pod, containers []api.Container) ([]*apitest.FakeContainer, error) {
sandboxConfig, err := m.generatePodSandboxConfig(pod, "")
sandboxConfig, err := m.generatePodSandboxConfig(pod, "", 0)
if err != nil {
return nil, err
}
@ -208,7 +208,7 @@ func TestGetPods(t *testing.T) {
fakeContainer := fakeContainers[i]
c, err := m.toKubeContainer(&runtimeApi.Container{
Id: fakeContainer.Id,
Name: fakeContainer.Name,
Metadata: fakeContainer.Metadata,
State: fakeContainer.State,
Image: fakeContainer.Image,
ImageRef: fakeContainer.ImageRef,

View File

@ -24,12 +24,17 @@ import (
)
// generatePodSandboxConfig generates pod sandbox config from api.Pod.
func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(pod *api.Pod, podIP string) (*runtimeApi.PodSandboxConfig, error) {
sandboxName := buildSandboxName(pod)
func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(pod *api.Pod, podIP string, attempt uint32) (*runtimeApi.PodSandboxConfig, error) {
// TODO: deprecating podsandbox resource requirements in favor of the pod level cgroup
// Refer https://github.com/kubernetes/kubernetes/issues/29871
podUID := string(pod.UID)
podSandboxConfig := &runtimeApi.PodSandboxConfig{
Name: &sandboxName,
Metadata: &runtimeApi.PodSandboxMetadata{
Name: &pod.Name,
Namespace: &pod.Namespace,
Uid: &podUID,
Attempt: &attempt,
},
Labels: newPodLabels(pod),
Annotations: newPodAnnotations(pod),
}
@ -126,7 +131,8 @@ func (m *kubeGenericRuntimeManager) getKubeletSandboxes(all bool) ([]*runtimeApi
result := []*runtimeApi.PodSandbox{}
for _, s := range resp {
if !isManagedByKubelet(s.Labels) {
glog.V(5).Infof("Sandbox %s is not managed by kubelet", s.GetName())
glog.V(5).Infof("Sandbox %s is not managed by kubelet", kubecontainer.BuildPodFullName(
s.Metadata.GetName(), s.Metadata.GetNamespace()))
continue
}

View File

@ -181,7 +181,7 @@ func (r *FakeRuntime) ListContainers(*runtimeApi.ContainerFilter) ([]*runtimeApi
for _, c := range r.Containers {
list = append(list, &runtimeApi.Container{
Id: c.Status.Id,
Name: c.Config.Name,
Metadata: c.Config.Metadata,
Labels: c.Config.Labels,
ImageRef: c.Status.ImageRef,
State: &c.State,