In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "how cAdvisor gets the information of machine and docker container". In the daily operation, I believe that many people have doubts about how cAdvisor gets the information of machine and docker container. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the questions of "how cAdvisor gets the information of machine and docker container". Next, please follow the editor to study!
Entrance
CAdvisor code managed address
Code entry: github.com/google/cadvisor/cadvisor.go
API handler: github.com/google/cadvisor/api/handler.go
Based on tag: v0.19.2
# github.com/google/cadvisor/cadvisor.go... .. 73 containerManager, err: = manager.New (memoryStorage, sysFs, * maxHousekeepingInterval, * allowDynamicHousekeeping) 74 if err! = nil {75 glog.Fatalf ("Failed to create a Container Manager:% s", err) 76} 7778 mux: = http.DefaultServeMux7980 / / Register all HTTP handlers.81 err = cadvisorHttp.RegisterHandlers (mux, containerManager, * httpAuthFile, * httpAuthRealm, * httpDigestFile * httpDigestRealm) 82 if err! = nil {83 glog.Fatalf ("Failed to register HTTP handlers:% v", err) 84} 8586 cadvisorHttp.RegisterPrometheusHandler (mux, containerManager, * prometheusEndpoint, nil) 8788 / / Start the manager.89 if err: = containerManager.Start () Err! = nil {90 glog.Fatalf ("Failed to start container manager:% v", err) 91}.
From the entrance, we can know that the interface that really gets container and machine information is Manager,github.com/google/cadvisor/manager/manager.go.
# github.com/google/cadvisor/manager/manager.go52 / / The Manager interface defines operations for starting a manager and getting53 / / container and machine information.54 type Manager interface {55 / / Start the manager. Calling other manager methods before this returns56 / / may produce undefined behavior.57 Start () error5859 / / Stops the manager.60 Stop () error6162 / / Get information about a container.63 GetContainerInfo (containerName string, query * info.ContainerInfoRequest) (* info.ContainerInfo, error). ...
The following is a specific explanation of how cadvisor obtains the information of machine and docker container in combination with the code.
MachineInfo # github.com/google/cadvisor/manager/manager.go158 machineInfo, err: = getMachineInfo (sysfs, fsInfo) / / get machine information here through the getMachineInfo () function 159 if err! = nil {160 return nil, err161} 162 newManager.machineInfo = * machineInfo163 glog.Infof ("Machine:% + v", newManager.machineInfo)
Get the concrete function getMachineInfo () of machineinfo
# github.com/google/cadvisor/manager/machine.go52 func getMachineInfo (sysFs sysfs.SysFs, fsInfo fs.FsInfo) (* info.MachineInfo, error) {53 cpuinfo, err: = ioutil.ReadFile ("/ proc/cpuinfo") 54 clockSpeed, err: = machine.GetClockSpeed (cpuinfo) 55 if err! = nil {56 return nil, err57} 58. ...
MachineInfo data structure:
# github.com/google/cadvisor/info/v1/machine.go131 type MachineInfo struct {132 / / The number of cores in this machine.133 NumCores int `json: "num_cores" `134135 / / Maximum clock speed for the cores In KHz.136 CpuFrequency uint64 `json: "cpu_frequency_khz" `137138 / / The amount of memory (in bytes) in this machine139 MemoryCapacity int64 `json: "memory_capacity" `140141 / / The machine id142 MachineID string `json: "machine_id" `143144 / / The system uuid145 SystemUUID string `json: "system_uuid" `146147 / / The boot id148 BootID string `json: "boot_id" `149150 / / Filesystems on this machine.151 Filesystems [] FsInfo `json: "filesystems" `152153 / / Disk map154 DiskMap map`string] DiskInfo `json: "disk_map" `155156 / / Network devices157 NetworkDevices [] NetInfo `json: "network_devices" `158159 / / Machine Topology160 / / Describes cpu/memory layout and hierarchy.161 Topology [] Node `json: "topology" `162163 / / Cloud provider the machine belongs to.164 CloudProvider CloudProvider `json: "cloud_provider" `165166 / / Type of cloud instance (e.g. GCE standard) the machine is .167 InstanceType InstanceType `json: "instance_type" `168}
Cpu / proc/cpuinfo
Mem / proc/meminfo
# github.com/google/cadvisor/utils/machine/machine.go76 func GetMachineMemoryCapacity () (int64, error) {77 out, err: = ioutil.ReadFile ("/ proc/meminfo") 78 if err! = nil {79 return 0, err80} 8182 memoryCapacity, err: = parseCapacity (out, memoryCapacityRegexp) 83 if err! = nil {84 return 0, err85} 86 return memoryCapacity, err87}
Machine_id / var/lib/dbus/machine-id
Boot_id / proc/sys/kernel/random/boot_id
➜~ cat / var/lib/dbus/machine-ida8919ec7c9ee43bd1bcaf6cd55e1a7bc➜ ~ cat / proc/sys/kernel/random/boot_id2f6bac7f-738a-4d85-8b58-53e71296119e
Disk / proc/diskstats
# github.com/google/cadvisor/fs/fs.go189 func (self * RealFsInfo) GetFsInfoForPath (mountSet map [string] struct {}) ([] Fs, error) {190 filesystems: = make ([] Fs, 0) 191 deviceSet: = make (map [string] struct {}) 192 diskStatsMap, err: = getDiskStatsMap ("/ proc/diskstats") / / disk status gets 193 if err! = nil {194 return nil through / proc/diskstats Err195}......
For the pool value assigned to the container, if it is of type device mapper, the device usage is obtained through dmsetup status pool_device_name
# github.com/google/cadvisor/fs/fs.go... .. 205 case "devicemapper": 206total, free, avail, err = getDMStats (device, partition.blockSize).
Get disk device information / sys/block
# github.com/google/cadvisor/utils/sysinfo/sysinfo.go31 func GetBlockDeviceInfo (sysfs sysfs.SysFs) (map [string] info.DiskInfo, error) {32 disks, err: = sysfs.GetBlockDevices () / / cadvisor/utils/sysfs/sysfs.go GetBlockDevices () you can get the disk device name through / sys/block Other information is the same as 33 if err! = nil {34 return nil, err35}. ➜~ cat / sys/block/sda/dev # Primary and secondary device number 8:0➜ ~ cat / sys/block/sda/size # disk device size 976773168 ➜~ cat / sys/block/sda/queue/scheduler # disk scheduling type noop deadline [cfq]➜ ~
NetDevices / sys/class/net
# github.com/google/cadvisor/utils/sysinfo/sysinfo.go87 func GetNetworkDevices (sysfs sysfs.SysFs) ([] info.NetInfo, error) {88 devs, err: = sysfs.GetNetworkDevices () 89 if err! = nil {90 return nil Err91} 92 netDevices: = [] info.NetInfo {}.. ➜~ cat / sys/class/net/eth0/addressf0:76:1c:6d:26:d6➜ ~ cat / sys/class/net/eth0/mtu1500 ➜~ cat / sys/class/net/eth0/speed10
System UUID / sys/class/dmi/id/product_uuid
➜~ sudo cat / sys/class/dmi/id/product_uuidF27316D5-4DB3-E411-A26A-F0761C6D26D6➜ ~ Docker Info# github.com/google/cadvisor/manager/manager.go201 / / Start the container manager.202 func (self * manager) Start () error {203 / / Register Docker container factory.204 err: = docker.Register (self, self.fsInfo) 205 if err! = nil {206glog.Errorf ("Docker container factory registration failed:% v.", err) 207}.
CAdvisor starts container manager and determines the creation and deletion of docker by calling the Linux system inotify to monitor the file changes in the cgroup docker directory.
Getprocesslist
CAdvisor first determines whether it is running in container, and if so, chroot / rootfs (cAdvisor runs in container will send the system / mount to / rootfs through volume) and then executes ps-e-o user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm,cgrou, otherwise it directly executes the acquisition. (github.com/google/cadvisor/manager/container.go GetProcessList () function implementation)
# github.com/google/cadvisor/manager/manager.go687 func (m * manager) GetProcessList (containerName string, options v2.RequestOptions) ([] v2.ProcessInfo, error) {688 / / override recursive. Only support single container listing.689 options.Recursive = false690 conts, err: = m.getRequestedContainers (containerName, options) 691if err! = nil {692return nil, err693} 694if len (conts)! = 1 {695 return nil, fmt.Errorf ("Expected the request to match only one container") 696}.
If you get the global processlist instead of the processlist of a container, the containername defaults to "/", and the judgment logic is as follows:
# github.com/google/cadvisor/manager/container.go273 if isRoot | | c.info.Name = = cgroup {274 processes = append (processes, v2.ProcessInfo {275 User: fields [0], 276 Pid: pid,277 Ppid: ppid,278 StartTime: fields [3] PercentCpu: float32 (percentCpu),... ContainerInfo
Get the info data of the specified container:
# github.com/google/cadvisor manager/manager.go531 func (self * manager) DockerContainer (containerName string, query * info.ContainerInfoRequest) (info.ContainerInfo, error) {532 container, err: = self.getDockerContainer (containerName) 533 if err! = nil {534 return info.ContainerInfo {}, err535} 536. ...
Specific acquisition function:
# github.com/google/cadvisor/manager/container.go102 func (c * containerData) GetInfo () (* containerInfo, error) {103 / / Get spec and subcontainers.104 if time.Since (c.lastUpdatedTime) > 5*time.Second {/ / you can see that info data will be updated only when the last update time exceeds 5s err: = c.updateSpec () 106 if err! = nil {107return nil Err108}......
ContainerSpec
The logic for cAdvisor to get the overall ContainerSpec is to find the corresponding system Spec json file corresponding to the container.
Container info handler:
# github.com/google/cadvisor/container/docker/handler.go220 func (self * dockerContainerHandler) GetSpec () (info.ContainerSpec, error) {221 mi, err: = self.machineInfoFactory.GetMachineInfo () 2222if err! = nil {223 return info.ContainerSpec {}, err224}
/ proc/self/mountinfo mount information of the currently running process
/ proc/cgroups cgroup types supported by the current kernel
Libcontainer configpath / var/run/docker/execdriver/native/containerId
# github.com/google/cadvisor/container/libcontainer/compatibility.go reads libcontainer config file information 150 func ReadConfig (dockerRoot, dockerRun, containerID string) (* configs.Config, error) {151 / / Try using the new config if it is available.152 configPath: = configPath (dockerRun, containerID) 153 if utils.FileExists (configPath) {154out, err: = ioutil.ReadFile (configPath) 155if err! = nil {156return nil Err157} 158159 var state libcontainer.State160 err = json.Unmarshal (out, & state) 161if err! = nil {162return nil, err163} 164return & state.Config, nil165} # github.com/google/cadvisor/container/docker/handler.go disk utilization statistics currently supports aufs This is the reason why there is no filesystem size on CentOS7 at present. 232 / / For now only enable for aufs filesystems233 spec.HasFilesystem = self.storageDriver = = aufsStorageDriver... .. 241 func (self * dockerContainerHandler) getFsStats (stats * info.ContainerStats) error {242 / / No support for non-aufs storage drivers.243 if self.storageDriver! = aufsStorageDriver {244 return nil245}.
File system related # github.com/google/cadvisor/fs/fs.go
Aufs storage dir: / var/lib/docker/aufs/diff/containerId
Get cgroup and network status
# github.com/google/cadvisor/container/docker/handler.go# cgroup information is to call github.com/docker/libcontainer/cgroups to get 276 func (self * dockerContainerHandler) GetStats () (* info.ContainerStats, error) {277 stats, err: = containerLibcontainer.GetStats (self.cgroupManager, self.rootFs, self.pid) 278 if err! = nil {279 return stats Err280} 281 / / Clean up stats for containers that don't have their own network-this282 / / includes containers running in Kubernetes pods that use the network of the283 / / infrastructure container This stops metrics being reported multiple times284 / / for each container in a pod. If container does not have its own network, it returns null. For K8s pod, the internal container communicates through the pause container network: if! hasNet (self.networkMode) {286 stats.Network = info.NetworkStats {} 287} 288289 / / Get filesystem stats.290 err = self.getFsStats (stats) 291 if err! = nil {292 return stats, err293} 294295 return stats, nil296}
Specifically get the functions of cgroup and network to implement GetStats ()
Container Network status / proc//net/dev
# github.com/google/cadvisor/container/libcontainer/helpers.go81 / / Get cgroup and networking stats of the specified container82 func GetStats (cgroupManager cgroups.Manager, rootFs string, pid int) (* info.ContainerStats, error) {83 cgroupStats, err: = cgroupManager.GetStats () 84 if err! = nil {85 return nil, err86} 87 libcontainerStats: = & libcontainer.Stats {88 CgroupStats: cgroupStats 89} 90 stats: = toContainerStats (libcontainerStats) 9192 / / If we know the pid then get network stats from / proc//net/dev93 if pid > 0 {94 netStats, err: = networkStatsFromProc (rootFs, pid) 95 if err! = nil {96 glog.V (2) .Infof ("Unable to get network stats from pid% d:% v", pid Err) 97} else {98 stats.Network.Interfaces = append (stats.Network.Interfaces, netStats...) 99}.
Cgroup status contains the following information (cadVisor calls licontainer/cgroups to obtain the corresponding cgroup information of container):
# github.com/docker/libcontainer/cgroups/stats.go88 func NewStats () * Stats {89 memoryStats: = MemoryStats {Stats: make (map [string] uint64)} 90 hugetlbStats: = make (map [string] HugetlbStats) 91 return & Stats {MemoryStats: memoryStats, HugetlbStats: hugetlbStats} 92} this ends the study of "how cAdvisor gets information about machine and docker container", hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.