diff --git a/docs/service-metrics.md b/docs/service-metrics.md
index 80207584c6..e4619869c6 100644
--- a/docs/service-metrics.md
+++ b/docs/service-metrics.md
@@ -2,10 +2,10 @@
| Metric name| Metric type | Description | Unit (where applicable) | Labels/tags | Status |
| ---------- | ----------- | ----------- | ----------------------- | ----------- | ------ |
-| kube_service_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`annotation_SERVICE_ANNOTATION`=<SERVICE_ANNOTATION> | EXPERIMENTAL |
-| kube_service_info | Gauge | Information about service | |`service`=<service-name>
`namespace`=<service-namespace>
`cluster_ip`=<service cluster ip>
`external_name`=<service external name>
`load_balancer_ip`=<service load balancer ip> | STABLE |
-| kube_service_labels | Gauge | Kubernetes labels converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`label_SERVICE_LABEL`=<SERVICE_LABEL> | STABLE |
-| kube_service_created | Gauge | Unix creation timestamp | seconds |`service`=<service-name>
`namespace`=<service-namespace> | STABLE |
-| kube_service_spec_type | Gauge | Type about service | |`service`=<service-name>
`namespace`=<service-namespace>
`type`=<ClusterIP\|NodePort\|LoadBalancer\|ExternalName> | STABLE |
-| kube_service_spec_external_ip | Gauge | Service external ips. One series for each ip | |`service`=<service-name>
`namespace`=<service-namespace>
`external_ip`=<external-ip> | STABLE |
-| kube_service_status_load_balancer_ingress | Gauge | Service load balancer ingress status | |`service`=<service-name>
`namespace`=<service-namespace>
`ip`=<load-balancer-ingress-ip>
`hostname`=<load-balancer-ingress-hostname> | STABLE |
+| kube_service_annotations | Gauge | Kubernetes annotations converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`annotation_SERVICE_ANNOTATION`=<SERVICE_ANNOTATION> | EXPERIMENTAL |
+| kube_service_info | Gauge | Information about service | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`cluster_ip`=<service cluster ip>
`external_name`=<service external name>
`load_balancer_ip`=<service load balancer ip> | STABLE |
+| kube_service_labels | Gauge | Kubernetes labels converted to Prometheus labels | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`label_SERVICE_LABEL`=<SERVICE_LABEL> | STABLE |
+| kube_service_created | Gauge | Unix creation timestamp | seconds |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid> | STABLE |
+| kube_service_spec_type | Gauge | Type about service | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`type`=<ClusterIP\|NodePort\|LoadBalancer\|ExternalName> | STABLE |
+| kube_service_spec_external_ip | Gauge | Service external ips. One series for each ip | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`external_ip`=<external-ip> | STABLE |
+| kube_service_status_load_balancer_ingress | Gauge | Service load balancer ingress status | |`service`=<service-name>
`namespace`=<service-namespace>
`uid`=<service-uid>
`ip`=<load-balancer-ingress-ip>
`hostname`=<load-balancer-ingress-hostname> | STABLE |
diff --git a/internal/store/service.go b/internal/store/service.go
index 7834c57ff8..549badeaaf 100644
--- a/internal/store/service.go
+++ b/internal/store/service.go
@@ -35,7 +35,7 @@ var (
descServiceAnnotationsHelp = "Kubernetes annotations converted to Prometheus labels."
descServiceLabelsName = "kube_service_labels"
descServiceLabelsHelp = "Kubernetes labels converted to Prometheus labels."
- descServiceLabelsDefaultLabels = []string{"namespace", "service"}
+ descServiceLabelsDefaultLabels = []string{"namespace", "service", "uid"}
)
func serviceMetricFamilies(allowAnnotationsList, allowLabelsList []string) []generator.FamilyGenerator {
@@ -180,7 +180,7 @@ func wrapSvcFunc(f func(*v1.Service) *metric.Family) func(interface{}) *metric.F
metricFamily := f(svc)
for _, m := range metricFamily.Metrics {
- m.LabelKeys, m.LabelValues = mergeKeyValues(descServiceLabelsDefaultLabels, []string{svc.Namespace, svc.Name}, m.LabelKeys, m.LabelValues)
+ m.LabelKeys, m.LabelValues = mergeKeyValues(descServiceLabelsDefaultLabels, []string{svc.Namespace, svc.Name, string(svc.UID)}, m.LabelKeys, m.LabelValues)
}
return metricFamily
diff --git a/internal/store/service_test.go b/internal/store/service_test.go
index d6f0c1838f..aa3ff17201 100644
--- a/internal/store/service_test.go
+++ b/internal/store/service_test.go
@@ -52,6 +52,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service1",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid1",
Labels: map[string]string{
"app": "example1",
},
@@ -72,11 +73,11 @@ func TestServiceStore(t *testing.T) {
# TYPE kube_service_info gauge
# TYPE kube_service_labels gauge
# TYPE kube_service_spec_type gauge
- kube_service_annotations{namespace="default",service="test-service1"} 1
- kube_service_created{namespace="default",service="test-service1"} 1.5e+09
- kube_service_info{cluster_ip="1.2.3.4",external_name="",load_balancer_ip="",namespace="default",service="test-service1"} 1
- kube_service_labels{namespace="default",service="test-service1"} 1
- kube_service_spec_type{namespace="default",service="test-service1",type="ClusterIP"} 1
+ kube_service_annotations{namespace="default",service="test-service1",uid="uid1"} 1
+ kube_service_created{namespace="default",service="test-service1",uid="uid1"} 1.5e+09
+ kube_service_info{cluster_ip="1.2.3.4",external_name="",load_balancer_ip="",namespace="default",service="test-service1",uid="uid1"} 1
+ kube_service_labels{namespace="default",service="test-service1",uid="uid1"} 1
+ kube_service_spec_type{namespace="default",service="test-service1",type="ClusterIP",uid="uid1"} 1
`,
MetricNames: []string{
"kube_service_annotations",
@@ -93,6 +94,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service2",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid2",
Labels: map[string]string{
"app": "example2",
},
@@ -103,11 +105,11 @@ func TestServiceStore(t *testing.T) {
},
},
Want: metadata + `
- kube_service_annotations{namespace="default",service="test-service2"} 1
- kube_service_created{namespace="default",service="test-service2"} 1.5e+09
- kube_service_info{cluster_ip="1.2.3.5",external_name="",load_balancer_ip="",namespace="default",service="test-service2"} 1
- kube_service_labels{namespace="default",service="test-service2"} 1
- kube_service_spec_type{namespace="default",service="test-service2",type="NodePort"} 1
+ kube_service_annotations{namespace="default",service="test-service2",uid="uid2"} 1
+ kube_service_created{namespace="default",service="test-service2",uid="uid2"} 1.5e+09
+ kube_service_info{cluster_ip="1.2.3.5",external_name="",load_balancer_ip="",namespace="default",service="test-service2",uid="uid2"} 1
+ kube_service_labels{namespace="default",service="test-service2",uid="uid2"} 1
+ kube_service_spec_type{namespace="default",service="test-service2",uid="uid2",type="NodePort"} 1
`,
},
{
@@ -116,6 +118,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service3",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid3",
Labels: map[string]string{
"app": "example3",
},
@@ -127,11 +130,11 @@ func TestServiceStore(t *testing.T) {
},
},
Want: metadata + `
- kube_service_annotations{namespace="default",service="test-service3"} 1
- kube_service_created{namespace="default",service="test-service3"} 1.5e+09
- kube_service_info{cluster_ip="1.2.3.6",external_name="",load_balancer_ip="1.2.3.7",namespace="default",service="test-service3"} 1
- kube_service_labels{namespace="default",service="test-service3"} 1
- kube_service_spec_type{namespace="default",service="test-service3",type="LoadBalancer"} 1
+ kube_service_annotations{namespace="default",service="test-service3",uid="uid3"} 1
+ kube_service_created{namespace="default",service="test-service3",uid="uid3"} 1.5e+09
+ kube_service_info{cluster_ip="1.2.3.6",external_name="",load_balancer_ip="1.2.3.7",namespace="default",service="test-service3",uid="uid3"} 1
+ kube_service_labels{namespace="default",service="test-service3",uid="uid3"} 1
+ kube_service_spec_type{namespace="default",service="test-service3",type="LoadBalancer",uid="uid3"} 1
`,
},
{
@@ -140,6 +143,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service4",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid4",
Labels: map[string]string{
"app": "example4",
},
@@ -150,11 +154,11 @@ func TestServiceStore(t *testing.T) {
},
},
Want: metadata + `
- kube_service_annotations{namespace="default",service="test-service4"} 1
- kube_service_created{namespace="default",service="test-service4"} 1.5e+09
- kube_service_info{cluster_ip="",external_name="www.example.com",load_balancer_ip="",namespace="default",service="test-service4"} 1
- kube_service_labels{namespace="default",service="test-service4"} 1
- kube_service_spec_type{namespace="default",service="test-service4",type="ExternalName"} 1
+ kube_service_annotations{namespace="default",service="test-service4",uid="uid4"} 1
+ kube_service_created{namespace="default",service="test-service4",uid="uid4"} 1.5e+09
+ kube_service_info{cluster_ip="",external_name="www.example.com",load_balancer_ip="",namespace="default",service="test-service4",uid="uid4"} 1
+ kube_service_labels{namespace="default",service="test-service4",uid="uid4"} 1
+ kube_service_spec_type{namespace="default",service="test-service4",uid="uid4",type="ExternalName"} 1
`,
},
{
@@ -163,6 +167,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service5",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid5",
Labels: map[string]string{
"app": "example5",
},
@@ -182,12 +187,12 @@ func TestServiceStore(t *testing.T) {
},
},
Want: metadata + `
- kube_service_annotations{namespace="default",service="test-service5"} 1
- kube_service_created{namespace="default",service="test-service5"} 1.5e+09
- kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service5"} 1
- kube_service_labels{namespace="default",service="test-service5"} 1
- kube_service_spec_type{namespace="default",service="test-service5",type="LoadBalancer"} 1
- kube_service_status_load_balancer_ingress{hostname="www.example.com",ip="1.2.3.8",namespace="default",service="test-service5"} 1
+ kube_service_annotations{namespace="default",service="test-service5",uid="uid5"} 1
+ kube_service_created{namespace="default",service="test-service5",uid="uid5"} 1.5e+09
+ kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service5",uid="uid5"} 1
+ kube_service_labels{namespace="default",service="test-service5",uid="uid5"} 1
+ kube_service_spec_type{namespace="default",service="test-service5",type="LoadBalancer",uid="uid5"} 1
+ kube_service_status_load_balancer_ingress{hostname="www.example.com",ip="1.2.3.8",namespace="default",service="test-service5",uid="uid5"} 1
`,
},
{
@@ -196,6 +201,7 @@ func TestServiceStore(t *testing.T) {
Name: "test-service6",
CreationTimestamp: metav1.Time{Time: time.Unix(1500000000, 0)},
Namespace: "default",
+ UID: "uid6",
Labels: map[string]string{
"app": "example6",
},
@@ -209,13 +215,13 @@ func TestServiceStore(t *testing.T) {
},
},
Want: metadata + `
- kube_service_annotations{namespace="default",service="test-service6"} 1
- kube_service_created{namespace="default",service="test-service6"} 1.5e+09
- kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service6"} 1
- kube_service_labels{namespace="default",service="test-service6"} 1
- kube_service_spec_type{namespace="default",service="test-service6",type="ClusterIP"} 1
- kube_service_spec_external_ip{external_ip="1.2.3.9",namespace="default",service="test-service6"} 1
- kube_service_spec_external_ip{external_ip="1.2.3.10",namespace="default",service="test-service6"} 1
+ kube_service_annotations{namespace="default",service="test-service6",uid="uid6"} 1
+ kube_service_created{namespace="default",service="test-service6",uid="uid6"} 1.5e+09
+ kube_service_info{cluster_ip="",external_name="",load_balancer_ip="",namespace="default",service="test-service6",uid="uid6"} 1
+ kube_service_labels{namespace="default",service="test-service6",uid="uid6"} 1
+ kube_service_spec_type{namespace="default",service="test-service6",uid="uid6",type="ClusterIP"} 1
+ kube_service_spec_external_ip{external_ip="1.2.3.9",namespace="default",service="test-service6",uid="uid6"} 1
+ kube_service_spec_external_ip{external_ip="1.2.3.10",namespace="default",service="test-service6",uid="uid6"} 1
`,
},
}