diff --git a/discovery/kubernetes/pod.go b/discovery/kubernetes/pod.go index 2e3687a06..396720c22 100644 --- a/discovery/kubernetes/pod.go +++ b/discovery/kubernetes/pod.go @@ -183,6 +183,7 @@ const ( podNameLabel = metaLabelPrefix + "pod_name" podIPLabel = metaLabelPrefix + "pod_ip" podContainerNameLabel = metaLabelPrefix + "pod_container_name" + podContainerIDLabel = metaLabelPrefix + "pod_container_id" podContainerImageLabel = metaLabelPrefix + "pod_container_image" podContainerPortNameLabel = metaLabelPrefix + "pod_container_port_name" podContainerPortNumberLabel = metaLabelPrefix + "pod_container_port_number" @@ -248,6 +249,24 @@ func podLabels(pod *apiv1.Pod) model.LabelSet { return ls } +func (p *Pod) findPodContainerStatus(statuses *[]apiv1.ContainerStatus, containerName string) (*apiv1.ContainerStatus, error) { + for _, s := range *statuses { + if s.Name == containerName { + return &s, nil + } + } + return nil, fmt.Errorf("cannot find container with name %v", containerName) +} + +func (p *Pod) findPodContainerID(statuses *[]apiv1.ContainerStatus, containerName string) string { + cStatus, err := p.findPodContainerStatus(statuses, containerName) + if err != nil { + level.Debug(p.logger).Log("msg", "cannot find container ID", "err", err) + return "" + } + return cStatus.ContainerID +} + func (p *Pod) buildPod(pod *apiv1.Pod) *targetgroup.Group { tg := &targetgroup.Group{ Source: podSource(pod), @@ -267,6 +286,12 @@ func (p *Pod) buildPod(pod *apiv1.Pod) *targetgroup.Group { for i, c := range containers { isInit := i >= len(pod.Spec.Containers) + cStatuses := &pod.Status.ContainerStatuses + if isInit { + cStatuses = &pod.Status.InitContainerStatuses + } + cID := p.findPodContainerID(cStatuses, c.Name) + // If no ports are defined for the container, create an anonymous // target per container. if len(c.Ports) == 0 { @@ -275,6 +300,7 @@ func (p *Pod) buildPod(pod *apiv1.Pod) *targetgroup.Group { tg.Targets = append(tg.Targets, model.LabelSet{ model.AddressLabel: lv(pod.Status.PodIP), podContainerNameLabel: lv(c.Name), + podContainerIDLabel: lv(cID), podContainerImageLabel: lv(c.Image), podContainerIsInit: lv(strconv.FormatBool(isInit)), }) @@ -288,6 +314,7 @@ func (p *Pod) buildPod(pod *apiv1.Pod) *targetgroup.Group { tg.Targets = append(tg.Targets, model.LabelSet{ model.AddressLabel: lv(addr), podContainerNameLabel: lv(c.Name), + podContainerIDLabel: lv(cID), podContainerImageLabel: lv(c.Image), podContainerPortNumberLabel: lv(ports), podContainerPortNameLabel: lv(port.Name), diff --git a/discovery/kubernetes/pod_test.go b/discovery/kubernetes/pod_test.go index f2b79dbb8..286a1a230 100644 --- a/discovery/kubernetes/pod_test.go +++ b/discovery/kubernetes/pod_test.go @@ -81,6 +81,16 @@ func makeMultiPortPods() *v1.Pod { Status: v1.ConditionTrue, }, }, + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "testcontainer0", + ContainerID: "docker://a1b2c3d4e5f6", + }, + { + Name: "testcontainer1", + ContainerID: "containerd://6f5e4d3c2b1a", + }, + }, }, } } @@ -118,6 +128,12 @@ func makePods() *v1.Pod { Status: v1.ConditionTrue, }, }, + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "testcontainer", + ContainerID: "docker://a1b2c3d4e5f6", + }, + }, }, } } @@ -162,6 +178,18 @@ func makeInitContainerPods() *v1.Pod { Status: v1.ConditionFalse, }, }, + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "testcontainer", + ContainerID: "docker://a1b2c3d4e5f6", + }, + }, + InitContainerStatuses: []v1.ContainerStatus{ + { + Name: "initcontainer", + ContainerID: "containerd://6f5e4d3c2b1a", + }, + }, }, } } @@ -179,6 +207,7 @@ func expectedPodTargetGroups(ns string) map[string]*targetgroup.Group { "__meta_kubernetes_pod_container_port_number": "9000", "__meta_kubernetes_pod_container_port_protocol": "TCP", "__meta_kubernetes_pod_container_init": "false", + "__meta_kubernetes_pod_container_id": "docker://a1b2c3d4e5f6", }, }, Labels: model.LabelSet{ @@ -230,6 +259,7 @@ func TestPodDiscoveryBeforeRun(t *testing.T) { "__meta_kubernetes_pod_container_port_number": "9000", "__meta_kubernetes_pod_container_port_protocol": "TCP", "__meta_kubernetes_pod_container_init": "false", + "__meta_kubernetes_pod_container_id": "docker://a1b2c3d4e5f6", }, { "__address__": "1.2.3.4:9001", @@ -239,12 +269,14 @@ func TestPodDiscoveryBeforeRun(t *testing.T) { "__meta_kubernetes_pod_container_port_number": "9001", "__meta_kubernetes_pod_container_port_protocol": "UDP", "__meta_kubernetes_pod_container_init": "false", + "__meta_kubernetes_pod_container_id": "docker://a1b2c3d4e5f6", }, { "__address__": "1.2.3.4", "__meta_kubernetes_pod_container_name": "testcontainer1", "__meta_kubernetes_pod_container_image": "testcontainer1:latest", "__meta_kubernetes_pod_container_init": "false", + "__meta_kubernetes_pod_container_id": "containerd://6f5e4d3c2b1a", }, }, Labels: model.LabelSet{ @@ -280,6 +312,7 @@ func TestPodDiscoveryInitContainer(t *testing.T) { "__meta_kubernetes_pod_container_name": "initcontainer", "__meta_kubernetes_pod_container_image": "initcontainer:latest", "__meta_kubernetes_pod_container_init": "true", + "__meta_kubernetes_pod_container_id": "containerd://6f5e4d3c2b1a", }) expected[key].Labels["__meta_kubernetes_pod_phase"] = "Pending" expected[key].Labels["__meta_kubernetes_pod_ready"] = "false"