...

Source file src/k8s.io/kubernetes/pkg/kubelet/stats/host_stats_provider.go

Documentation: k8s.io/kubernetes/pkg/kubelet/stats

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package stats
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  
    24  	cadvisorapiv2 "github.com/google/cadvisor/info/v2"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/types"
    27  	statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
    28  	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
    29  	"k8s.io/kubernetes/pkg/kubelet/kuberuntime"
    30  	"k8s.io/kubernetes/pkg/volume"
    31  )
    32  
    33  // PodEtcHostsPathFunc is a function to fetch a etc hosts path by pod uid and whether etc host path is supported by the runtime
    34  type PodEtcHostsPathFunc func(podUID types.UID) string
    35  
    36  // metricsProviderByPath maps a path to its metrics provider
    37  type metricsProviderByPath map[string]volume.MetricsProvider
    38  
    39  // HostStatsProvider defines an interface for providing host stats associated with pod.
    40  type HostStatsProvider interface {
    41  	// getPodLogStats gets stats associated with pod log usage
    42  	getPodLogStats(podNamespace, podName string, podUID types.UID, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error)
    43  	// getPodContainerLogStats gets stats associated with container log usage
    44  	getPodContainerLogStats(podNamespace, podName string, podUID types.UID, containerName string, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error)
    45  	// getPodEtcHostsStats gets stats associated with pod etc-hosts usage
    46  	getPodEtcHostsStats(podUID types.UID, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error)
    47  }
    48  
    49  type hostStatsProvider struct {
    50  	// osInterface is the interface for syscalls.
    51  	osInterface kubecontainer.OSInterface
    52  	// podEtcHostsPathFunc fetches a pod etc hosts path by uid.
    53  	podEtcHostsPathFunc PodEtcHostsPathFunc
    54  	// podLogsDirectory is the root directory path for pod logs.
    55  	podLogsDirectory string
    56  }
    57  
    58  // NewHostStatsProvider returns a new HostStatsProvider type struct.
    59  func NewHostStatsProvider(osInterface kubecontainer.OSInterface, podEtcHostsPathFunc PodEtcHostsPathFunc, podLogsDirectory string) HostStatsProvider {
    60  	return hostStatsProvider{
    61  		osInterface:         osInterface,
    62  		podEtcHostsPathFunc: podEtcHostsPathFunc,
    63  		podLogsDirectory:    podLogsDirectory,
    64  	}
    65  }
    66  
    67  func (h hostStatsProvider) getPodLogStats(podNamespace, podName string, podUID types.UID, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error) {
    68  	metricsByPath, err := h.podLogMetrics(podNamespace, podName, podUID)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	return metricsByPathToFsStats(metricsByPath, rootFsInfo)
    73  }
    74  
    75  // getPodContainerLogStats gets stats for container
    76  func (h hostStatsProvider) getPodContainerLogStats(podNamespace, podName string, podUID types.UID, containerName string, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error) {
    77  	metricsByPath, err := h.podContainerLogMetrics(podNamespace, podName, podUID, containerName)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	return metricsByPathToFsStats(metricsByPath, rootFsInfo)
    82  }
    83  
    84  // getPodEtcHostsStats gets status for pod etc hosts usage
    85  func (h hostStatsProvider) getPodEtcHostsStats(podUID types.UID, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error) {
    86  	// Runtimes may not support etc hosts file (Windows with docker)
    87  	podEtcHostsPath := h.podEtcHostsPathFunc(podUID)
    88  	// Some pods have an explicit /etc/hosts mount and the Kubelet will not create an etc-hosts file for them
    89  	if _, err := os.Stat(podEtcHostsPath); os.IsNotExist(err) {
    90  		return nil, nil
    91  	}
    92  
    93  	metrics := volume.NewMetricsDu(podEtcHostsPath)
    94  	hostMetrics, err := metrics.GetMetrics()
    95  	if err != nil {
    96  		return nil, fmt.Errorf("failed to get stats %v", err)
    97  	}
    98  	result := rootFsInfoToFsStats(rootFsInfo)
    99  	usedBytes := uint64(hostMetrics.Used.Value())
   100  	inodesUsed := uint64(hostMetrics.InodesUsed.Value())
   101  	result.UsedBytes = addUsage(result.UsedBytes, &usedBytes)
   102  	result.InodesUsed = addUsage(result.InodesUsed, &inodesUsed)
   103  	result.Time = maxUpdateTime(&result.Time, &hostMetrics.Time)
   104  	return result, nil
   105  }
   106  
   107  func (h hostStatsProvider) podLogMetrics(podNamespace, podName string, podUID types.UID) (metricsProviderByPath, error) {
   108  	podLogsDirectoryPath := kuberuntime.BuildPodLogsDirectory(h.podLogsDirectory, podNamespace, podName, podUID)
   109  	return h.fileMetricsByDir(podLogsDirectoryPath)
   110  }
   111  
   112  func (h hostStatsProvider) podContainerLogMetrics(podNamespace, podName string, podUID types.UID, containerName string) (metricsProviderByPath, error) {
   113  	podContainerLogsDirectoryPath := kuberuntime.BuildContainerLogsDirectory(h.podLogsDirectory, podNamespace, podName, podUID, containerName)
   114  	return h.fileMetricsByDir(podContainerLogsDirectoryPath)
   115  }
   116  
   117  // fileMetricsByDir returns metrics by path for each file under specified directory
   118  func (h hostStatsProvider) fileMetricsByDir(dirname string) (metricsProviderByPath, error) {
   119  	files, err := h.osInterface.ReadDir(dirname)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	results := metricsProviderByPath{}
   124  	for _, f := range files {
   125  		if f.IsDir() {
   126  			continue
   127  		}
   128  		// Only include *files* under pod log directory.
   129  		fpath := filepath.Join(dirname, f.Name())
   130  		results[fpath] = volume.NewMetricsDu(fpath)
   131  	}
   132  	return results, nil
   133  }
   134  
   135  // metricsByPathToFsStats converts a metrics provider by path to fs stats
   136  func metricsByPathToFsStats(metricsByPath metricsProviderByPath, rootFsInfo *cadvisorapiv2.FsInfo) (*statsapi.FsStats, error) {
   137  	result := rootFsInfoToFsStats(rootFsInfo)
   138  	for fpath, metrics := range metricsByPath {
   139  		hostMetrics, err := metrics.GetMetrics()
   140  		if err != nil {
   141  			return nil, fmt.Errorf("failed to get fsstats for %q: %v", fpath, err)
   142  		}
   143  		usedBytes := uint64(hostMetrics.Used.Value())
   144  		inodesUsed := uint64(hostMetrics.InodesUsed.Value())
   145  		result.UsedBytes = addUsage(result.UsedBytes, &usedBytes)
   146  		result.InodesUsed = addUsage(result.InodesUsed, &inodesUsed)
   147  		result.Time = maxUpdateTime(&result.Time, &hostMetrics.Time)
   148  	}
   149  	return result, nil
   150  }
   151  
   152  // rootFsInfoToFsStats is a utility to convert rootFsInfo into statsapi.FsStats
   153  func rootFsInfoToFsStats(rootFsInfo *cadvisorapiv2.FsInfo) *statsapi.FsStats {
   154  	return &statsapi.FsStats{
   155  		Time:           metav1.NewTime(rootFsInfo.Timestamp),
   156  		AvailableBytes: &rootFsInfo.Available,
   157  		CapacityBytes:  &rootFsInfo.Capacity,
   158  		InodesFree:     rootFsInfo.InodesFree,
   159  		Inodes:         rootFsInfo.Inodes,
   160  	}
   161  }
   162  

View as plain text