Explorar el Código

Add the remaining KSM metrics, clean some of the existing metric definitions.

Matt Bolt hace 4 años
padre
commit
3759278c44
Se han modificado 4 ficheros con 546 adiciones y 89 borrados
  1. 133 3
      pkg/metrics/deploymentmetrics.go
  2. 3 0
      pkg/metrics/kubemetrics.go
  3. 222 69
      pkg/metrics/nodemetrics.go
  4. 188 17
      pkg/metrics/podmetrics.go

+ 133 - 3
pkg/metrics/deploymentmetrics.go

@@ -114,12 +114,142 @@ type KubeDeploymentCollector struct {
 // Describe sends the super-set of all possible descriptors of metrics
 // Describe sends the super-set of all possible descriptors of metrics
 // collected by this Collector.
 // collected by this Collector.
 func (kdc KubeDeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
 func (kdc KubeDeploymentCollector) Describe(ch chan<- *prometheus.Desc) {
-	// kube_deployment_status_replicas_available
-	// kube_deployment_spec_replicas
-	// kube_deployment_status_replicas_available
+	ch <- prometheus.NewDesc("kube_deployment_spec_replicas", "Number of desired pods for a deployment.", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_deployment_status_replicas_available", "The number of available replicas per deployment.", []string{}, nil)
+
 }
 }
 
 
 // Collect is called by the Prometheus registry when collecting metrics.
 // Collect is called by the Prometheus registry when collecting metrics.
 func (kdc KubeDeploymentCollector) Collect(ch chan<- prometheus.Metric) {
 func (kdc KubeDeploymentCollector) Collect(ch chan<- prometheus.Metric) {
+	deployments := kdc.KubeClusterCache.GetAllDeployments()
+
+	for _, deployment := range deployments {
+		deploymentName := deployment.GetName()
+		deploymentNS := deployment.GetNamespace()
+
+		// Replicas Defined
+		var replicas int32
+		if deployment.Spec.Replicas == nil {
+			replicas = 1 // defaults to 1, documented on the 'Replicas' field
+		} else {
+			replicas = *deployment.Spec.Replicas
+		}
+
+		ch <- newKubeDeploymentReplicasMetric("kube_deployment_spec_replicas", deploymentName, deploymentNS, replicas)
+
+		// Replicas Available
+		ch <- newKubeDeploymentStatusAvailableReplicasMetric(
+			"kube_deployment_status_replicas_available",
+			deploymentName,
+			deploymentNS,
+			deployment.Status.AvailableReplicas)
+	}
+}
+
+//--------------------------------------------------------------------------
+//  KubeDeploymentReplicasMetric
+//--------------------------------------------------------------------------
+
+// KubeDeploymentReplicasMetric is a prometheus.Metric used to encode deployment match labels
+type KubeDeploymentReplicasMetric struct {
+	fqName     string
+	help       string
+	deployment string
+	namespace  string
+	replicas   float64
+}
+
+// Creates a new DeploymentMatchLabelsMetric, implementation of prometheus.Metric
+func newKubeDeploymentReplicasMetric(fqname, deployment, namespace string, replicas int32) KubeDeploymentReplicasMetric {
+	return KubeDeploymentReplicasMetric{
+		fqName:     fqname,
+		help:       "kube_deployment_spec_replicas Number of desired pods for a deployment.",
+		deployment: deployment,
+		namespace:  namespace,
+		replicas:   float64(replicas),
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kdr KubeDeploymentReplicasMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"deployment": kdr.deployment,
+		"namespace":  kdr.namespace,
+	}
+	return prometheus.NewDesc(kdr.fqName, kdr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data
+// transmission object.
+func (kdr KubeDeploymentReplicasMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kdr.replicas,
+	}
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("namespace"),
+			Value: &kdr.namespace,
+		},
+		{
+			Name:  toStringPtr("deployment"),
+			Value: &kdr.deployment,
+		},
+	}
+
+	return nil
+}
+
+//--------------------------------------------------------------------------
+//  KubeDeploymentStatusAvailableReplicasMetric
+//--------------------------------------------------------------------------
+
+// KubeDeploymentStatusAvailableReplicasMetric is a prometheus.Metric used to encode deployment match labels
+type KubeDeploymentStatusAvailableReplicasMetric struct {
+	fqName            string
+	help              string
+	deployment        string
+	namespace         string
+	replicasAvailable float64
+}
+
+// Creates a new DeploymentMatchLabelsMetric, implementation of prometheus.Metric
+func newKubeDeploymentStatusAvailableReplicasMetric(fqname, deployment, namespace string, replicasAvailable int32) KubeDeploymentStatusAvailableReplicasMetric {
+	return KubeDeploymentStatusAvailableReplicasMetric{
+		fqName:            fqname,
+		help:              "kube_deployment_status_replicas_available The number of available replicas per deployment.",
+		deployment:        deployment,
+		namespace:         namespace,
+		replicasAvailable: float64(replicasAvailable),
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kdr KubeDeploymentStatusAvailableReplicasMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"deployment": kdr.deployment,
+		"namespace":  kdr.namespace,
+	}
+	return prometheus.NewDesc(kdr.fqName, kdr.help, []string{}, l)
+}
 
 
+// Write encodes the Metric into a "Metric" Protocol Buffer data
+// transmission object.
+func (kdr KubeDeploymentStatusAvailableReplicasMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kdr.replicasAvailable,
+	}
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("namespace"),
+			Value: &kdr.namespace,
+		},
+		{
+			Name:  toStringPtr("deployment"),
+			Value: &kdr.deployment,
+		},
+	}
+
+	return nil
 }
 }

