Merge pull request #103095 from haircommander/podAndContainerStatsFromCRI-feature-gate

Kubelet: implement support for podAndContainerStatsFromCRI
This commit is contained in:
Kubernetes Prow Robot 2021-11-07 18:26:53 -08:00 committed by GitHub
commit 33de444861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 229 additions and 54 deletions

View File

@ -784,6 +784,14 @@ const (
// node affinity, selector and tolerations. This is allowed only for suspended jobs // node affinity, selector and tolerations. This is allowed only for suspended jobs
// that have never been unsuspended before. // that have never been unsuspended before.
JobMutableNodeSchedulingDirectives featuregate.Feature = "JobMutableNodeSchedulingDirectives" JobMutableNodeSchedulingDirectives featuregate.Feature = "JobMutableNodeSchedulingDirectives"
// owner: @haircommander
// kep: http://kep.k8s.io/2364
// alpha: v1.23
//
// Configures the Kubelet to use the CRI to populate pod and container stats, instead of supplimenting with stats from cAdvisor.
// Requires the CRI implementation supports supplying the required stats.
PodAndContainerStatsFromCRI featuregate.Feature = "PodAndContainerStatsFromCRI"
) )
func init() { func init() {
@ -899,6 +907,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
CPUManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta}, CPUManagerPolicyBetaOptions: {Default: true, PreRelease: featuregate.Beta},
JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.Beta}, JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.Beta},
IdentifyPodOS: {Default: false, PreRelease: featuregate.Alpha}, IdentifyPodOS: {Default: false, PreRelease: featuregate.Alpha},
PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha},
// inherited features from generic apiserver, relisted here to get a conflict if it is changed // inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side: // unintentionally on either side:

View File

@ -723,7 +723,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
kubeDeps.RemoteRuntimeService, kubeDeps.RemoteRuntimeService,
kubeDeps.RemoteImageService, kubeDeps.RemoteImageService,
hostStatsProvider, hostStatsProvider,
utilfeature.DefaultFeatureGate.Enabled(features.DisableAcceleratorUsageMetrics)) utilfeature.DefaultFeatureGate.Enabled(features.DisableAcceleratorUsageMetrics),
utilfeature.DefaultFeatureGate.Enabled(features.PodAndContainerStatsFromCRI))
} }
klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{}) klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})

View File

