github.com/google/cadvisor@v0.49.1/container/crio/factory.go (about) 1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package crio 16 17 import ( 18 "fmt" 19 "path" 20 "regexp" 21 "strings" 22 23 "github.com/google/cadvisor/container" 24 "github.com/google/cadvisor/container/libcontainer" 25 "github.com/google/cadvisor/fs" 26 info "github.com/google/cadvisor/info/v1" 27 "github.com/google/cadvisor/watcher" 28 29 "k8s.io/klog/v2" 30 ) 31 32 // The namespace under which crio aliases are unique. 33 const CrioNamespace = "crio" 34 35 // The namespace suffix under which crio aliases are unique. 36 const CrioNamespaceSuffix = ".scope" 37 38 // The namespace systemd runs components under. 39 const SystemdNamespace = "system-systemd" 40 41 // Regexp that identifies CRI-O cgroups 42 var crioCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`) 43 44 type storageDriver string 45 46 const ( 47 // TODO add full set of supported drivers in future.. 48 overlayStorageDriver storageDriver = "overlay" 49 overlay2StorageDriver storageDriver = "overlay2" 50 ) 51 52 type crioFactory struct { 53 machineInfoFactory info.MachineInfoFactory 54 55 storageDriver storageDriver 56 storageDir string 57 58 // Information about the mounted cgroup subsystems. 59 cgroupSubsystems map[string]string 60 61 // Information about mounted filesystems. 62 fsInfo fs.FsInfo 63 64 includedMetrics container.MetricSet 65 66 client CrioClient 67 } 68 69 func (f *crioFactory) String() string { 70 return CrioNamespace 71 } 72 73 func (f *crioFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) { 74 client, err := Client() 75 if err != nil { 76 return 77 } 78 handler, err = newCrioContainerHandler( 79 client, 80 name, 81 f.machineInfoFactory, 82 f.fsInfo, 83 f.storageDriver, 84 f.storageDir, 85 f.cgroupSubsystems, 86 inHostNamespace, 87 metadataEnvAllowList, 88 f.includedMetrics, 89 ) 90 return 91 } 92 93 // Returns the CRIO ID from the full container name. 94 func ContainerNameToCrioId(name string) string { 95 id := path.Base(name) 96 97 if matches := crioCgroupRegexp.FindStringSubmatch(id); matches != nil { 98 return matches[1] 99 } 100 101 return id 102 } 103 104 // isContainerName returns true if the cgroup with associated name 105 // corresponds to a crio container. 106 func isContainerName(name string) bool { 107 // always ignore .mount cgroup even if associated with crio and delegate to systemd 108 if strings.HasSuffix(name, ".mount") { 109 return false 110 } 111 return crioCgroupRegexp.MatchString(path.Base(name)) 112 } 113 114 // crio handles all containers under /crio 115 func (f *crioFactory) CanHandleAndAccept(name string) (bool, bool, error) { 116 if strings.HasPrefix(path.Base(name), "crio-conmon") { 117 // TODO(runcom): should we include crio-conmon cgroups? 118 return false, false, nil 119 } 120 if strings.HasPrefix(path.Base(name), SystemdNamespace) { 121 return true, false, nil 122 } 123 if !strings.HasPrefix(path.Base(name), CrioNamespace) { 124 return false, false, nil 125 } 126 // if the container is not associated with CRI-O, we can't handle it or accept it. 127 if !isContainerName(name) { 128 return false, false, nil 129 } 130 131 if !strings.HasSuffix(path.Base(name), CrioNamespaceSuffix) { 132 // this mean it's a sandbox container 133 return true, false, nil 134 } 135 return true, true, nil 136 } 137 138 func (f *crioFactory) DebugInfo() map[string][]string { 139 return map[string][]string{} 140 } 141 142 // Register root container before running this function! 143 func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) error { 144 client, err := Client() 145 if err != nil { 146 return err 147 } 148 149 info, err := client.Info() 150 if err != nil { 151 return err 152 } 153 154 // TODO determine crio version so we can work differently w/ future versions if needed 155 156 cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics) 157 if err != nil { 158 return fmt.Errorf("failed to get cgroup subsystems: %v", err) 159 } 160 161 klog.V(1).Infof("Registering CRI-O factory") 162 f := &crioFactory{ 163 client: client, 164 cgroupSubsystems: cgroupSubsystems, 165 fsInfo: fsInfo, 166 machineInfoFactory: factory, 167 storageDriver: storageDriver(info.StorageDriver), 168 storageDir: info.StorageRoot, 169 includedMetrics: includedMetrics, 170 } 171 172 container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw}) 173 return nil 174 }