+ 3 - 0
pkg/metrics/kubemetrics.go

@@ -69,6 +69,9 @@ func InitKubeMetrics(clusterCache clustercache.ClusterCache, opts *KubeMetricsOp
 			prometheus.MustRegister(KubeNodeCollector{
 			prometheus.MustRegister(KubeNodeCollector{
 				KubeClusterCache: clusterCache,
 				KubeClusterCache: clusterCache,
 			})
 			})
+			prometheus.MustRegister(KubeDeploymentCollector{
+				KubeClusterCache: clusterCache,
+			})
 			prometheus.MustRegister(KubePodCollector{
 			prometheus.MustRegister(KubePodCollector{
 				KubeClusterCache:   clusterCache,
 				KubeClusterCache:   clusterCache,
 				emitPodAnnotations: opts.EmitPodAnnotations,
 				emitPodAnnotations: opts.EmitPodAnnotations,

+ 222 - 69
pkg/metrics/nodemetrics.go

@@ -27,11 +27,14 @@ type KubeNodeCollector struct {
 // Describe sends the super-set of all possible descriptors of metrics
 // Describe sends the super-set of all possible descriptors of metrics
 // collected by this Collector.
 // collected by this Collector.
 func (nsac KubeNodeCollector) Describe(ch chan<- *prometheus.Desc) {
 func (nsac KubeNodeCollector) Describe(ch chan<- *prometheus.Desc) {
+	ch <- prometheus.NewDesc("kube_node_status_capacity", "Node resource capacity.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_capacity_memory_bytes", "node capacity memory bytes", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_capacity_memory_bytes", "node capacity memory bytes", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_capacity_cpu_cores", "node capacity cpu cores", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_capacity_cpu_cores", "node capacity cpu cores", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_node_status_allocatable", "The allocatable for different resources of a node that are available for scheduling.", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_node_status_allocatable_cpu_cores", "The allocatable cpu cores.", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_node_status_allocatable_memory_bytes", "The allocatable memory in bytes.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_labels", "all labels for each node prefixed with label_", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_labels", "all labels for each node prefixed with label_", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_condition", "The condition of a cluster node.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_node_status_condition", "The condition of a cluster node.", []string{}, nil)
-	ch <- prometheus.NewDesc("kube_node_status_allocatable", "The allocatable for different resources of a node that are available for scheduling.", []string{}, nil)
 }
 }
 
 
 // Collect is called by the Prometheus registry when collecting metrics.
 // Collect is called by the Prometheus registry when collecting metrics.
@@ -40,18 +43,29 @@ func (nsac KubeNodeCollector) Collect(ch chan<- prometheus.Metric) {
 	for _, node := range nodes {
 	for _, node := range nodes {
 		nodeName := node.GetName()
 		nodeName := node.GetName()
 
 
-		// k8s.io/apimachinery/pkg/api/resource/amount.go and
-		// k8s.io/apimachinery/pkg/api/resource/quantity.go for
-		// details on the "amount" API. See
-		// https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-types
-		// for the units of memory and CPU.
-		memoryBytes := node.Status.Capacity.Memory().Value()
-		ch <- newKubeNodeStatusCapacityMemoryBytesMetric(nodeName, memoryBytes, "kube_node_status_capacity_memory_bytes", nil, nil)
+		// Node Capacity
+		for resourceName, quantity := range node.Status.Capacity {
+			resource, unit, value := toResourceUnitValue(resourceName, quantity)
+
+			// failed to parse the resource type
+			if resource == "" {
+				log.DedupedWarningf(5, "Failed to parse resource units and quantity for resource: %s", resourceName)
+				continue
+			}
+
+			// KSM v1 Emission
+			if resource == "cpu" {
+				ch <- newKubeNodeStatusCapacityCPUCoresMetric("kube_node_status_capacity_cpu_cores", nodeName, value)
+
+			}
+			if resource == "memory" {
+				ch <- newKubeNodeStatusCapacityMemoryBytesMetric("kube_node_status_capacity_memory_bytes", nodeName, value)
+			}
 
 
-		cpuCores := float64(node.Status.Capacity.Cpu().MilliValue()) / 1000
-		ch <- newKubeNodeStatusCapacityCPUCoresMetric(nodeName, cpuCores, "kube_node_status_capacity_cpu_cores", nil, nil)
+			ch <- newKubeNodeStatusCapacityMetric("kube_node_status_capacity", nodeName, resource, unit, value)
+		}
 
 
-		// allocatable resources
+		// Node Allocatable Resources
 		for resourceName, quantity := range node.Status.Allocatable {
 		for resourceName, quantity := range node.Status.Allocatable {
 			resource, unit, value := toResourceUnitValue(resourceName, quantity)
 			resource, unit, value := toResourceUnitValue(resourceName, quantity)
 
 
@@ -61,6 +75,15 @@ func (nsac KubeNodeCollector) Collect(ch chan<- prometheus.Metric) {
 				continue
 				continue
 			}
 			}
 
 
+			// KSM v1 Emission
+			if resource == "cpu" {
+				ch <- newKubeNodeStatusAllocatableCPUCoresMetric("kube_node_status_allocatable_cpu_cores", nodeName, value)
+
+			}
+			if resource == "memory" {
+				ch <- newKubeNodeStatusAllocatableMemoryBytesMetric("kube_node_status_allocatable_memory_bytes", nodeName, value)
+			}
+
 			ch <- newKubeNodeStatusAllocatableMetric("kube_node_status_allocatable", nodeName, resource, unit, value)
 			ch <- newKubeNodeStatusAllocatableMetric("kube_node_status_allocatable", nodeName, resource, unit, value)
 		}
 		}
 
 
@@ -81,6 +104,66 @@ func (nsac KubeNodeCollector) Collect(ch chan<- prometheus.Metric) {
 	}
 	}
 }
 }
 
 
+//--------------------------------------------------------------------------
+//  KubeNodeStatusCapacityMetric
+//--------------------------------------------------------------------------
+
+// KubeNodeStatusCapacityMetric is a prometheus.Metric
+type KubeNodeStatusCapacityMetric struct {
+	fqName   string
+	help     string
+	resource string
+	unit     string
+	node     string
+	value    float64
+}
+
+// Creates a new KubeNodeStatusCapacityMetric, implementation of prometheus.Metric
+func newKubeNodeStatusCapacityMetric(fqname, node, resource, unit string, value float64) KubeNodeStatusCapacityMetric {
+	return KubeNodeStatusCapacityMetric{
+		fqName:   fqname,
+		help:     "kube_node_status_capacity node capacity",
+		node:     node,
+		resource: resource,
+		unit:     unit,
+		value:    value,
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kpcrr KubeNodeStatusCapacityMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"node":     kpcrr.node,
+		"resource": kpcrr.resource,
+		"unit":     kpcrr.unit,
+	}
+	return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data transmission object.
+func (kpcrr KubeNodeStatusCapacityMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kpcrr.value,
+	}
+
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("node"),
+			Value: &kpcrr.node,
+		},
+		{
+			Name:  toStringPtr("resource"),
+			Value: &kpcrr.resource,
+		},
+		{
+			Name:  toStringPtr("unit"),
+			Value: &kpcrr.unit,
+		},
+	}
+	return nil
+}
+
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 //  KubeNodeStatusCapacityMemoryBytesMetric
 //  KubeNodeStatusCapacityMemoryBytesMetric
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
@@ -89,23 +172,19 @@ func (nsac KubeNodeCollector) Collect(ch chan<- prometheus.Metric) {
 // a duplicate of the deprecated kube-state-metrics metric
 // a duplicate of the deprecated kube-state-metrics metric
 // kube_node_status_capacity_memory_bytes
 // kube_node_status_capacity_memory_bytes
 type KubeNodeStatusCapacityMemoryBytesMetric struct {
 type KubeNodeStatusCapacityMemoryBytesMetric struct {
-	fqName      string
-	help        string
-	labelNames  []string
-	labelValues []string
-	bytes       int64
-	node        string
+	fqName string
+	help   string
+	bytes  float64
+	node   string
 }
 }
 
 
 // Creates a new KubeNodeStatusCapacityMemoryBytesMetric, implementation of prometheus.Metric
 // Creates a new KubeNodeStatusCapacityMemoryBytesMetric, implementation of prometheus.Metric
-func newKubeNodeStatusCapacityMemoryBytesMetric(node string, bytes int64, fqname string, labelNames []string, labelValues []string) KubeNodeStatusCapacityMemoryBytesMetric {
+func newKubeNodeStatusCapacityMemoryBytesMetric(fqname string, node string, bytes float64) KubeNodeStatusCapacityMemoryBytesMetric {
 	return KubeNodeStatusCapacityMemoryBytesMetric{
 	return KubeNodeStatusCapacityMemoryBytesMetric{
-		fqName:      fqname,
-		labelNames:  labelNames,
-		labelValues: labelValues,
-		help:        "kube_node_status_capacity_memory_bytes Node Capacity Memory Bytes",
-		bytes:       bytes,
-		node:        node,
+		fqName: fqname,
+		help:   "kube_node_status_capacity_memory_bytes Node Capacity Memory Bytes",
+		node:   node,
+		bytes:  bytes,
 	}
 	}
 }
 }
 
 
@@ -113,30 +192,21 @@ func newKubeNodeStatusCapacityMemoryBytesMetric(node string, bytes int64, fqname
 // returns the same descriptor throughout the lifetime of the Metric.
 // returns the same descriptor throughout the lifetime of the Metric.
 func (nam KubeNodeStatusCapacityMemoryBytesMetric) Desc() *prometheus.Desc {
 func (nam KubeNodeStatusCapacityMemoryBytesMetric) Desc() *prometheus.Desc {
 	l := prometheus.Labels{"node": nam.node}
 	l := prometheus.Labels{"node": nam.node}
-	return prometheus.NewDesc(nam.fqName, nam.help, nam.labelNames, l)
+	return prometheus.NewDesc(nam.fqName, nam.help, []string{}, l)
 }
 }
 
 
 // Write encodes the Metric into a "Metric" Protocol Buffer data
 // Write encodes the Metric into a "Metric" Protocol Buffer data
 // transmission object.
 // transmission object.
 func (nam KubeNodeStatusCapacityMemoryBytesMetric) Write(m *dto.Metric) error {
 func (nam KubeNodeStatusCapacityMemoryBytesMetric) Write(m *dto.Metric) error {
-	h := float64(nam.bytes)
 	m.Gauge = &dto.Gauge{
 	m.Gauge = &dto.Gauge{
-		Value: &h,
+		Value: &nam.bytes,
 	}
 	}
-
-	var labels []*dto.LabelPair
-	for i := range nam.labelNames {
-		labels = append(labels, &dto.LabelPair{
-			Name:  &nam.labelNames[i],
-			Value: &nam.labelValues[i],
-		})
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("node"),
+			Value: &nam.node,
+		},
 	}
 	}
-	n := "node"
-	labels = append(labels, &dto.LabelPair{
-		Name:  &n,
-		Value: &nam.node,
-	})
-	m.Label = labels
 	return nil
 	return nil
 }
 }
 
 
@@ -148,23 +218,19 @@ func (nam KubeNodeStatusCapacityMemoryBytesMetric) Write(m *dto.Metric) error {
 // a duplicate of the deprecated kube-state-metrics metric
 // a duplicate of the deprecated kube-state-metrics metric
 // kube_node_status_capacity_memory_bytes
 // kube_node_status_capacity_memory_bytes
 type KubeNodeStatusCapacityCPUCoresMetric struct {
 type KubeNodeStatusCapacityCPUCoresMetric struct {
-	fqName      string
-	help        string
-	labelNames  []string
-	labelValues []string
-	cores       float64
-	node        string
+	fqName string
+	help   string
+	cores  float64
+	node   string
 }
 }
 
 
 // Creates a new KubeNodeStatusCapacityCPUCoresMetric, implementation of prometheus.Metric
 // Creates a new KubeNodeStatusCapacityCPUCoresMetric, implementation of prometheus.Metric
-func newKubeNodeStatusCapacityCPUCoresMetric(node string, cores float64, fqname string, labelNames []string, labelValues []string) KubeNodeStatusCapacityCPUCoresMetric {
+func newKubeNodeStatusCapacityCPUCoresMetric(fqname string, node string, cores float64) KubeNodeStatusCapacityCPUCoresMetric {
 	return KubeNodeStatusCapacityCPUCoresMetric{
 	return KubeNodeStatusCapacityCPUCoresMetric{
-		fqName:      fqname,
-		labelNames:  labelNames,
-		labelValues: labelValues,
-		help:        "kube_node_status_capacity_cpu_cores Node Capacity CPU Cores",
-		cores:       cores,
-		node:        node,
+		fqName: fqname,
+		help:   "kube_node_status_capacity_cpu_cores Node Capacity CPU Cores",
+		cores:  cores,
+		node:   node,
 	}
 	}
 }
 }
 
 
@@ -172,30 +238,21 @@ func newKubeNodeStatusCapacityCPUCoresMetric(node string, cores float64, fqname
 // returns the same descriptor throughout the lifetime of the Metric.
 // returns the same descriptor throughout the lifetime of the Metric.
 func (nam KubeNodeStatusCapacityCPUCoresMetric) Desc() *prometheus.Desc {
 func (nam KubeNodeStatusCapacityCPUCoresMetric) Desc() *prometheus.Desc {
 	l := prometheus.Labels{"node": nam.node}
 	l := prometheus.Labels{"node": nam.node}
-	return prometheus.NewDesc(nam.fqName, nam.help, nam.labelNames, l)
+	return prometheus.NewDesc(nam.fqName, nam.help, []string{}, l)
 }
 }
 
 
 // Write encodes the Metric into a "Metric" Protocol Buffer data
 // Write encodes the Metric into a "Metric" Protocol Buffer data
 // transmission object.
 // transmission object.
 func (nam KubeNodeStatusCapacityCPUCoresMetric) Write(m *dto.Metric) error {
 func (nam KubeNodeStatusCapacityCPUCoresMetric) Write(m *dto.Metric) error {
-	h := nam.cores
 	m.Gauge = &dto.Gauge{
 	m.Gauge = &dto.Gauge{
-		Value: &h,
+		Value: &nam.cores,
 	}
 	}
-
-	var labels []*dto.LabelPair
-	for i := range nam.labelNames {
-		labels = append(labels, &dto.LabelPair{
-			Name:  &nam.labelNames[i],
-			Value: &nam.labelValues[i],
-		})
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("node"),
+			Value: &nam.node,
+		},
 	}
 	}
-	n := "node"
-	labels = append(labels, &dto.LabelPair{
-		Name:  &n,
-		Value: &nam.node,
-	})
-	m.Label = labels
 	return nil
 	return nil
 }
 }
 
 
@@ -403,3 +460,99 @@ func (kpcrr KubeNodeStatusAllocatableMetric) Write(m *dto.Metric) error {
 	}
 	}
 	return nil
 	return nil
 }
 }
