123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /*
- Copyright 2017 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package stats
- import (
- "fmt"
- cadvisorapiv1 "github.com/google/cadvisor/info/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/types"
- internalapi "k8s.io/cri-api/pkg/apis"
- statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
- "k8s.io/kubernetes/pkg/kubelet/cadvisor"
- kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
- kubepod "k8s.io/kubernetes/pkg/kubelet/pod"
- "k8s.io/kubernetes/pkg/kubelet/server/stats"
- "k8s.io/kubernetes/pkg/kubelet/stats/pidlimit"
- "k8s.io/kubernetes/pkg/kubelet/status"
- )
- // NewCRIStatsProvider returns a StatsProvider that provides the node stats
- // from cAdvisor and the container stats from CRI.
- func NewCRIStatsProvider(
- cadvisor cadvisor.Interface,
- resourceAnalyzer stats.ResourceAnalyzer,
- podManager kubepod.Manager,
- runtimeCache kubecontainer.RuntimeCache,
- runtimeService internalapi.RuntimeService,
- imageService internalapi.ImageManagerService,
- logMetricsService LogMetricsService,
- osInterface kubecontainer.OSInterface,
- ) *StatsProvider {
- return newStatsProvider(cadvisor, podManager, runtimeCache, newCRIStatsProvider(cadvisor, resourceAnalyzer,
- runtimeService, imageService, logMetricsService, osInterface))
- }
- // NewCadvisorStatsProvider returns a containerStatsProvider that provides both
- // the node and the container stats from cAdvisor.
- func NewCadvisorStatsProvider(
- cadvisor cadvisor.Interface,
- resourceAnalyzer stats.ResourceAnalyzer,
- podManager kubepod.Manager,
- runtimeCache kubecontainer.RuntimeCache,
- imageService kubecontainer.ImageService,
- statusProvider status.PodStatusProvider,
- ) *StatsProvider {
- return newStatsProvider(cadvisor, podManager, runtimeCache, newCadvisorStatsProvider(cadvisor, resourceAnalyzer, imageService, statusProvider))
- }
- // newStatsProvider returns a new StatsProvider that provides node stats from
- // cAdvisor and the container stats using the containerStatsProvider.
- func newStatsProvider(
- cadvisor cadvisor.Interface,
- podManager kubepod.Manager,
- runtimeCache kubecontainer.RuntimeCache,
- containerStatsProvider containerStatsProvider,
- ) *StatsProvider {
- return &StatsProvider{
- cadvisor: cadvisor,
- podManager: podManager,
- runtimeCache: runtimeCache,
- containerStatsProvider: containerStatsProvider,
- }
- }
- // StatsProvider provides the stats of the node and the pod-managed containers.
- type StatsProvider struct {
- cadvisor cadvisor.Interface
- podManager kubepod.Manager
- runtimeCache kubecontainer.RuntimeCache
- containerStatsProvider
- rlimitStatsProvider
- }
- // containerStatsProvider is an interface that provides the stats of the
- // containers managed by pods.
- type containerStatsProvider interface {
- ListPodStats() ([]statsapi.PodStats, error)
- ListPodStatsAndUpdateCPUNanoCoreUsage() ([]statsapi.PodStats, error)
- ListPodCPUAndMemoryStats() ([]statsapi.PodStats, error)
- ImageFsStats() (*statsapi.FsStats, error)
- ImageFsDevice() (string, error)
- }
- type rlimitStatsProvider interface {
- RlimitStats() (*statsapi.RlimitStats, error)
- }
- // RlimitStats returns base information about process count
- func (p *StatsProvider) RlimitStats() (*statsapi.RlimitStats, error) {
- return pidlimit.Stats()
- }
- // GetCgroupStats returns the stats of the cgroup with the cgroupName. Note that
- // this function doesn't generate filesystem stats.
- func (p *StatsProvider) GetCgroupStats(cgroupName string, updateStats bool) (*statsapi.ContainerStats, *statsapi.NetworkStats, error) {
- info, err := getCgroupInfo(p.cadvisor, cgroupName, updateStats)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to get cgroup stats for %q: %v", cgroupName, err)
- }
- // Rootfs and imagefs doesn't make sense for raw cgroup.
- s := cadvisorInfoToContainerStats(cgroupName, info, nil, nil)
- n := cadvisorInfoToNetworkStats(cgroupName, info)
- return s, n, nil
- }
- // GetCgroupCPUAndMemoryStats returns the CPU and memory stats of the cgroup with the cgroupName. Note that
- // this function doesn't generate filesystem stats.
- func (p *StatsProvider) GetCgroupCPUAndMemoryStats(cgroupName string, updateStats bool) (*statsapi.ContainerStats, error) {
- info, err := getCgroupInfo(p.cadvisor, cgroupName, updateStats)
- if err != nil {
- return nil, fmt.Errorf("failed to get cgroup stats for %q: %v", cgroupName, err)
- }
- // Rootfs and imagefs doesn't make sense for raw cgroup.
- s := cadvisorInfoToContainerCPUAndMemoryStats(cgroupName, info)
- return s, nil
- }
- // RootFsStats returns the stats of the node root filesystem.
- func (p *StatsProvider) RootFsStats() (*statsapi.FsStats, error) {
- rootFsInfo, err := p.cadvisor.RootFsInfo()
- if err != nil {
- return nil, fmt.Errorf("failed to get rootFs info: %v", err)
- }
- var nodeFsInodesUsed *uint64
- if rootFsInfo.Inodes != nil && rootFsInfo.InodesFree != nil {
- nodeFsIU := *rootFsInfo.Inodes - *rootFsInfo.InodesFree
- nodeFsInodesUsed = &nodeFsIU
- }
- // Get the root container stats's timestamp, which will be used as the
- // imageFs stats timestamp. Dont force a stats update, as we only want the timestamp.
- rootStats, err := getCgroupStats(p.cadvisor, "/", false)
- if err != nil {
- return nil, fmt.Errorf("failed to get root container stats: %v", err)
- }
- return &statsapi.FsStats{
- Time: metav1.NewTime(rootStats.Timestamp),
- AvailableBytes: &rootFsInfo.Available,
- CapacityBytes: &rootFsInfo.Capacity,
- UsedBytes: &rootFsInfo.Usage,
- InodesFree: rootFsInfo.InodesFree,
- Inodes: rootFsInfo.Inodes,
- InodesUsed: nodeFsInodesUsed,
- }, nil
- }
- // GetContainerInfo returns stats (from cAdvisor) for a container.
- func (p *StatsProvider) GetContainerInfo(podFullName string, podUID types.UID, containerName string, req *cadvisorapiv1.ContainerInfoRequest) (*cadvisorapiv1.ContainerInfo, error) {
- // Resolve and type convert back again.
- // We need the static pod UID but the kubecontainer API works with types.UID.
- podUID = types.UID(p.podManager.TranslatePodUID(podUID))
- pods, err := p.runtimeCache.GetPods()
- if err != nil {
- return nil, err
- }
- pod := kubecontainer.Pods(pods).FindPod(podFullName, podUID)
- container := pod.FindContainerByName(containerName)
- if container == nil {
- return nil, kubecontainer.ErrContainerNotFound
- }
- ci, err := p.cadvisor.DockerContainer(container.ID.ID, req)
- if err != nil {
- return nil, err
- }
- return &ci, nil
- }
- // GetRawContainerInfo returns the stats (from cadvisor) for a non-Kubernetes
- // container.
- func (p *StatsProvider) GetRawContainerInfo(containerName string, req *cadvisorapiv1.ContainerInfoRequest, subcontainers bool) (map[string]*cadvisorapiv1.ContainerInfo, error) {
- if subcontainers {
- return p.cadvisor.SubcontainerInfo(containerName, req)
- }
- containerInfo, err := p.cadvisor.ContainerInfo(containerName, req)
- if err != nil {
- return nil, err
- }
- return map[string]*cadvisorapiv1.ContainerInfo{
- containerInfo.Name: containerInfo,
- }, nil
- }
- // HasDedicatedImageFs returns true if a dedicated image filesystem exists for storing images.
- func (p *StatsProvider) HasDedicatedImageFs() (bool, error) {
- device, err := p.containerStatsProvider.ImageFsDevice()
- if err != nil {
- return false, err
- }
- rootFsInfo, err := p.cadvisor.RootFsInfo()
- if err != nil {
- return false, err
- }
- return device != rootFsInfo.Device, nil
- }
|