From a3e9628e0c9968d5f82924469fa10e02d29f529d Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 6 Dec 2021 22:27:11 +0100 Subject: [PATCH] Kubernetes service discovery: add provider ID label (#9603) When using Kubernetes on cloud providers, nodes will have the spec.providerID field populated to contain the cloud provider specific name of the EC2/GCE/... instance. Let's expose this information as an additional label, so that it's easier to annotate metrics and alerts to contain the cloud provider specific name of the instance to which it pertains. Signed-off-by: Ed Schouten --- discovery/kubernetes/node.go | 2 ++ discovery/kubernetes/node_test.go | 14 +++++++++++--- docs/configuration/configuration.md | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/discovery/kubernetes/node.go b/discovery/kubernetes/node.go index 668686fbab..13ead15523 100644 --- a/discovery/kubernetes/node.go +++ b/discovery/kubernetes/node.go @@ -149,6 +149,7 @@ func nodeSourceFromName(name string) string { const ( nodeNameLabel = metaLabelPrefix + "node_name" + nodeProviderIDLabel = metaLabelPrefix + "node_provider_id" nodeLabelPrefix = metaLabelPrefix + "node_label_" nodeLabelPresentPrefix = metaLabelPrefix + "node_labelpresent_" nodeAnnotationPrefix = metaLabelPrefix + "node_annotation_" @@ -161,6 +162,7 @@ func nodeLabels(n *apiv1.Node) model.LabelSet { ls := make(model.LabelSet, 2*(len(n.Labels)+len(n.Annotations))+1) ls[nodeNameLabel] = lv(n.Name) + ls[nodeProviderIDLabel] = lv(n.Spec.ProviderID) for k, v := range n.Labels { ln := strutil.SanitizeLabelName(k) diff --git a/discovery/kubernetes/node_test.go b/discovery/kubernetes/node_test.go index afdaaf6b2b..bbf7a6b27c 100644 --- a/discovery/kubernetes/node_test.go +++ b/discovery/kubernetes/node_test.go @@ -25,13 +25,16 @@ import ( "github.com/prometheus/prometheus/discovery/targetgroup" ) -func makeNode(name, address string, labels, annotations map[string]string) *v1.Node { +func makeNode(name, address, providerID string, labels, annotations map[string]string) *v1.Node { return &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: name, Labels: labels, Annotations: annotations, }, + Spec: v1.NodeSpec{ + ProviderID: providerID, + }, Status: v1.NodeStatus{ Addresses: []v1.NodeAddress{ { @@ -49,7 +52,7 @@ func makeNode(name, address string, labels, annotations map[string]string) *v1.N } func makeEnumeratedNode(i int) *v1.Node { - return makeNode(fmt.Sprintf("test%d", i), "1.2.3.4", map[string]string{}, map[string]string{}) + return makeNode(fmt.Sprintf("test%d", i), "1.2.3.4", fmt.Sprintf("aws:///de-west-3a/i-%d", i), map[string]string{}, map[string]string{}) } func TestNodeDiscoveryBeforeStart(t *testing.T) { @@ -61,6 +64,7 @@ func TestNodeDiscoveryBeforeStart(t *testing.T) { obj := makeNode( "test", "1.2.3.4", + "aws:///nl-north-7b/i-03149834983492827", map[string]string{"test-label": "testvalue"}, map[string]string{"test-annotation": "testannotationvalue"}, ) @@ -78,6 +82,7 @@ func TestNodeDiscoveryBeforeStart(t *testing.T) { }, Labels: model.LabelSet{ "__meta_kubernetes_node_name": "test", + "__meta_kubernetes_node_provider_id": "aws:///nl-north-7b/i-03149834983492827", "__meta_kubernetes_node_label_test_label": "testvalue", "__meta_kubernetes_node_labelpresent_test_label": "true", "__meta_kubernetes_node_annotation_test_annotation": "testannotationvalue", @@ -109,7 +114,8 @@ func TestNodeDiscoveryAdd(t *testing.T) { }, }, Labels: model.LabelSet{ - "__meta_kubernetes_node_name": "test1", + "__meta_kubernetes_node_name": "test1", + "__meta_kubernetes_node_provider_id": "aws:///de-west-3a/i-1", }, Source: "node/test1", }, @@ -146,6 +152,7 @@ func TestNodeDiscoveryUpdate(t *testing.T) { obj2 := makeNode( "test0", "1.2.3.4", + "aws:///fr-south-1c/i-49508290343823952", map[string]string{"Unschedulable": "true"}, map[string]string{}, ) @@ -165,6 +172,7 @@ func TestNodeDiscoveryUpdate(t *testing.T) { "__meta_kubernetes_node_label_Unschedulable": "true", "__meta_kubernetes_node_labelpresent_Unschedulable": "true", "__meta_kubernetes_node_name": "test0", + "__meta_kubernetes_node_provider_id": "aws:///fr-south-1c/i-49508290343823952", }, Source: "node/test0", }, diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index 9b1d1266e4..e27c607b26 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -1513,6 +1513,7 @@ node object in the address type order of `NodeInternalIP`, `NodeExternalIP`, Available meta labels: * `__meta_kubernetes_node_name`: The name of the node object. +* `__meta_kubernetes_node_provider_id`: The cloud provider's name for the node object. * `__meta_kubernetes_node_label_`: Each label from the node object. * `__meta_kubernetes_node_labelpresent_`: `true` for each label from the node object. * `__meta_kubernetes_node_annotation_`: Each annotation from the node object.