+
+//--------------------------------------------------------------------------
+//  KubeNodeStatusAllocatableCPUCoresMetric
+//--------------------------------------------------------------------------
+
+// KubeNodeStatusAllocatableCPUCoresMetric is a prometheus.Metric
+type KubeNodeStatusAllocatableCPUCoresMetric struct {
+	fqName   string
+	help     string
+	resource string
+	unit     string
+	node     string
+	value    float64
+}
+
+// Creates a new KubeNodeStatusAllocatableCPUCoresMetric, implementation of prometheus.Metric
+func newKubeNodeStatusAllocatableCPUCoresMetric(fqname, node string, value float64) KubeNodeStatusAllocatableCPUCoresMetric {
+	return KubeNodeStatusAllocatableCPUCoresMetric{
+		fqName: fqname,
+		help:   "kube_node_status_allocatable_cpu_cores node allocatable cpu cores",
+		node:   node,
+		value:  value,
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kpcrr KubeNodeStatusAllocatableCPUCoresMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"node": kpcrr.node,
+	}
+	return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data transmission object.
+func (kpcrr KubeNodeStatusAllocatableCPUCoresMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kpcrr.value,
+	}
+
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("node"),
+			Value: &kpcrr.node,
+		},
+	}
+	return nil
+}
+
+//--------------------------------------------------------------------------
+//  KubeNodeStatusAllocatableMemoryBytesMetric
+//--------------------------------------------------------------------------
+
+// KubeNodeStatusAllocatableMemoryBytesMetric is a prometheus.Metric
+type KubeNodeStatusAllocatableMemoryBytesMetric struct {
+	fqName   string
+	help     string
+	resource string
+	unit     string
+	node     string
+	value    float64
+}
+
+// Creates a new KubeNodeStatusAllocatableMemoryBytesMetric, implementation of prometheus.Metric
+func newKubeNodeStatusAllocatableMemoryBytesMetric(fqname, node string, value float64) KubeNodeStatusAllocatableMemoryBytesMetric {
+	return KubeNodeStatusAllocatableMemoryBytesMetric{
+		fqName: fqname,
+		help:   "kube_node_status_allocatable_memory_bytes node allocatable memory in bytes",
+		node:   node,
+		value:  value,
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kpcrr KubeNodeStatusAllocatableMemoryBytesMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"node": kpcrr.node,
+	}
+	return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data transmission object.
+func (kpcrr KubeNodeStatusAllocatableMemoryBytesMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kpcrr.value,
+	}
+
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("node"),
+			Value: &kpcrr.node,
+		},
+	}
+	return nil
+}