@ -27,6 +27,8 @@ import (
cadvisorfs "github.com/google/cadvisor/fs" cadvisorfs "github.com/google/cadvisor/fs"
cadvisorapiv2 "github.com/google/cadvisor/info/v2" cadvisorapiv2 "github.com/google/cadvisor/info/v2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
internalapi "k8s.io/cri-api/pkg/apis" internalapi "k8s.io/cri-api/pkg/apis"
@ -70,6 +72,7 @@ type criStatsProvider struct {
cpuUsageCache map[string]*cpuUsageRecord cpuUsageCache map[string]*cpuUsageRecord
mutex sync.RWMutex mutex sync.RWMutex
disableAcceleratorUsageMetrics bool disableAcceleratorUsageMetrics bool
podAndContainerStatsFromCRI bool
} }
// newCRIStatsProvider returns a containerStatsProvider implementation that // newCRIStatsProvider returns a containerStatsProvider implementation that
@ -80,7 +83,8 @@ func newCRIStatsProvider(
runtimeService internalapi.RuntimeService, runtimeService internalapi.RuntimeService,
imageService internalapi.ImageManagerService, imageService internalapi.ImageManagerService,
hostStatsProvider HostStatsProvider, hostStatsProvider HostStatsProvider,
disableAcceleratorUsageMetrics bool, disableAcceleratorUsageMetrics,
podAndContainerStatsFromCRI bool,
) containerStatsProvider { ) containerStatsProvider {
return &criStatsProvider{ return &criStatsProvider{
cadvisor: cadvisor, cadvisor: cadvisor,
@ -90,6 +94,7 @@ func newCRIStatsProvider(
hostStatsProvider: hostStatsProvider, hostStatsProvider: hostStatsProvider,
cpuUsageCache: make(map[string]*cpuUsageRecord), cpuUsageCache: make(map[string]*cpuUsageRecord),
disableAcceleratorUsageMetrics: disableAcceleratorUsageMetrics, disableAcceleratorUsageMetrics: disableAcceleratorUsageMetrics,
podAndContainerStatsFromCRI: podAndContainerStatsFromCRI,
} }
} }
@ -122,21 +127,29 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
return nil, fmt.Errorf("failed to get rootFs info: %v", err) return nil, fmt.Errorf("failed to get rootFs info: %v", err)
} }
containers, err := p.runtimeService.ListContainers(&runtimeapi.ContainerFilter{}) containerMap, podSandboxMap, err := p.getPodAndContainerMaps()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to list all containers: %v", err) return nil, fmt.Errorf("failed to get pod or container map: %v", err)
} }
// Creates pod sandbox map. if p.podAndContainerStatsFromCRI {
podSandboxMap := make(map[string]*runtimeapi.PodSandbox) _, err := p.listPodStatsStrictlyFromCRI(updateCPUNanoCoreUsage, containerMap, podSandboxMap, &rootFsInfo)
podSandboxes, err := p.runtimeService.ListPodSandbox(&runtimeapi.PodSandboxFilter{}) if err != nil {
if err != nil { s, ok := status.FromError(err)
return nil, fmt.Errorf("failed to list all pod sandboxes: %v", err) // Legitimate failure, rather than the CRI implementation does not support ListPodSandboxStats.
} if !ok || s.Code() != codes.Unimplemented {
podSandboxes = removeTerminatedPods(podSandboxes) return nil, err
for _, s := range podSandboxes { }
podSandboxMap[s.Id] = s // CRI implementation doesn't support ListPodSandboxStats, warn and fallback.
klog.V(5).ErrorS(err,
"CRI implementation must be updated to support ListPodSandboxStats if PodAndContainerStatsFromCRI feature gate is enabled. Falling back to populating with cAdvisor; this call will fail in the future.",
)
}
} }
return p.listPodStatsPartiallyFromCRI(updateCPUNanoCoreUsage, containerMap, podSandboxMap, &rootFsInfo)
}
func (p *criStatsProvider) listPodStatsPartiallyFromCRI(updateCPUNanoCoreUsage bool, containerMap map[string]*runtimeapi.Container, podSandboxMap map[string]*runtimeapi.PodSandbox, rootFsInfo *cadvisorapiv2.FsInfo) ([]statsapi.PodStats, error) {
// fsIDtoInfo is a map from filesystem id to its stats. This will be used // fsIDtoInfo is a map from filesystem id to its stats. This will be used
// as a cache to avoid querying cAdvisor for the filesystem stats with the // as a cache to avoid querying cAdvisor for the filesystem stats with the
// same filesystem id many times. // same filesystem id many times.
@ -149,14 +162,6 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to list all container stats: %v", err) return nil, fmt.Errorf("failed to list all container stats: %v", err)
} }
containers = removeTerminatedContainers(containers)
// Creates container map.
containerMap := make(map[string]*runtimeapi.Container)
for _, c := range containers {
containerMap[c.Id] = c
}
allInfos, err := getCadvisorContainerInfo(p.cadvisor) allInfos, err := getCadvisorContainerInfo(p.cadvisor)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch cadvisor stats: %v", err) return nil, fmt.Errorf("failed to fetch cadvisor stats: %v", err)
@ -192,7 +197,7 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
} }
// Fill available stats for full set of required pod stats // Fill available stats for full set of required pod stats
cs := p.makeContainerStats(stats, container, &rootFsInfo, fsIDtoInfo, podSandbox.GetMetadata(), updateCPUNanoCoreUsage) cs := p.makeContainerStats(stats, container, rootFsInfo, fsIDtoInfo, podSandbox.GetMetadata(), updateCPUNanoCoreUsage)
p.addPodNetworkStats(ps, podSandboxID, caInfos, cs, containerNetworkStats[podSandboxID]) p.addPodNetworkStats(ps, podSandboxID, caInfos, cs, containerNetworkStats[podSandboxID])
p.addPodCPUMemoryStats(ps, types.UID(podSandbox.Metadata.Uid), allInfos, cs) p.addPodCPUMemoryStats(ps, types.UID(podSandbox.Metadata.Uid), allInfos, cs)
p.addProcessStats(ps, types.UID(podSandbox.Metadata.Uid), allInfos, cs) p.addProcessStats(ps, types.UID(podSandbox.Metadata.Uid), allInfos, cs)
@ -212,45 +217,92 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
result := make([]statsapi.PodStats, 0, len(sandboxIDToPodStats)) result := make([]statsapi.PodStats, 0, len(sandboxIDToPodStats))
for _, s := range sandboxIDToPodStats { for _, s := range sandboxIDToPodStats {
p.makePodStorageStats(s, &rootFsInfo) p.makePodStorageStats(s, rootFsInfo)
result = append(result, *s) result = append(result, *s)
} }
return result, nil return result, nil
} }
func (p *criStatsProvider) listPodStatsStrictlyFromCRI(updateCPUNanoCoreUsage bool, containerMap map[string]*runtimeapi.Container, podSandboxMap map[string]*runtimeapi.PodSandbox, rootFsInfo *cadvisorapiv2.FsInfo) ([]statsapi.PodStats, error) {
criSandboxStats, err := p.runtimeService.ListPodSandboxStats(&runtimeapi.PodSandboxStatsFilter{})
if err != nil {
return nil, err
}
fsIDtoInfo := make(map[runtimeapi.FilesystemIdentifier]*cadvisorapiv2.FsInfo)
summarySandboxStats := make([]statsapi.PodStats, 0, len(podSandboxMap))
for _, criSandboxStat := range criSandboxStats {
if criSandboxStat == nil || criSandboxStat.Attributes == nil {
klog.V(5).InfoS("Unable to find CRI stats for sandbox")
continue
}
podSandbox, found := podSandboxMap[criSandboxStat.Attributes.Id]
if !found {
continue
}
ps := buildPodStats(podSandbox)
for _, criContainerStat := range criSandboxStat.Linux.Containers {
container, found := containerMap[criContainerStat.Attributes.Id]
if !found {
continue
}
// Fill available stats for full set of required pod stats
cs := p.makeContainerStats(criContainerStat, container, rootFsInfo, fsIDtoInfo, podSandbox.GetMetadata(), updateCPUNanoCoreUsage)
ps.Containers = append(ps.Containers, *cs)
}
addCRIPodNetworkStats(ps, criSandboxStat)
addCRIPodCPUStats(ps, criSandboxStat)
addCRIPodMemoryStats(ps, criSandboxStat)
addCRIPodProcessStats(ps, criSandboxStat)
p.makePodStorageStats(ps, rootFsInfo)
summarySandboxStats = append(summarySandboxStats, *ps)
}
return summarySandboxStats, nil
}
// ListPodCPUAndMemoryStats returns the CPU and Memory stats of all the pod-managed containers. // ListPodCPUAndMemoryStats returns the CPU and Memory stats of all the pod-managed containers.
func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, error) { func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, error) {
containers, err := p.runtimeService.ListContainers(&runtimeapi.ContainerFilter{})
if err != nil {
return nil, fmt.Errorf("failed to list all containers: %v", err)
}
// Creates pod sandbox map.
podSandboxMap := make(map[string]*runtimeapi.PodSandbox)
podSandboxes, err := p.runtimeService.ListPodSandbox(&runtimeapi.PodSandboxFilter{})
if err != nil {
return nil, fmt.Errorf("failed to list all pod sandboxes: %v", err)
}
podSandboxes = removeTerminatedPods(podSandboxes)
for _, s := range podSandboxes {
podSandboxMap[s.Id] = s
}
// sandboxIDToPodStats is a temporary map from sandbox ID to its pod stats. // sandboxIDToPodStats is a temporary map from sandbox ID to its pod stats.
sandboxIDToPodStats := make(map[string]*statsapi.PodStats) sandboxIDToPodStats := make(map[string]*statsapi.PodStats)
containerMap, podSandboxMap, err := p.getPodAndContainerMaps()
if err != nil {
return nil, fmt.Errorf("failed to get pod or container map: %v", err)
}
result := make([]statsapi.PodStats, 0, len(podSandboxMap))
if p.podAndContainerStatsFromCRI {
criSandboxStats, err := p.runtimeService.ListPodSandboxStats(&runtimeapi.PodSandboxStatsFilter{})
// Call succeeded
if err == nil {
for _, criSandboxStat := range criSandboxStats {
podSandbox, found := podSandboxMap[criSandboxStat.Attributes.Id]
if !found {
continue
}
ps := buildPodStats(podSandbox)
addCRIPodCPUStats(ps, criSandboxStat)
addCRIPodMemoryStats(ps, criSandboxStat)
result = append(result, *ps)
}
return result, err
}
// Call failed, why?
s, ok := status.FromError(err)
// Legitimate failure, rather than the CRI implementation does not support ListPodSandboxStats.
if !ok || s.Code() != codes.Unimplemented {
return nil, err
}
// CRI implementation doesn't support ListPodSandboxStats, warn and fallback.
klog.ErrorS(err,
"CRI implementation must be updated to support ListPodSandboxStats if PodAndContainerStatsFromCRI feature gate is enabled. Falling back to populating with cAdvisor; this call will fail in the future.",
)
}
resp, err := p.runtimeService.ListContainerStats(&runtimeapi.ContainerStatsFilter{}) resp, err := p.runtimeService.ListContainerStats(&runtimeapi.ContainerStatsFilter{})
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to list all container stats: %v", err) return nil, fmt.Errorf("failed to list all container stats: %v", err)
} }
containers = removeTerminatedContainers(containers)
// Creates container map.
containerMap := make(map[string]*runtimeapi.Container)
for _, c := range containers {
containerMap[c.Id] = c
}
allInfos, err := getCadvisorContainerInfo(p.cadvisor) allInfos, err := getCadvisorContainerInfo(p.cadvisor)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch cadvisor stats: %v", err) return nil, fmt.Errorf("failed to fetch cadvisor stats: %v", err)
@ -295,13 +347,38 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, erro
// cleanup outdated caches. // cleanup outdated caches.
p.cleanupOutdatedCaches() p.cleanupOutdatedCaches()
result := make([]statsapi.PodStats, 0, len(sandboxIDToPodStats))
for _, s := range sandboxIDToPodStats { for _, s := range sandboxIDToPodStats {
result = append(result, *s) result = append(result, *s)
} }
return result, nil return result, nil
} }
func (p *criStatsProvider) getPodAndContainerMaps() (map[string]*runtimeapi.Container, map[string]*runtimeapi.PodSandbox, error) {
containers, err := p.runtimeService.ListContainers(&runtimeapi.ContainerFilter{})
if err != nil {
return nil, nil, fmt.Errorf("failed to list all containers: %v", err)
}
// Creates pod sandbox map between the pod sandbox ID and the PodSandbox object.
podSandboxMap := make(map[string]*runtimeapi.PodSandbox)
podSandboxes, err := p.runtimeService.ListPodSandbox(&runtimeapi.PodSandboxFilter{})
if err != nil {
return nil, nil, fmt.Errorf("failed to list all pod sandboxes: %v", err)
}
podSandboxes = removeTerminatedPods(podSandboxes)
for _, s := range podSandboxes {
podSandboxMap[s.Id] = s
}
containers = removeTerminatedContainers(containers)
// Creates container map between the container ID and the Container object.
containerMap := make(map[string]*runtimeapi.Container)
for _, c := range containers {
containerMap[c.Id] = c
}
return containerMap, podSandboxMap, nil
}
// ImageFsStats returns the stats of the image filesystem. // ImageFsStats returns the stats of the image filesystem.
func (p *criStatsProvider) ImageFsStats() (*statsapi.FsStats, error) { func (p *criStatsProvider) ImageFsStats() (*statsapi.FsStats, error) {
resp, err := p.imageService.ImageFsInfo() resp, err := p.imageService.ImageFsInfo()
@ -628,12 +705,18 @@ func (p *criStatsProvider) makeContainerCPUAndMemoryStats(
return result return result
} }
// getContainerUsageNanoCores gets the cached usageNanoCores. // getContainerUsageNanoCores first attempts to get the usage nano cores from the stats reported
// by the CRI. If it is unable to, it gets the information from the cache instead.
func (p *criStatsProvider) getContainerUsageNanoCores(stats *runtimeapi.ContainerStats) *uint64 { func (p *criStatsProvider) getContainerUsageNanoCores(stats *runtimeapi.ContainerStats) *uint64 {
if stats == nil || stats.Attributes == nil { if stats == nil || stats.Attributes == nil {
return nil return nil
} }
// Bypass the cache if the CRI implementation specified the UsageNanoCores.
if stats.Cpu != nil && stats.Cpu.UsageNanoCores != nil {
return &stats.Cpu.UsageNanoCores.Value
}
p.mutex.RLock() p.mutex.RLock()
defer p.mutex.RUnlock() defer p.mutex.RUnlock()
@ -646,11 +729,19 @@ func (p *criStatsProvider) getContainerUsageNanoCores(stats *runtimeapi.Containe
return &latestUsage return &latestUsage
} }
// getContainerUsageNanoCores computes usageNanoCores based on the given and // getAndUpdateContainerUsageNanoCores first attempts to get the usage nano cores from the stats reported
// the cached usageCoreNanoSeconds, updates the cache with the computed // by the CRI. If it is unable to, it computes usageNanoCores based on the given and the cached usageCoreNanoSeconds,
// usageNanoCores, and returns the usageNanoCores. // updates the cache with the computed usageNanoCores, and returns the usageNanoCores.
func (p *criStatsProvider) getAndUpdateContainerUsageNanoCores(stats *runtimeapi.ContainerStats) *uint64 { func (p *criStatsProvider) getAndUpdateContainerUsageNanoCores(stats *runtimeapi.ContainerStats) *uint64 {
if stats == nil || stats.Attributes == nil || stats.Cpu == nil || stats.Cpu.UsageCoreNanoSeconds == nil { if stats == nil || stats.Attributes == nil || stats.Cpu == nil {
return nil
}
// Bypass the cache if the CRI implementation specified the UsageNanoCores.
if stats.Cpu.UsageNanoCores != nil {
return &stats.Cpu.UsageNanoCores.Value
}
// If there is no UsageNanoCores, nor UsageCoreNanoSeconds, there is no information to use
if stats.Cpu.UsageCoreNanoSeconds == nil {
return nil return nil
} }
id := stats.Attributes.Id id := stats.Attributes.Id
@ -847,3 +938,73 @@ func extractIDFromCgroupPath(cgroupPath string) string {
} }
return id return id
} }
func addCRIPodNetworkStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) {
if criPodStat == nil || criPodStat.Linux == nil || criPodStat.Linux.Network == nil {
return
}
criNetwork := criPodStat.Linux.Network
iStats := statsapi.NetworkStats{
Time: metav1.NewTime(time.Unix(0, criNetwork.Timestamp)),
InterfaceStats: criInterfaceToSummary(criNetwork.DefaultInterface),
Interfaces: make([]statsapi.InterfaceStats, 0, len(criNetwork.Interfaces)),
}
for _, iface := range criNetwork.Interfaces {
iStats.Interfaces = append(iStats.Interfaces, criInterfaceToSummary(iface))
}
ps.Network = &iStats
}
func criInterfaceToSummary(criIface *runtimeapi.NetworkInterfaceUsage) statsapi.InterfaceStats {
return statsapi.InterfaceStats{
Name: criIface.Name,
RxBytes: valueOfUInt64Value(criIface.RxBytes),
RxErrors: valueOfUInt64Value(criIface.RxErrors),
TxBytes: valueOfUInt64Value(criIface.TxBytes),
TxErrors: valueOfUInt64Value(criIface.TxErrors),
}
}
func addCRIPodCPUStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) {
if criPodStat == nil || criPodStat.Linux == nil || criPodStat.Linux.Cpu == nil {
return
}
criCPU := criPodStat.Linux.Cpu
ps.CPU = &statsapi.CPUStats{
Time: metav1.NewTime(time.Unix(0, criCPU.Timestamp)),
UsageNanoCores: valueOfUInt64Value(criCPU.UsageNanoCores),
UsageCoreNanoSeconds: valueOfUInt64Value(criCPU.UsageCoreNanoSeconds),
}
}
func addCRIPodMemoryStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) {
if criPodStat == nil || criPodStat.Linux == nil || criPodStat.Linux.Memory == nil {
return
}
criMemory := criPodStat.Linux.Memory
ps.Memory = &statsapi.MemoryStats{
Time: metav1.NewTime(time.Unix(0, criMemory.Timestamp)),
AvailableBytes: valueOfUInt64Value(criMemory.AvailableBytes),
UsageBytes: valueOfUInt64Value(criMemory.UsageBytes),
WorkingSetBytes: valueOfUInt64Value(criMemory.WorkingSetBytes),
RSSBytes: valueOfUInt64Value(criMemory.RssBytes),
PageFaults: valueOfUInt64Value(criMemory.PageFaults),
MajorPageFaults: valueOfUInt64Value(criMemory.MajorPageFaults),
}
}
func addCRIPodProcessStats(ps *statsapi.PodStats, criPodStat *runtimeapi.PodSandboxStats) {
if criPodStat == nil || criPodStat.Linux == nil || criPodStat.Linux.Process == nil {
return
}
ps.ProcessStats = &statsapi.ProcessStats{
ProcessCount: valueOfUInt64Value(criPodStat.Linux.Process.ProcessCount),
}
}
func valueOfUInt64Value(value *runtimeapi.UInt64Value) *uint64 {
if value == nil {
return nil
}
return &value.Value
}

