diff --git a/pkg/kubelet/cadvisor/cadvisor_linux.go b/pkg/kubelet/cadvisor/cadvisor_linux.go index c7b381700a4..853e0d5d566 100644 --- a/pkg/kubelet/cadvisor/cadvisor_linux.go +++ b/pkg/kubelet/cadvisor/cadvisor_linux.go @@ -33,7 +33,9 @@ import ( cadvisorapi "github.com/google/cadvisor/info/v1" cadvisorapiv2 "github.com/google/cadvisor/info/v2" "github.com/google/cadvisor/manager" + "github.com/google/cadvisor/metrics" "github.com/google/cadvisor/utils/sysfs" + "k8s.io/kubernetes/pkg/kubelet/types" "k8s.io/kubernetes/pkg/util/runtime" ) @@ -70,7 +72,27 @@ func init() { } } -// Creates a cAdvisor and exports its API on the specified port if port > 0. +func containerLabels(c *cadvisorapi.ContainerInfo) map[string]string { + set := map[string]string{metrics.LabelID: c.Name} + if len(c.Aliases) > 0 { + set[metrics.LabelName] = c.Aliases[0] + } + if image := c.Spec.Image; len(image) > 0 { + set[metrics.LabelImage] = image + } + if v, ok := c.Spec.Labels[types.KubernetesPodNameLabel]; ok { + set["pod_name"] = v + } + if v, ok := c.Spec.Labels[types.KubernetesPodNamespaceLabel]; ok { + set["namespace"] = v + } + if v, ok := c.Spec.Labels[types.KubernetesContainerNameLabel]; ok { + set["container_name"] = v + } + return set +} + +// New creates a cAdvisor and exports its API on the specified port if port > 0. func New(port uint, runtime string) (Interface, error) { sysFs, err := sysfs.NewRealSysFs() if err != nil { @@ -108,7 +130,7 @@ func (cc *cadvisorClient) exportHTTP(port uint) error { return err } - cadvisorhttp.RegisterPrometheusHandler(mux, cc, "/metrics", nil) + cadvisorhttp.RegisterPrometheusHandler(mux, cc, "/metrics", containerLabels) // Only start the http server if port > 0 if port > 0 { diff --git a/pkg/kubelet/cadvisor/cadvisor_linux_test.go b/pkg/kubelet/cadvisor/cadvisor_linux_test.go new file mode 100644 index 00000000000..48f06e026c1 --- /dev/null +++ b/pkg/kubelet/cadvisor/cadvisor_linux_test.go @@ -0,0 +1,65 @@ +// +build cgo,linux + +/* +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 cadvisor + +import ( + "reflect" + "testing" + + info "github.com/google/cadvisor/info/v1" + "github.com/google/cadvisor/metrics" + "k8s.io/kubernetes/pkg/kubelet/types" +) + +func TestContainerLabels(t *testing.T) { + container := &info.ContainerInfo{ + ContainerReference: info.ContainerReference{ + Name: "/docker/f81ad5335d390944e454ea19ab0924037d57337c19731524ad96eb26e74b6c6d", + Aliases: []string{"k8s_POD.639b2af2_foo-web-315473031-e40e2_foobar_a369ace2-5fa9-11e6-b10f-c81f66e5e84d_851a97fd"}, + }, + Spec: info.ContainerSpec{ + Image: "qux/foo:latest", + Labels: map[string]string{ + "io.kubernetes.container.hash": "639b2af2", + types.KubernetesContainerNameLabel: "POD", + "io.kubernetes.container.restartCount": "0", + "io.kubernetes.container.terminationMessagePath": "", + types.KubernetesPodNameLabel: "foo-web-315473031-e40e2", + types.KubernetesPodNamespaceLabel: "foobar", + "io.kubernetes.pod.terminationGracePeriod": "30", + types.KubernetesPodUIDLabel: "a369ace2-5fa9-11e6-b10f-c81f66e5e84d", + }, + Envs: map[string]string{ + "foo+env": "prod", + }, + }, + } + want := map[string]string{ + metrics.LabelID: "/docker/f81ad5335d390944e454ea19ab0924037d57337c19731524ad96eb26e74b6c6d", + metrics.LabelName: "k8s_POD.639b2af2_foo-web-315473031-e40e2_foobar_a369ace2-5fa9-11e6-b10f-c81f66e5e84d_851a97fd", + metrics.LabelImage: "qux/foo:latest", + "namespace": "foobar", + "container_name": "POD", + "pod_name": "foo-web-315473031-e40e2", + } + + if have := containerLabels(container); !reflect.DeepEqual(want, have) { + t.Errorf("want %v, have %v", want, have) + } +}