+ 188 - 17
pkg/metrics/podmetrics.go

@@ -34,6 +34,8 @@ func (kpmc KubePodCollector) Describe(ch chan<- *prometheus.Desc) {
 	ch <- prometheus.NewDesc("kube_pod_container_status_restarts_total", "The number of container restarts per container.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_container_status_restarts_total", "The number of container restarts per container.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_container_resource_requests", "The number of requested resource by a container", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_container_resource_requests", "The number of requested resource by a container", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_container_resource_limits", "The number of requested limit resource by a container.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_container_resource_limits", "The number of requested limit resource by a container.", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_pod_container_resource_limits_cpu_cores", "The number of requested limit cpu core resource by a container.", []string{}, nil)
+	ch <- prometheus.NewDesc("kube_pod_container_resource_limits_memory_bytes", "The number of requested limit memory resource by a container.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_status_phase", "The pods current phase.", []string{}, nil)
 	ch <- prometheus.NewDesc("kube_pod_status_phase", "The pods current phase.", []string{}, nil)
 }
 }
 
 
@@ -134,6 +136,28 @@ func (kpmc KubePodCollector) Collect(ch chan<- prometheus.Metric) {
 					continue
 					continue
 				}
 				}
 
 
+				// KSM v1 Emission
+				if resource == "cpu" {
+					ch <- newKubePodContainerResourceLimitsCPUCoresMetric(
+						"kube_pod_container_resource_limits_cpu_cores",
+						podName,
+						podNS,
+						podUID,
+						container.Name,
+						node,
+						value)
+				}
+				if resource == "memory" {
+					ch <- newKubePodContainerResourceLimitsMemoryBytesMetric(
+						"kube_pod_container_resource_limits_memory_bytes",
+						podName,
+						podNS,
+						podUID,
+						container.Name,
+						node,
+						value)
+				}
+
 				ch <- newKubePodContainerResourceLimitsMetric(
 				ch <- newKubePodContainerResourceLimitsMetric(
 					"kube_pod_container_resource_limits",
 					"kube_pod_container_resource_limits",
 					podName,
 					podName,
@@ -197,16 +221,15 @@ func (pam PodAnnotationsMetric) Write(m *dto.Metric) error {
 			Value: &pam.labelValues[i],
 			Value: &pam.labelValues[i],
 		})
 		})
 	}
 	}