View File

@ -236,6 +236,7 @@ func TestCRIListPodStats(t *testing.T) {
fakeImageService, fakeImageService,
NewFakeHostStatsProviderWithData(fakeStats, fakeOS), NewFakeHostStatsProviderWithData(fakeStats, fakeOS),
false, false,
false,
) )
stats, err := provider.ListPodStats() stats, err := provider.ListPodStats()
@ -396,6 +397,7 @@ func TestAcceleratorUsageStatsCanBeDisabled(t *testing.T) {
fakeImageService, fakeImageService,
NewFakeHostStatsProvider(), NewFakeHostStatsProvider(),
true, // this is what the test is actually testing true, // this is what the test is actually testing
false,
) )
stats, err := provider.ListPodStats() stats, err := provider.ListPodStats()
@ -541,6 +543,7 @@ func TestCRIListPodCPUAndMemoryStats(t *testing.T) {
nil, nil,
NewFakeHostStatsProvider(), NewFakeHostStatsProvider(),
false, false,
false,
) )
stats, err := provider.ListPodCPUAndMemoryStats() stats, err := provider.ListPodCPUAndMemoryStats()
@ -671,6 +674,7 @@ func TestCRIImagesFsStats(t *testing.T) {
fakeImageService, fakeImageService,
NewFakeHostStatsProvider(), NewFakeHostStatsProvider(),
false, false,
false,
) )
stats, err := provider.ImageFsStats() stats, err := provider.ImageFsStats()

View File

@ -42,10 +42,10 @@ func NewCRIStatsProvider(
runtimeService internalapi.RuntimeService, runtimeService internalapi.RuntimeService,
imageService internalapi.ImageManagerService, imageService internalapi.ImageManagerService,
hostStatsProvider HostStatsProvider, hostStatsProvider HostStatsProvider,
disableAcceleratorUsageMetrics bool, disableAcceleratorUsageMetrics, podAndContainerStatsFromCRI bool,
) *Provider { ) *Provider {
return newStatsProvider(cadvisor, podManager, runtimeCache, newCRIStatsProvider(cadvisor, resourceAnalyzer, return newStatsProvider(cadvisor, podManager, runtimeCache, newCRIStatsProvider(cadvisor, resourceAnalyzer,
runtimeService, imageService, hostStatsProvider, disableAcceleratorUsageMetrics)) runtimeService, imageService, hostStatsProvider, disableAcceleratorUsageMetrics, podAndContainerStatsFromCRI))
} }
// NewCadvisorStatsProvider returns a containerStatsProvider that provides both // NewCadvisorStatsProvider returns a containerStatsProvider that provides both