2022-05-24 21:49:47 +08:00
|
|
|
//go:generate ../../../tools/readme_config_includer/generator
|
2016-09-17 01:31:41 +08:00
|
|
|
package kubernetes
|
|
|
|
|
|
|
|
|
|
import (
|
2022-12-09 23:56:24 +08:00
|
|
|
"context"
|
2022-05-24 21:49:47 +08:00
|
|
|
_ "embed"
|
2016-09-17 01:31:41 +08:00
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
2021-09-29 05:16:32 +08:00
|
|
|
"os"
|
2019-01-16 07:26:18 +08:00
|
|
|
"strings"
|
2022-12-09 23:56:24 +08:00
|
|
|
"sync"
|
2016-09-17 01:31:41 +08:00
|
|
|
"time"
|
|
|
|
|
|
2023-02-23 21:49:36 +08:00
|
|
|
v1 "k8s.io/api/core/v1"
|
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
|
"k8s.io/client-go/kubernetes"
|
|
|
|
|
"k8s.io/client-go/rest"
|
|
|
|
|
|
2016-09-17 01:31:41 +08:00
|
|
|
"github.com/influxdata/telegraf"
|
2021-04-10 01:15:04 +08:00
|
|
|
"github.com/influxdata/telegraf/config"
|
2019-12-13 07:01:50 +08:00
|
|
|
"github.com/influxdata/telegraf/filter"
|
2020-06-26 02:44:22 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/common/tls"
|
2016-09-17 01:31:41 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/inputs"
|
|
|
|
|
)
|
|
|
|
|
|
2022-05-24 21:49:47 +08:00
|
|
|
//go:embed sample.conf
|
|
|
|
|
var sampleConfig string
|
|
|
|
|
|
2016-09-17 01:31:41 +08:00
|
|
|
// Kubernetes represents the config object for the plugin
|
|
|
|
|
type Kubernetes struct {
|
2024-03-25 20:36:44 +08:00
|
|
|
URL string `toml:"url"`
|
|
|
|
|
BearerToken string `toml:"bearer_token"`
|
2024-06-06 04:19:47 +08:00
|
|
|
BearerTokenString string `toml:"bearer_token_string" deprecated:"1.24.0;1.35.0;use 'BearerToken' with a file instead"`
|
2024-03-25 20:36:44 +08:00
|
|
|
NodeMetricName string `toml:"node_metric_name"`
|
|
|
|
|
LabelInclude []string `toml:"label_include"`
|
|
|
|
|
LabelExclude []string `toml:"label_exclude"`
|
|
|
|
|
ResponseTimeout config.Duration `toml:"response_timeout"`
|
|
|
|
|
Log telegraf.Logger `toml:"-"`
|
2017-09-13 08:22:15 +08:00
|
|
|
|
2018-05-05 07:33:23 +08:00
|
|
|
tls.ClientConfig
|
|
|
|
|
|
2024-03-25 20:36:44 +08:00
|
|
|
labelFilter filter.Filter
|
|
|
|
|
httpClient *http.Client
|
2016-09-17 01:31:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const (
|
2022-12-09 23:58:14 +08:00
|
|
|
defaultServiceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
2016-09-17 01:31:41 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
inputs.Add("kubernetes", func() telegraf.Input {
|
2019-12-13 06:14:37 +08:00
|
|
|
return &Kubernetes{
|
|
|
|
|
LabelInclude: []string{},
|
|
|
|
|
LabelExclude: []string{"*"},
|
|
|
|
|
}
|
2016-09-17 01:31:41 +08:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-24 21:49:47 +08:00
|
|
|
func (*Kubernetes) SampleConfig() string {
|
|
|
|
|
return sampleConfig
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-07 05:37:48 +08:00
|
|
|
func (k *Kubernetes) Init() error {
|
|
|
|
|
// If neither are provided, use the default service account.
|
|
|
|
|
if k.BearerToken == "" && k.BearerTokenString == "" {
|
|
|
|
|
k.BearerToken = defaultServiceAccountPath
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 06:14:37 +08:00
|
|
|
labelFilter, err := filter.NewIncludeExcludeFilter(k.LabelInclude, k.LabelExclude)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
k.labelFilter = labelFilter
|
|
|
|
|
|
2022-12-09 23:56:24 +08:00
|
|
|
if k.URL == "" {
|
|
|
|
|
k.InsecureSkipVerify = true
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-25 20:36:44 +08:00
|
|
|
if k.NodeMetricName == "" {
|
|
|
|
|
k.NodeMetricName = "kubernetes_node"
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-07 05:37:48 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 02:49:36 +08:00
|
|
|
// Gather collects kubernetes metrics from a given URL
|
2016-09-17 01:31:41 +08:00
|
|
|
func (k *Kubernetes) Gather(acc telegraf.Accumulator) error {
|
2022-12-09 23:56:24 +08:00
|
|
|
if k.URL != "" {
|
|
|
|
|
acc.AddError(k.gatherSummary(k.URL, acc))
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
nodeBaseURLs, err := getNodeURLs(k.Log)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, url := range nodeBaseURLs {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go func(url string) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
acc.AddError(k.gatherSummary(url, acc))
|
|
|
|
|
}(url)
|
|
|
|
|
}
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
2017-04-25 02:13:26 +08:00
|
|
|
return nil
|
2016-09-17 01:31:41 +08:00
|
|
|
}
|
|
|
|
|
|
2022-12-09 23:56:24 +08:00
|
|
|
func getNodeURLs(log telegraf.Logger) ([]string, error) {
|
|
|
|
|
cfg, err := rest.InClusterConfig()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
client, err := kubernetes.NewForConfig(cfg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nodes, err := client.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nodeUrls := make([]string, 0, len(nodes.Items))
|
2023-12-15 22:36:34 +08:00
|
|
|
for i := range nodes.Items {
|
|
|
|
|
n := &nodes.Items[i]
|
|
|
|
|
|
|
|
|
|
address := getNodeAddress(n.Status.Addresses)
|
2022-12-09 23:56:24 +08:00
|
|
|
if address == "" {
|
2023-02-23 21:49:36 +08:00
|
|
|
log.Warnf("Unable to node addresses for Node %q", n.Name)
|
2022-12-09 23:56:24 +08:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
nodeUrls = append(nodeUrls, "https://"+address+":10250")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nodeUrls, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prefer internal addresses, if none found, use ExternalIP
|
2023-12-15 22:36:34 +08:00
|
|
|
func getNodeAddress(addresses []v1.NodeAddress) string {
|
2022-12-09 23:56:24 +08:00
|
|
|
extAddresses := make([]string, 0)
|
2023-12-15 22:36:34 +08:00
|
|
|
for _, addr := range addresses {
|
2022-12-09 23:56:24 +08:00
|
|
|
if addr.Type == v1.NodeInternalIP {
|
|
|
|
|
return addr.Address
|
|
|
|
|
}
|
|
|
|
|
extAddresses = append(extAddresses, addr.Address)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(extAddresses) > 0 {
|
|
|
|
|
return extAddresses[0]
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 01:31:41 +08:00
|
|
|
func (k *Kubernetes) gatherSummary(baseURL string, acc telegraf.Accumulator) error {
|
2019-12-13 06:14:37 +08:00
|
|
|
summaryMetrics := &SummaryMetrics{}
|
2024-02-09 04:46:22 +08:00
|
|
|
err := k.LoadJSON(baseURL+"/stats/summary", summaryMetrics)
|
2016-09-17 01:31:41 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 06:14:37 +08:00
|
|
|
podInfos, err := k.gatherPodInfo(baseURL)
|
2016-09-17 01:31:41 +08:00
|
|
|
if err != nil {
|
2019-12-13 06:14:37 +08:00
|
|
|
return err
|
2016-09-17 01:31:41 +08:00
|
|
|
}
|
|
|
|
|
buildSystemContainerMetrics(summaryMetrics, acc)
|
2024-03-25 20:36:44 +08:00
|
|
|
buildNodeMetrics(summaryMetrics, acc, k.NodeMetricName)
|
2021-03-23 01:21:36 +08:00
|
|
|
buildPodMetrics(summaryMetrics, podInfos, k.labelFilter, acc)
|
2016-09-17 01:31:41 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func buildSystemContainerMetrics(summaryMetrics *SummaryMetrics, acc telegraf.Accumulator) {
|
|
|
|
|
for _, container := range summaryMetrics.Node.SystemContainers {
|
|
|
|
|
tags := map[string]string{
|
|
|
|
|
"node_name": summaryMetrics.Node.NodeName,
|
|
|
|
|
"container_name": container.Name,
|
|
|
|
|
}
|
|
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
fields["cpu_usage_nanocores"] = container.CPU.UsageNanoCores
|
|
|
|
|
fields["cpu_usage_core_nanoseconds"] = container.CPU.UsageCoreNanoSeconds
|
|
|
|
|
fields["memory_usage_bytes"] = container.Memory.UsageBytes
|
|
|
|
|
fields["memory_working_set_bytes"] = container.Memory.WorkingSetBytes
|
|
|
|
|
fields["memory_rss_bytes"] = container.Memory.RSSBytes
|
|
|
|
|
fields["memory_page_faults"] = container.Memory.PageFaults
|
|
|
|
|
fields["memory_major_page_faults"] = container.Memory.MajorPageFaults
|
|
|
|
|
fields["rootfs_available_bytes"] = container.RootFS.AvailableBytes
|
|
|
|
|
fields["rootfs_capacity_bytes"] = container.RootFS.CapacityBytes
|
2019-08-06 05:04:41 +08:00
|
|
|
fields["logsfs_available_bytes"] = container.LogsFS.AvailableBytes
|
2016-09-17 01:31:41 +08:00
|
|
|
fields["logsfs_capacity_bytes"] = container.LogsFS.CapacityBytes
|
|
|
|
|
acc.AddFields("kubernetes_system_container", fields, tags)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-25 20:36:44 +08:00
|
|
|
func buildNodeMetrics(summaryMetrics *SummaryMetrics, acc telegraf.Accumulator, metricName string) {
|
2016-09-17 01:31:41 +08:00
|
|
|
tags := map[string]string{
|
|
|
|
|
"node_name": summaryMetrics.Node.NodeName,
|
|
|
|
|
}
|
|
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
fields["cpu_usage_nanocores"] = summaryMetrics.Node.CPU.UsageNanoCores
|
|
|
|
|
fields["cpu_usage_core_nanoseconds"] = summaryMetrics.Node.CPU.UsageCoreNanoSeconds
|
|
|
|
|
fields["memory_available_bytes"] = summaryMetrics.Node.Memory.AvailableBytes
|
|
|
|
|
fields["memory_usage_bytes"] = summaryMetrics.Node.Memory.UsageBytes
|
|
|
|
|
fields["memory_working_set_bytes"] = summaryMetrics.Node.Memory.WorkingSetBytes
|
|
|
|
|
fields["memory_rss_bytes"] = summaryMetrics.Node.Memory.RSSBytes
|
|
|
|
|
fields["memory_page_faults"] = summaryMetrics.Node.Memory.PageFaults
|
|
|
|
|
fields["memory_major_page_faults"] = summaryMetrics.Node.Memory.MajorPageFaults
|
|
|
|
|
fields["network_rx_bytes"] = summaryMetrics.Node.Network.RXBytes
|
|
|
|
|
fields["network_rx_errors"] = summaryMetrics.Node.Network.RXErrors
|
|
|
|
|
fields["network_tx_bytes"] = summaryMetrics.Node.Network.TXBytes
|
|
|
|
|
fields["network_tx_errors"] = summaryMetrics.Node.Network.TXErrors
|
|
|
|
|
fields["fs_available_bytes"] = summaryMetrics.Node.FileSystem.AvailableBytes
|
|
|
|
|
fields["fs_capacity_bytes"] = summaryMetrics.Node.FileSystem.CapacityBytes
|
|
|
|
|
fields["fs_used_bytes"] = summaryMetrics.Node.FileSystem.UsedBytes
|
|
|
|
|
fields["runtime_image_fs_available_bytes"] = summaryMetrics.Node.Runtime.ImageFileSystem.AvailableBytes
|
|
|
|
|
fields["runtime_image_fs_capacity_bytes"] = summaryMetrics.Node.Runtime.ImageFileSystem.CapacityBytes
|
|
|
|
|
fields["runtime_image_fs_used_bytes"] = summaryMetrics.Node.Runtime.ImageFileSystem.UsedBytes
|
2024-03-25 20:36:44 +08:00
|
|
|
acc.AddFields(metricName, fields, tags)
|
2016-09-17 01:31:41 +08:00
|
|
|
}
|
|
|
|
|
|
2023-05-19 21:54:09 +08:00
|
|
|
func (k *Kubernetes) gatherPodInfo(baseURL string) ([]Item, error) {
|
2021-03-02 05:04:35 +08:00
|
|
|
var podAPI Pods
|
2024-02-09 04:46:22 +08:00
|
|
|
err := k.LoadJSON(baseURL+"/pods", &podAPI)
|
2019-12-13 06:14:37 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2023-05-19 21:54:09 +08:00
|
|
|
podInfos := make([]Item, 0, len(podAPI.Items))
|
|
|
|
|
podInfos = append(podInfos, podAPI.Items...)
|
2019-12-13 06:14:37 +08:00
|
|
|
return podInfos, nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 05:04:35 +08:00
|
|
|
func (k *Kubernetes) LoadJSON(url string, v interface{}) error {
|
2019-12-13 06:14:37 +08:00
|
|
|
var req, err = http.NewRequest("GET", url, nil)
|
2020-09-09 02:13:23 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2019-12-13 06:14:37 +08:00
|
|
|
var resp *http.Response
|
|
|
|
|
tlsCfg, err := k.ClientConfig.TLSConfig()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-03-22 20:33:53 +08:00
|
|
|
|
|
|
|
|
if k.httpClient == nil {
|
2021-04-10 01:15:04 +08:00
|
|
|
if k.ResponseTimeout < config.Duration(time.Second) {
|
|
|
|
|
k.ResponseTimeout = config.Duration(time.Second * 5)
|
2019-12-13 06:14:37 +08:00
|
|
|
}
|
2023-03-22 20:33:53 +08:00
|
|
|
k.httpClient = &http.Client{
|
|
|
|
|
Transport: &http.Transport{
|
|
|
|
|
TLSClientConfig: tlsCfg,
|
|
|
|
|
},
|
2024-02-13 06:26:10 +08:00
|
|
|
CheckRedirect: func(*http.Request, []*http.Request) error {
|
2023-03-22 20:33:53 +08:00
|
|
|
return http.ErrUseLastResponse
|
|
|
|
|
},
|
|
|
|
|
Timeout: time.Duration(k.ResponseTimeout),
|
2019-12-13 06:14:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-22 20:33:53 +08:00
|
|
|
|
2022-08-04 03:10:42 +08:00
|
|
|
if k.BearerToken != "" {
|
|
|
|
|
token, err := os.ReadFile(k.BearerToken)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
k.BearerTokenString = strings.TrimSpace(string(token))
|
|
|
|
|
}
|
2019-12-13 06:14:37 +08:00
|
|
|
req.Header.Set("Authorization", "Bearer "+k.BearerTokenString)
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
2023-03-22 20:33:53 +08:00
|
|
|
resp, err = k.httpClient.Do(req)
|
2019-12-13 06:14:37 +08:00
|
|
|
if err != nil {
|
2023-03-02 05:18:35 +08:00
|
|
|
return fmt.Errorf("error making HTTP request to %q: %w", url, err)
|
2019-12-13 06:14:37 +08:00
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
|
return fmt.Errorf("%s returned HTTP status %s", url, resp.Status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = json.NewDecoder(resp.Body).Decode(v)
|
|
|
|
|
if err != nil {
|
2023-03-02 05:18:35 +08:00
|
|
|
return fmt.Errorf("error parsing response: %w", err)
|
2019-12-13 06:14:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 21:54:09 +08:00
|
|
|
func buildPodMetrics(summaryMetrics *SummaryMetrics, podInfo []Item, labelFilter filter.Filter, acc telegraf.Accumulator) {
|
2016-09-17 01:31:41 +08:00
|
|
|
for _, pod := range summaryMetrics.Pods {
|
2021-07-28 05:13:12 +08:00
|
|
|
podLabels := make(map[string]string)
|
2023-05-19 21:54:09 +08:00
|
|
|
containerImages := make(map[string]string)
|
2021-07-28 05:13:12 +08:00
|
|
|
for _, info := range podInfo {
|
2023-05-19 21:54:09 +08:00
|
|
|
if info.Metadata.Name == pod.PodRef.Name && info.Metadata.Namespace == pod.PodRef.Namespace {
|
|
|
|
|
for _, v := range info.Spec.Containers {
|
|
|
|
|
containerImages[v.Name] = v.Image
|
|
|
|
|
}
|
|
|
|
|
for k, v := range info.Metadata.Labels {
|
2021-07-28 05:13:12 +08:00
|
|
|
if labelFilter.Match(k) {
|
|
|
|
|
podLabels[k] = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 01:31:41 +08:00
|
|
|
for _, container := range pod.Containers {
|
|
|
|
|
tags := map[string]string{
|
|
|
|
|
"node_name": summaryMetrics.Node.NodeName,
|
|
|
|
|
"namespace": pod.PodRef.Namespace,
|
|
|
|
|
"container_name": container.Name,
|
|
|
|
|
"pod_name": pod.PodRef.Name,
|
|
|
|
|
}
|
2023-05-19 21:54:09 +08:00
|
|
|
for k, v := range containerImages {
|
|
|
|
|
if k == container.Name {
|
|
|
|
|
tags["image"] = v
|
|
|
|
|
tok := strings.Split(v, ":")
|
|
|
|
|
if len(tok) == 2 {
|
|
|
|
|
tags["version"] = tok[1]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-28 05:13:12 +08:00
|
|
|
for k, v := range podLabels {
|
|
|
|
|
tags[k] = v
|
2019-12-13 06:14:37 +08:00
|
|
|
}
|
2016-09-17 01:31:41 +08:00
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
fields["cpu_usage_nanocores"] = container.CPU.UsageNanoCores
|
|
|
|
|
fields["cpu_usage_core_nanoseconds"] = container.CPU.UsageCoreNanoSeconds
|
|
|
|
|
fields["memory_usage_bytes"] = container.Memory.UsageBytes
|
|
|
|
|
fields["memory_working_set_bytes"] = container.Memory.WorkingSetBytes
|
|
|
|
|
fields["memory_rss_bytes"] = container.Memory.RSSBytes
|
|
|
|
|
fields["memory_page_faults"] = container.Memory.PageFaults
|
|
|
|
|
fields["memory_major_page_faults"] = container.Memory.MajorPageFaults
|
|
|
|
|
fields["rootfs_available_bytes"] = container.RootFS.AvailableBytes
|
|
|
|
|
fields["rootfs_capacity_bytes"] = container.RootFS.CapacityBytes
|
|
|
|
|
fields["rootfs_used_bytes"] = container.RootFS.UsedBytes
|
2019-08-06 05:04:41 +08:00
|
|
|
fields["logsfs_available_bytes"] = container.LogsFS.AvailableBytes
|
2016-09-17 01:31:41 +08:00
|
|
|
fields["logsfs_capacity_bytes"] = container.LogsFS.CapacityBytes
|
|
|
|
|
fields["logsfs_used_bytes"] = container.LogsFS.UsedBytes
|
|
|
|
|
acc.AddFields("kubernetes_pod_container", fields, tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, volume := range pod.Volumes {
|
|
|
|
|
tags := map[string]string{
|
|
|
|
|
"node_name": summaryMetrics.Node.NodeName,
|
|
|
|
|
"pod_name": pod.PodRef.Name,
|
|
|
|
|
"namespace": pod.PodRef.Namespace,
|
|
|
|
|
"volume_name": volume.Name,
|
|
|
|
|
}
|
2021-07-28 05:13:12 +08:00
|
|
|
for k, v := range podLabels {
|
|
|
|
|
tags[k] = v
|
|
|
|
|
}
|
2016-09-17 01:31:41 +08:00
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
fields["available_bytes"] = volume.AvailableBytes
|
|
|
|
|
fields["capacity_bytes"] = volume.CapacityBytes
|
|
|
|
|
fields["used_bytes"] = volume.UsedBytes
|
|
|
|
|
acc.AddFields("kubernetes_pod_volume", fields, tags)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tags := map[string]string{
|
|
|
|
|
"node_name": summaryMetrics.Node.NodeName,
|
|
|
|
|
"pod_name": pod.PodRef.Name,
|
|
|
|
|
"namespace": pod.PodRef.Namespace,
|
|
|
|
|
}
|
2021-07-28 05:13:12 +08:00
|
|
|
for k, v := range podLabels {
|
|
|
|
|
tags[k] = v
|
|
|
|
|
}
|
2016-09-17 01:31:41 +08:00
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
fields["rx_bytes"] = pod.Network.RXBytes
|
|
|
|
|
fields["rx_errors"] = pod.Network.RXErrors
|
|
|
|
|
fields["tx_bytes"] = pod.Network.TXBytes
|
|
|
|
|
fields["tx_errors"] = pod.Network.TXErrors
|
|
|
|
|
acc.AddFields("kubernetes_pod_network", fields, tags)
|
|
|
|
|
}
|
|
|
|
|
}
|