k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/kubelet/cadvisor/cadvisor_linux.go (about) 1 //go:build linux 2 // +build linux 3 4 /* 5 Copyright 2015 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package cadvisor 21 22 import ( 23 "flag" 24 "fmt" 25 "net/http" 26 "os" 27 "path" 28 "time" 29 30 // Register supported container handlers. 31 _ "github.com/google/cadvisor/container/containerd/install" 32 _ "github.com/google/cadvisor/container/crio/install" 33 _ "github.com/google/cadvisor/container/systemd/install" 34 35 "github.com/google/cadvisor/cache/memory" 36 cadvisormetrics "github.com/google/cadvisor/container" 37 cadvisorapi "github.com/google/cadvisor/info/v1" 38 cadvisorapiv2 "github.com/google/cadvisor/info/v2" 39 "github.com/google/cadvisor/manager" 40 "github.com/google/cadvisor/utils/sysfs" 41 "k8s.io/klog/v2" 42 "k8s.io/utils/pointer" 43 ) 44 45 type cadvisorClient struct { 46 imageFsInfoProvider ImageFsInfoProvider 47 rootPath string 48 manager.Manager 49 } 50 51 var _ Interface = new(cadvisorClient) 52 53 // TODO(vmarmol): Make configurable. 54 // The amount of time for which to keep stats in memory. 55 const statsCacheDuration = 2 * time.Minute 56 const maxHousekeepingInterval = 15 * time.Second 57 const defaultHousekeepingInterval = 10 * time.Second 58 const allowDynamicHousekeeping = true 59 60 func init() { 61 // Override cAdvisor flag defaults. 62 flagOverrides := map[string]string{ 63 // Override the default cAdvisor housekeeping interval. 64 "housekeeping_interval": defaultHousekeepingInterval.String(), 65 // Disable event storage by default. 66 "event_storage_event_limit": "default=0", 67 "event_storage_age_limit": "default=0", 68 } 69 for name, defaultValue := range flagOverrides { 70 if f := flag.Lookup(name); f != nil { 71 f.DefValue = defaultValue 72 f.Value.Set(defaultValue) 73 } else { 74 klog.ErrorS(nil, "Expected cAdvisor flag not found", "flag", name) 75 } 76 } 77 } 78 79 // New creates a new cAdvisor Interface for linux systems. 80 func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string, usingLegacyStats, localStorageCapacityIsolation bool) (Interface, error) { 81 sysFs := sysfs.NewRealSysFs() 82 83 includedMetrics := cadvisormetrics.MetricSet{ 84 cadvisormetrics.CpuUsageMetrics: struct{}{}, 85 cadvisormetrics.MemoryUsageMetrics: struct{}{}, 86 cadvisormetrics.CpuLoadMetrics: struct{}{}, 87 cadvisormetrics.DiskIOMetrics: struct{}{}, 88 cadvisormetrics.NetworkUsageMetrics: struct{}{}, 89 cadvisormetrics.AppMetrics: struct{}{}, 90 cadvisormetrics.ProcessMetrics: struct{}{}, 91 cadvisormetrics.OOMMetrics: struct{}{}, 92 } 93 94 if usingLegacyStats || localStorageCapacityIsolation { 95 includedMetrics[cadvisormetrics.DiskUsageMetrics] = struct{}{} 96 } 97 98 duration := maxHousekeepingInterval 99 housekeepingConfig := manager.HousekeepingConfig{ 100 Interval: &duration, 101 AllowDynamic: pointer.Bool(allowDynamicHousekeeping), 102 } 103 104 // Create the cAdvisor container manager. 105 m, err := manager.New(memory.New(statsCacheDuration, nil), sysFs, housekeepingConfig, includedMetrics, http.DefaultClient, cgroupRoots, nil /* containerEnvMetadataWhiteList */, "" /* perfEventsFile */, time.Duration(0) /*resctrlInterval*/) 106 if err != nil { 107 return nil, err 108 } 109 110 if _, err := os.Stat(rootPath); err != nil { 111 if os.IsNotExist(err) { 112 if err := os.MkdirAll(path.Clean(rootPath), 0750); err != nil { 113 return nil, fmt.Errorf("error creating root directory %q: %v", rootPath, err) 114 } 115 } else { 116 return nil, fmt.Errorf("failed to Stat %q: %v", rootPath, err) 117 } 118 } 119 120 return &cadvisorClient{ 121 imageFsInfoProvider: imageFsInfoProvider, 122 rootPath: rootPath, 123 Manager: m, 124 }, nil 125 } 126 127 func (cc *cadvisorClient) Start() error { 128 return cc.Manager.Start() 129 } 130 131 func (cc *cadvisorClient) ContainerInfoV2(name string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) { 132 return cc.GetContainerInfoV2(name, options) 133 } 134 135 func (cc *cadvisorClient) VersionInfo() (*cadvisorapi.VersionInfo, error) { 136 return cc.GetVersionInfo() 137 } 138 139 func (cc *cadvisorClient) MachineInfo() (*cadvisorapi.MachineInfo, error) { 140 return cc.GetMachineInfo() 141 } 142 143 func (cc *cadvisorClient) ImagesFsInfo() (cadvisorapiv2.FsInfo, error) { 144 label, err := cc.imageFsInfoProvider.ImageFsInfoLabel() 145 if err != nil { 146 return cadvisorapiv2.FsInfo{}, err 147 } 148 return cc.getFsInfo(label) 149 } 150 151 func (cc *cadvisorClient) RootFsInfo() (cadvisorapiv2.FsInfo, error) { 152 return cc.GetDirFsInfo(cc.rootPath) 153 } 154 155 func (cc *cadvisorClient) getFsInfo(label string) (cadvisorapiv2.FsInfo, error) { 156 res, err := cc.GetFsInfo(label) 157 if err != nil { 158 return cadvisorapiv2.FsInfo{}, err 159 } 160 if len(res) == 0 { 161 return cadvisorapiv2.FsInfo{}, fmt.Errorf("failed to find information for the filesystem labeled %q", label) 162 } 163 // TODO(vmarmol): Handle this better when a label has more than one image filesystem. 164 if len(res) > 1 { 165 klog.InfoS("More than one filesystem labeled. Only using the first one", "label", label, "fileSystem", res) 166 } 167 168 return res[0], nil 169 } 170 171 func (cc *cadvisorClient) ContainerFsInfo() (cadvisorapiv2.FsInfo, error) { 172 label, err := cc.imageFsInfoProvider.ContainerFsInfoLabel() 173 if err != nil { 174 return cadvisorapiv2.FsInfo{}, err 175 } 176 return cc.getFsInfo(label) 177 }