-	n := "namespace"
-	labels = append(labels, &dto.LabelPair{
-		Name:  &n,
-		Value: &pam.namespace,
-	})
-	r := "pod"
-	labels = append(labels, &dto.LabelPair{
-		Name:  &r,
-		Value: &pam.name,
-	})
+	labels = append(labels,
+		&dto.LabelPair{
+			Name:  toStringPtr("namespace"),
+			Value: &pam.namespace,
+		},
+		&dto.LabelPair{
+			Name:  toStringPtr("pod"),
+			Value: &pam.name,
+		})
 	m.Label = labels
 	m.Label = labels
 	return nil
 	return nil
 }
 }
@@ -268,19 +291,17 @@ func (nam KubePodLabelsMetric) Write(m *dto.Metric) error {
 		})
 		})
 	}
 	}
 
 
-	podString := "pod"
-	namespaceString := "namespace"
-	uidString := "uid"
 	labels = append(labels,
 	labels = append(labels,
 		&dto.LabelPair{
 		&dto.LabelPair{
-			Name:  &podString,
+			Name:  toStringPtr("pod"),
 			Value: &nam.pod,
 			Value: &nam.pod,
 		},
 		},
 		&dto.LabelPair{
 		&dto.LabelPair{
-			Name:  &namespaceString,
+			Name:  toStringPtr("namespace"),
 			Value: &nam.namespace,
 			Value: &nam.namespace,
-		}, &dto.LabelPair{
-			Name:  &uidString,
+		},
+		&dto.LabelPair{
+			Name:  toStringPtr("uid"),
 			Value: &nam.uid,
 			Value: &nam.uid,
 		},
 		},
 	)
 	)
