1
16
17
18 package stats
19
20 import (
21 "context"
22 "fmt"
23
24 "k8s.io/klog/v2"
25
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
28 "k8s.io/kubernetes/pkg/kubelet/util"
29 )
30
31
32 type SummaryProvider interface {
33
34
35 Get(ctx context.Context, updateStats bool) (*statsapi.Summary, error)
36
37 GetCPUAndMemoryStats(ctx context.Context) (*statsapi.Summary, error)
38 }
39
40
41 type summaryProviderImpl struct {
42
43 kubeletCreationTime metav1.Time
44
45 systemBootTime metav1.Time
46
47 provider Provider
48 }
49
50 var _ SummaryProvider = &summaryProviderImpl{}
51
52
53
54 func NewSummaryProvider(statsProvider Provider) SummaryProvider {
55 kubeletCreationTime := metav1.Now()
56 bootTime, err := util.GetBootTime()
57 if err != nil {
58
59 klog.InfoS("Error getting system boot time. Node metrics will have an incorrect start time", "err", err)
60 }
61
62 return &summaryProviderImpl{
63 kubeletCreationTime: kubeletCreationTime,
64 systemBootTime: metav1.NewTime(bootTime),
65 provider: statsProvider,
66 }
67 }
68
69 func (sp *summaryProviderImpl) Get(ctx context.Context, updateStats bool) (*statsapi.Summary, error) {
70
71
72 node, err := sp.provider.GetNode()
73 if err != nil {
74 return nil, fmt.Errorf("failed to get node info: %v", err)
75 }
76 nodeConfig := sp.provider.GetNodeConfig()
77 rootStats, networkStats, err := sp.provider.GetCgroupStats("/", updateStats)
78 if err != nil {
79 return nil, fmt.Errorf("failed to get root cgroup stats: %v", err)
80 }
81 rootFsStats, err := sp.provider.RootFsStats()
82 if err != nil {
83 return nil, fmt.Errorf("failed to get rootFs stats: %v", err)
84 }
85 imageFsStats, containerFsStats, err := sp.provider.ImageFsStats(ctx)
86 if err != nil {
87 return nil, fmt.Errorf("failed to get imageFs stats: %v", err)
88 }
89 var podStats []statsapi.PodStats
90 if updateStats {
91 podStats, err = sp.provider.ListPodStatsAndUpdateCPUNanoCoreUsage(ctx)
92 } else {
93 podStats, err = sp.provider.ListPodStats(ctx)
94 }
95 if err != nil {
96 return nil, fmt.Errorf("failed to list pod stats: %v", err)
97 }
98
99 rlimit, err := sp.provider.RlimitStats()
100 if err != nil {
101 return nil, fmt.Errorf("failed to get rlimit stats: %v", err)
102 }
103
104 nodeStats := statsapi.NodeStats{
105 NodeName: node.Name,
106 CPU: rootStats.CPU,
107 Memory: rootStats.Memory,
108 Swap: rootStats.Swap,
109 Network: networkStats,
110 StartTime: sp.systemBootTime,
111 Fs: rootFsStats,
112 Runtime: &statsapi.RuntimeStats{ContainerFs: containerFsStats, ImageFs: imageFsStats},
113 Rlimit: rlimit,
114 SystemContainers: sp.GetSystemContainersStats(nodeConfig, podStats, updateStats),
115 }
116 summary := statsapi.Summary{
117 Node: nodeStats,
118 Pods: podStats,
119 }
120 return &summary, nil
121 }
122
123 func (sp *summaryProviderImpl) GetCPUAndMemoryStats(ctx context.Context) (*statsapi.Summary, error) {
124
125
126 node, err := sp.provider.GetNode()
127 if err != nil {
128 return nil, fmt.Errorf("failed to get node info: %v", err)
129 }
130 nodeConfig := sp.provider.GetNodeConfig()
131 rootStats, err := sp.provider.GetCgroupCPUAndMemoryStats("/", false)
132 if err != nil {
133 return nil, fmt.Errorf("failed to get root cgroup stats: %v", err)
134 }
135
136 podStats, err := sp.provider.ListPodCPUAndMemoryStats(ctx)
137 if err != nil {
138 return nil, fmt.Errorf("failed to list pod stats: %v", err)
139 }
140
141 nodeStats := statsapi.NodeStats{
142 NodeName: node.Name,
143 CPU: rootStats.CPU,
144 Memory: rootStats.Memory,
145 Swap: rootStats.Swap,
146 StartTime: rootStats.StartTime,
147 SystemContainers: sp.GetSystemContainersCPUAndMemoryStats(nodeConfig, podStats, false),
148 }
149 summary := statsapi.Summary{
150 Node: nodeStats,
151 Pods: podStats,
152 }
153 return &summary, nil
154 }
155
View as plain text