mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 16:30:55 +01:00
86394b4179
Cache sanitized label names and return them next time. This reduces the number of allocations and speeds up the SanitizeLabelName() function for common case when the number of unique label names is smaller than 100k
142 lines
3.7 KiB
Go
142 lines
3.7 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
|
|
)
|
|
|
|
// getNodesLabels returns labels for k8s nodes obtained from the given cfg
|
|
func (n *Node) key() string {
|
|
return n.Metadata.key()
|
|
}
|
|
|
|
func parseNodeList(r io.Reader) (map[string]object, ListMeta, error) {
|
|
var nl NodeList
|
|
d := json.NewDecoder(r)
|
|
if err := d.Decode(&nl); err != nil {
|
|
return nil, nl.Metadata, fmt.Errorf("cannot unmarshal NodeList: %w", err)
|
|
}
|
|
objectsByKey := make(map[string]object)
|
|
for _, n := range nl.Items {
|
|
objectsByKey[n.key()] = n
|
|
}
|
|
return objectsByKey, nl.Metadata, nil
|
|
}
|
|
|
|
func parseNode(data []byte) (object, error) {
|
|
var n Node
|
|
if err := json.Unmarshal(data, &n); err != nil {
|
|
return nil, err
|
|
}
|
|
return &n, nil
|
|
}
|
|
|
|
// NodeList represents NodeList from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeList
|
|
type NodeList struct {
|
|
Metadata ListMeta
|
|
Items []*Node
|
|
}
|
|
|
|
// Node represents Node from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/node-v1/
|
|
type Node struct {
|
|
Metadata ObjectMeta
|
|
Status NodeStatus
|
|
Spec NodeSpec
|
|
}
|
|
|
|
// NodeStatus represents NodeStatus from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeStatus
|
|
type NodeStatus struct {
|
|
Addresses []NodeAddress
|
|
DaemonEndpoints NodeDaemonEndpoints
|
|
}
|
|
|
|
// NodeSpec represents NodeSpec from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeSpec
|
|
type NodeSpec struct {
|
|
ProviderID string
|
|
}
|
|
|
|
// NodeAddress represents NodeAddress from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#nodeaddress-v1-core
|
|
type NodeAddress struct {
|
|
Type string
|
|
Address string
|
|
}
|
|
|
|
// NodeDaemonEndpoints represents NodeDaemonEndpoints from k8s API.
|
|
//
|
|
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#nodedaemonendpoints-v1-core
|
|
type NodeDaemonEndpoints struct {
|
|
KubeletEndpoint DaemonEndpoint
|
|
}
|
|
|
|
// getTargetLabels returs labels for the given n.
|
|
//
|
|
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#node
|
|
func (n *Node) getTargetLabels(gw *groupWatcher) []map[string]string {
|
|
addr := getNodeAddr(n.Status.Addresses)
|
|
if len(addr) == 0 {
|
|
// Skip node without address
|
|
return nil
|
|
}
|
|
addr = discoveryutils.JoinHostPort(addr, n.Status.DaemonEndpoints.KubeletEndpoint.Port)
|
|
m := map[string]string{
|
|
"__address__": addr,
|
|
"instance": n.Metadata.Name,
|
|
"__meta_kubernetes_node_name": n.Metadata.Name,
|
|
"__meta_kubernetes_node_provider_id": n.Spec.ProviderID,
|
|
}
|
|
n.Metadata.registerLabelsAndAnnotations("__meta_kubernetes_node", m)
|
|
addrTypesUsed := make(map[string]bool, len(n.Status.Addresses))
|
|
for _, a := range n.Status.Addresses {
|
|
if addrTypesUsed[a.Type] {
|
|
continue
|
|
}
|
|
addrTypesUsed[a.Type] = true
|
|
m[discoveryutils.SanitizeLabelName("__meta_kubernetes_node_address_"+a.Type)] = a.Address
|
|
}
|
|
return []map[string]string{m}
|
|
}
|
|
|
|
func getNodeAddr(nas []NodeAddress) string {
|
|
if addr := getAddrByType(nas, "InternalIP"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
if addr := getAddrByType(nas, "InternalDNS"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
if addr := getAddrByType(nas, "ExternalIP"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
if addr := getAddrByType(nas, "ExternalDNS"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
if addr := getAddrByType(nas, "LegacyHostIP"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
if addr := getAddrByType(nas, "Hostname"); len(addr) > 0 {
|
|
return addr
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getAddrByType(nas []NodeAddress, typ string) string {
|
|
for _, na := range nas {
|
|
if na.Type == typ {
|
|
return na.Address
|
|
}
|
|
}
|
|
return ""
|
|
}
|