@@ -750,6 +771,156 @@ func (kpcrr KubePodContainerResourceLimitsMetric) Write(m *dto.Metric) error {
 	return nil
 	return nil
 }
 }
 
 
+//--------------------------------------------------------------------------
+//  KubePodContainerResourceLimitsCPUCoresMetric (KSM v1)
+//--------------------------------------------------------------------------
+
+// KubePodContainerResourceLimitsCPUCoresMetric is a prometheus.Metric
+type KubePodContainerResourceLimitsCPUCoresMetric struct {
+	fqName    string
+	help      string
+	pod       string
+	namespace string
+	container string
+	uid       string
+	node      string
+	value     float64
+}
+
+// Creates a new KubePodContainerResourceLimitsMetric, implementation of prometheus.Metric
+func newKubePodContainerResourceLimitsCPUCoresMetric(fqname, pod, namespace, uid, container, node string, value float64) KubePodContainerResourceLimitsCPUCoresMetric {
+	return KubePodContainerResourceLimitsCPUCoresMetric{
+		fqName:    fqname,
+		help:      "kube_pod_container_resource_limits_cpu_cores pods container cpu cores resource limits",
+		pod:       pod,
+		namespace: namespace,
+		uid:       uid,
+		container: container,
+		node:      node,
+		value:     value,
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kpcrr KubePodContainerResourceLimitsCPUCoresMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"pod":       kpcrr.pod,
+		"namespace": kpcrr.namespace,
+		"uid":       kpcrr.uid,
+		"container": kpcrr.container,
+		"node":      kpcrr.node,
+	}
+	return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data
+// transmission object.
+func (kpcrr KubePodContainerResourceLimitsCPUCoresMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kpcrr.value,
+	}
+
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("pod"),
+			Value: &kpcrr.pod,
+		},
+		{
+			Name:  toStringPtr("namespace"),
+			Value: &kpcrr.namespace,
+		},
+		{
+			Name:  toStringPtr("container"),
+			Value: &kpcrr.container,
+		},
+		{
+			Name:  toStringPtr("uid"),
+			Value: &kpcrr.uid,
+		},
+		{
+			Name:  toStringPtr("node"),
+			Value: &kpcrr.node,
+		},
+	}
+	return nil
+}
+
+//--------------------------------------------------------------------------
+//  KubePodContainerResourceLimitsMemoryBytesMetric (KSM v1)
+//--------------------------------------------------------------------------
+
+// KubePodContainerResourceLimitsMemoryBytesMetric is a prometheus.Metric
+type KubePodContainerResourceLimitsMemoryBytesMetric struct {
+	fqName    string
+	help      string
+	pod       string
+	namespace string
+	container string
+	uid       string
+	node      string
+	value     float64
+}
+
+// Creates a new KubePodContainerResourceLimitsMemoryBytesMetric, implementation of prometheus.Metric
+func newKubePodContainerResourceLimitsMemoryBytesMetric(fqname, pod, namespace, uid, container, node string, value float64) KubePodContainerResourceLimitsMemoryBytesMetric {
+	return KubePodContainerResourceLimitsMemoryBytesMetric{
+		fqName:    fqname,
+		help:      "kube_pod_container_resource_limits_memory_bytes pods container memory bytes resource limits",
+		pod:       pod,
+		namespace: namespace,
+		uid:       uid,
+		container: container,
+		node:      node,
+		value:     value,
+	}
+}
+
+// Desc returns the descriptor for the Metric. This method idempotently
+// returns the same descriptor throughout the lifetime of the Metric.
+func (kpcrr KubePodContainerResourceLimitsMemoryBytesMetric) Desc() *prometheus.Desc {
+	l := prometheus.Labels{
+		"pod":       kpcrr.pod,
+		"namespace": kpcrr.namespace,
+		"uid":       kpcrr.uid,
+		"container": kpcrr.container,
+		"node":      kpcrr.node,
+	}
+	return prometheus.NewDesc(kpcrr.fqName, kpcrr.help, []string{}, l)
+}
+
+// Write encodes the Metric into a "Metric" Protocol Buffer data
+// transmission object.
+func (kpcrr KubePodContainerResourceLimitsMemoryBytesMetric) Write(m *dto.Metric) error {
+	m.Gauge = &dto.Gauge{
+		Value: &kpcrr.value,
+	}
+
+	m.Label = []*dto.LabelPair{
+		{
+			Name:  toStringPtr("pod"),
+			Value: &kpcrr.pod,
+		},
+		{
+			Name:  toStringPtr("namespace"),
+			Value: &kpcrr.namespace,
+		},
+		{
+			Name:  toStringPtr("container"),
+			Value: &kpcrr.container,
+		},
+		{
+			Name:  toStringPtr("uid"),
+			Value: &kpcrr.uid,
+		},
+		{
+			Name:  toStringPtr("node"),
+			Value: &kpcrr.node,
+		},
+	}
+	return nil
+}
+
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 //  KubePodOwnerMetric
 //  KubePodOwnerMetric
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------