diff --git a/pkg/kubelet/dockertools/labels.go b/pkg/kubelet/dockertools/labels.go index 95b6dca77b9..652373141cf 100644 --- a/pkg/kubelet/dockertools/labels.go +++ b/pkg/kubelet/dockertools/labels.go @@ -32,10 +32,12 @@ const ( kubernetesPodNamespaceLabel = "io.kubernetes.pod.namespace" kubernetesPodUID = "io.kubernetes.pod.uid" + kubernetesContainerRestartCountLabel = "io.kubernetes.container.restartCount" + kubernetesContainerTerminationMessagePath = "io.kubernetes.container.terminationMessagePath" + kubernetesPodLabel = "io.kubernetes.pod.data" kubernetesTerminationGracePeriodLabel = "io.kubernetes.pod.terminationGracePeriod" kubernetesContainerLabel = "io.kubernetes.container.name" - kubernetesContainerRestartCountLabel = "io.kubernetes.container.restartCount" ) func newLabels(container *api.Container, pod *api.Pod, restartCount int) map[string]string { @@ -46,6 +48,7 @@ func newLabels(container *api.Container, pod *api.Pod, restartCount int) map[str labels[kubernetesPodUID] = string(pod.UID) labels[kubernetesContainerRestartCountLabel] = strconv.Itoa(restartCount) + labels[kubernetesContainerTerminationMessagePath] = container.TerminationMessagePath return labels } @@ -65,3 +68,14 @@ func getRestartCountFromLabel(labels map[string]string) (restartCount int, err e } return restartCount, err } + +func getTerminationMessagePathFromLabel(labels map[string]string) string { + if terminationMessagePath, found := labels[kubernetesContainerTerminationMessagePath]; found { + return terminationMessagePath + } else { + // Do not report error, because there should be many old containers without this label now. + // Return empty string "" for these containers, the caller will get terminationMessagePath by other ways. + glog.V(3).Infof("Container doesn't have label %s, it may be an old or invalid container", kubernetesContainerTerminationMessagePath) + return "" + } +} diff --git a/pkg/kubelet/dockertools/manager.go b/pkg/kubelet/dockertools/manager.go index 2004dcd5826..4304ec701a5 100644 --- a/pkg/kubelet/dockertools/manager.go +++ b/pkg/kubelet/dockertools/manager.go @@ -338,6 +338,7 @@ func (dm *DockerManager) determineContainerIP(podNamespace, podName string, cont return result } +// TODO (random-liu) Remove parameter tPath when old containers are deprecated. func (dm *DockerManager) inspectContainer(dockerID, containerName, tPath string, pod *api.Pod) *containerStatusResult { result := containerStatusResult{api.ContainerStatus{}, "", nil} @@ -408,8 +409,14 @@ func (dm *DockerManager) inspectContainer(dockerID, containerName, tPath string, FinishedAt: finishedAt, ContainerID: DockerPrefix + dockerID, } - if tPath != "" { - path, found := inspectResult.Volumes[tPath] + terminationMessagePath := getTerminationMessagePathFromLabel(inspectResult.Config.Labels) + if terminationMessagePath == "" { + // Because old containers have no terminationMessagePath Label, we stil have to rely on the information from apiserver here. + // TODO (random-liu) Remove this later when old containers with no labels are deprecated. + terminationMessagePath = tPath + } + if terminationMessagePath != "" { + path, found := inspectResult.Volumes[terminationMessagePath] if found { data, err := ioutil.ReadFile(path) if err != nil { diff --git a/pkg/kubelet/dockertools/manager_test.go b/pkg/kubelet/dockertools/manager_test.go index a10358e83ee..e9853f4e32e 100644 --- a/pkg/kubelet/dockertools/manager_test.go +++ b/pkg/kubelet/dockertools/manager_test.go @@ -1600,6 +1600,44 @@ func TestGetRestartCount(t *testing.T) { pod.Status = verifyRestartCount(&pod, 4) } +func TestGetTerminationMessagePath(t *testing.T) { + dm, fakeDocker := newTestDockerManager() + containers := []api.Container{ + { + Name: "bar", + TerminationMessagePath: "/dev/somepath", + }, + } + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + UID: "12345678", + Name: "foo", + Namespace: "new", + }, + Spec: api.PodSpec{ + Containers: containers, + }, + } + + fakeDocker.ContainerMap = map[string]*docker.Container{} + + runSyncPod(t, dm, fakeDocker, pod, nil) + + containerList := fakeDocker.ContainerList + if len(containerList) != 2 { + // One for infra container, one for container "bar" + t.Fatalf("unexpected container list length %d", len(containerList)) + } + inspectResult, err := dm.client.InspectContainer(containerList[0].ID) + if err != nil { + t.Fatalf("unexpected inspect error %v", err) + } + terminationMessagePath := getTerminationMessagePathFromLabel(inspectResult.Config.Labels) + if terminationMessagePath != containers[0].TerminationMessagePath { + t.Errorf("expected termination message path %s, got %s", containers[0].TerminationMessagePath, terminationMessagePath) + } +} + func TestSyncPodWithPodInfraCreatesContainerCallsHandler(t *testing.T) { fakeHTTPClient := &fakeHTTP{} dm, fakeDocker := newTestDockerManagerWithHTTPClient(fakeHTTPClient)