...

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

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

     1  /*
     2  Copyright 2017 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  	"context"
    21  	"fmt"
    22  
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"k8s.io/apimachinery/pkg/types"
    25  	internalapi "k8s.io/cri-api/pkg/apis"
    26  	statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
    27  	"k8s.io/kubernetes/pkg/kubelet/cadvisor"
    28  	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
    29  	"k8s.io/kubernetes/pkg/kubelet/server/stats"
    30  	"k8s.io/kubernetes/pkg/kubelet/stats/pidlimit"
    31  	"k8s.io/kubernetes/pkg/kubelet/status"
    32  	kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
    33  	"k8s.io/utils/ptr"
    34  )
    35  
    36  // PodManager is the subset of methods the manager needs to observe the actual state of the kubelet.
    37  // See pkg/k8s.io/kubernetes/pkg/kubelet/pod.Manager for method godoc.
    38  type PodManager interface {
    39  	TranslatePodUID(uid types.UID) kubetypes.ResolvedPodUID
    40  }
    41  
    42  // NewCRIStatsProvider returns a Provider that provides the node stats
    43  // from cAdvisor and the container stats from CRI.
    44  func NewCRIStatsProvider(
    45  	cadvisor cadvisor.Interface,
    46  	resourceAnalyzer stats.ResourceAnalyzer,
    47  	podManager PodManager,
    48  	runtimeCache kubecontainer.RuntimeCache,
    49  	runtimeService internalapi.RuntimeService,
    50  	imageService internalapi.ImageManagerService,
    51  	hostStatsProvider HostStatsProvider,
    52  	podAndContainerStatsFromCRI bool,
    53  ) *Provider {
    54  	return newStatsProvider(cadvisor, podManager, runtimeCache, newCRIStatsProvider(cadvisor, resourceAnalyzer,
    55  		runtimeService, imageService, hostStatsProvider, podAndContainerStatsFromCRI))
    56  }
    57  
    58  // NewCadvisorStatsProvider returns a containerStatsProvider that provides both
    59  // the node and the container stats from cAdvisor.
    60  func NewCadvisorStatsProvider(
    61  	cadvisor cadvisor.Interface,
    62  	resourceAnalyzer stats.ResourceAnalyzer,
    63  	podManager PodManager,
    64  	runtimeCache kubecontainer.RuntimeCache,
    65  	imageService kubecontainer.ImageService,
    66  	statusProvider status.PodStatusProvider,
    67  	hostStatsProvider HostStatsProvider,
    68  ) *Provider {
    69  	return newStatsProvider(cadvisor, podManager, runtimeCache, newCadvisorStatsProvider(cadvisor, resourceAnalyzer, imageService, statusProvider, hostStatsProvider))
    70  }
    71  
    72  // newStatsProvider returns a new Provider that provides node stats from
    73  // cAdvisor and the container stats using the containerStatsProvider.
    74  func newStatsProvider(
    75  	cadvisor cadvisor.Interface,
    76  	podManager PodManager,
    77  	runtimeCache kubecontainer.RuntimeCache,
    78  	containerStatsProvider containerStatsProvider,
    79  ) *Provider {
    80  	return &Provider{
    81  		cadvisor:               cadvisor,
    82  		podManager:             podManager,
    83  		runtimeCache:           runtimeCache,
    84  		containerStatsProvider: containerStatsProvider,
    85  	}
    86  }
    87  
    88  // Provider provides the stats of the node and the pod-managed containers.
    89  type Provider struct {
    90  	cadvisor     cadvisor.Interface
    91  	podManager   PodManager
    92  	runtimeCache kubecontainer.RuntimeCache
    93  	containerStatsProvider
    94  }
    95  
    96  // containerStatsProvider is an interface that provides the stats of the
    97  // containers managed by pods.
    98  type containerStatsProvider interface {
    99  	ListPodStats(ctx context.Context) ([]statsapi.PodStats, error)
   100  	ListPodStatsAndUpdateCPUNanoCoreUsage(ctx context.Context) ([]statsapi.PodStats, error)
   101  	ListPodCPUAndMemoryStats(ctx context.Context) ([]statsapi.PodStats, error)
   102  	ImageFsStats(ctx context.Context) (*statsapi.FsStats, *statsapi.FsStats, error)
   103  	ImageFsDevice(ctx context.Context) (string, error)
   104  }
   105  
   106  // RlimitStats returns base information about process count
   107  func (p *Provider) RlimitStats() (*statsapi.RlimitStats, error) {
   108  	return pidlimit.Stats()
   109  }
   110  
   111  // GetCgroupStats returns the stats of the cgroup with the cgroupName. Note that
   112  // this function doesn't generate filesystem stats.
   113  func (p *Provider) GetCgroupStats(cgroupName string, updateStats bool) (*statsapi.ContainerStats, *statsapi.NetworkStats, error) {
   114  	info, err := getCgroupInfo(p.cadvisor, cgroupName, updateStats)
   115  	if err != nil {
   116  		return nil, nil, fmt.Errorf("failed to get cgroup stats for %q: %v", cgroupName, err)
   117  	}
   118  	// Rootfs and imagefs doesn't make sense for raw cgroup.
   119  	s := cadvisorInfoToContainerStats(cgroupName, info, nil, nil)
   120  	n := cadvisorInfoToNetworkStats(info)
   121  	return s, n, nil
   122  }
   123  
   124  // GetCgroupCPUAndMemoryStats returns the CPU and memory stats of the cgroup with the cgroupName. Note that
   125  // this function doesn't generate filesystem stats.
   126  func (p *Provider) GetCgroupCPUAndMemoryStats(cgroupName string, updateStats bool) (*statsapi.ContainerStats, error) {
   127  	info, err := getCgroupInfo(p.cadvisor, cgroupName, updateStats)
   128  	if err != nil {
   129  		return nil, fmt.Errorf("failed to get cgroup stats for %q: %v", cgroupName, err)
   130  	}
   131  	// Rootfs and imagefs doesn't make sense for raw cgroup.
   132  	s := cadvisorInfoToContainerCPUAndMemoryStats(cgroupName, info)
   133  	return s, nil
   134  }
   135  
   136  // RootFsStats returns the stats of the node root filesystem.
   137  func (p *Provider) RootFsStats() (*statsapi.FsStats, error) {
   138  	rootFsInfo, err := p.cadvisor.RootFsInfo()
   139  	if err != nil {
   140  		return nil, fmt.Errorf("failed to get rootFs info: %v", err)
   141  	}
   142  
   143  	var nodeFsInodesUsed *uint64
   144  	if rootFsInfo.Inodes != nil && rootFsInfo.InodesFree != nil {
   145  		nodeFsIU := *rootFsInfo.Inodes - *rootFsInfo.InodesFree
   146  		nodeFsInodesUsed = &nodeFsIU
   147  	}
   148  
   149  	// Get the root container stats's timestamp, which will be used as the
   150  	// imageFs stats timestamp.  Don't force a stats update, as we only want the timestamp.
   151  	rootStats, err := getCgroupStats(p.cadvisor, "/", false)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("failed to get root container stats: %v", err)
   154  	}
   155  
   156  	return &statsapi.FsStats{
   157  		Time:           metav1.NewTime(rootStats.Timestamp),
   158  		AvailableBytes: &rootFsInfo.Available,
   159  		CapacityBytes:  &rootFsInfo.Capacity,
   160  		UsedBytes:      &rootFsInfo.Usage,
   161  		InodesFree:     rootFsInfo.InodesFree,
   162  		Inodes:         rootFsInfo.Inodes,
   163  		InodesUsed:     nodeFsInodesUsed,
   164  	}, nil
   165  }
   166  
   167  // HasDedicatedImageFs returns true if a dedicated image filesystem exists for storing images.
   168  // KEP Issue Number 4191: Enhanced this to allow for the containers to be separate from images.
   169  func (p *Provider) HasDedicatedImageFs(ctx context.Context) (bool, error) {
   170  	device, err := p.containerStatsProvider.ImageFsDevice(ctx)
   171  	if err != nil {
   172  		return false, err
   173  	}
   174  	rootFsInfo, err := p.cadvisor.RootFsInfo()
   175  	if err != nil {
   176  		return false, err
   177  	}
   178  	// KEP Enhancement: DedicatedImageFs can mean either container or image fs are separate from root
   179  	// CAdvisor reports this a bit differently than Container runtimes
   180  	if device == rootFsInfo.Device {
   181  		imageFs, containerFs, err := p.ImageFsStats(ctx)
   182  		if err != nil {
   183  			return false, err
   184  		}
   185  		if !equalFileSystems(imageFs, containerFs) {
   186  			return true, nil
   187  		}
   188  	}
   189  	return device != rootFsInfo.Device, nil
   190  }
   191  
   192  func equalFileSystems(a, b *statsapi.FsStats) bool {
   193  	if a == nil || b == nil {
   194  		return false
   195  	}
   196  	if !ptr.Equal(a.AvailableBytes, b.AvailableBytes) {
   197  		return false
   198  	}
   199  	if !ptr.Equal(a.CapacityBytes, b.CapacityBytes) {
   200  		return false
   201  	}
   202  	if !ptr.Equal(a.InodesUsed, b.InodesUsed) {
   203  		return false
   204  	}
   205  	if !ptr.Equal(a.InodesFree, b.InodesFree) {
   206  		return false
   207  	}
   208  	if !ptr.Equal(a.Inodes, b.Inodes) {
   209  		return false
   210  	}
   211  	return true
   212  }
   213  

View as plain text