久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

cAdvisor如何獲取到machine和docker container的信息

161次閱讀
沒有評論

共計 11391 個字符,預計需要花費 29 分鐘才能閱讀完成。

這篇文章主要介紹“cAdvisor 如何獲取到 machine 和 docker container 的信息”,在日常操作中,相信很多人在 cAdvisor 如何獲取到 machine 和 docker container 的信息問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”cAdvisor 如何獲取到 machine 和 docker container 的信息”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

入口

cAdvisor 代碼托管地址

代碼入口:github.com/google/cadvisor/cadvisor.go

API handler: github.com/google/cadvisor/api/handler.go

基于 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 }
78 mux := http.DefaultServeMux
80 // 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 }
86 cadvisorHttp.RegisterPrometheusHandler(mux, containerManager, *prometheusEndpoint, nil)
88 // Start the manager.
89 if err := containerManager.Start(); err != nil {90 glog.Fatalf( Failed to start container manager: %v , err)
91 }
... ...

從入口可以得知真正獲取 container 和 machine 信息的 interface 為 Manager,github.com/google/cadvisor/manager/manager.go

# github.com/google/cadvisor/manager/manager.go
52 // The Manager interface defines operations for starting a manager and getting
53 // container and machine information.
54 type Manager interface {
55 // Start the manager. Calling other manager methods before this returns
56 // may produce undefined behavior.
57 Start() error
59 // Stops the manager.
60 Stop() error
62 // Get information about a container.
63 GetContainerInfo(containerName string, query *info.ContainerInfoRequest) (*info.ContainerInfo, error)
... ...

以下對 cadvisor 具體如何獲取到 machine 和 docker container 的信息結合代碼具體講解。

Machine Info

# github.com/google/cadvisor/manager/manager.go
158 machineInfo, err := getMachineInfo(sysfs, fsInfo) //  此處通過  getMachineInfo()  函數獲取  machine  信息
159 if err != nil {
160 return nil, err
161 }
162 newManager.machineInfo = *machineInfo
163 glog.Infof(Machine: %+v , newManager.machineInfo)

獲取 machineinfo 的具體函數 getMachineInfo()

# github.com/google/cadvisor/manager/machine.go
52 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, err
57 }
... ...

MachineInfo 數據結構:

# github.com/google/cadvisor/info/v1/machine.go
131 type MachineInfo struct {
132 // The number of cores in this machine.
133 NumCores int `json: num_cores `
135 // Maximum clock speed for the cores, in KHz.
136 CpuFrequency uint64 `json: cpu_frequency_khz `
138 // The amount of memory (in bytes) in this machine
139 MemoryCapacity int64 `json: memory_capacity `
141 // The machine id
142 MachineID string `json: machine_id `
144 // The system uuid
145 SystemUUID string `json: system_uuid `
147 // The boot id
148 BootID string `json: boot_id `
150 // Filesystems on this machine.
151 Filesystems []FsInfo `json: filesystems `
153 // Disk map
154 DiskMap map[string]DiskInfo `json: disk_map `
156 // Network devices
157 NetworkDevices []NetInfo `json: network_devices `
159 // Machine Topology
160 // Describes cpu/memory layout and hierarchy.
161 Topology []Node `json: topology `
163 // Cloud provider the machine belongs to.
164 CloudProvider CloudProvider `json: cloud_provider `
166 // 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.go
76 func GetMachineMemoryCapacity() (int64, error) {77 out, err := ioutil.ReadFile( /proc/meminfo)
78 if err != nil {
79 return 0, err
80 }
82 memoryCapacity, err := parseCapacity(out, memoryCapacityRegexp)
83 if err != nil {
84 return 0, err
85 }
86 return memoryCapacity, err
87 }

machine_id /var/lib/dbus/machine-id

boot_id /proc/sys/kernel/random/boot_id

? ~ cat /var/lib/dbus/machine-id
a8919ec7c9ee43bd1bcaf6cd55e1a7bc
? ~ cat /proc/sys/kernel/random/boot_id
2f6bac7f-738a-4d85-8b58-53e71296119e

disk /proc/diskstats

# github.com/google/cadvisor/fs/fs.go
189 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) //  磁盤狀態通過  /proc/diskstats  獲取
193 if err != nil {
194 return nil, err
195 }
... ...

對于分配給容器的 pool 值,如果是 device mapper 類型的,則通過 dmsetup status pool_device_name 獲取設備使用情況

# github.com/google/cadvisor/fs/fs.go
... ...
205 case  devicemapper :
206 total, free, avail, err = getDMStats(device, partition.blockSize)
....

獲取磁盤設備信息 /sys/block

# github.com/google/cadvisor/utils/sysinfo/sysinfo.go
31 func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {32 disks, err := sysfs.GetBlockDevices()
 // cadvisor/utils/sysfs/sysfs.go GetBlockDevices()  可知,通過  /sys/block  獲取磁盤設備名,其它信息雷同
33 if err != nil {
34 return nil, err
35 }
... ...
? ~ cat /sys/block/sda/dev   #  主次設備號
? ~ cat /sys/block/sda/size  #  磁盤設備大小
976773168
? ~ cat /sys/block/sda/queue/scheduler #  磁盤調度類型
noop deadline [cfq]
? ~

netDevices /sys/class/net

# github.com/google/cadvisor/utils/sysinfo/sysinfo.go
87 func GetNetworkDevices(sysfs sysfs.SysFs) ([]info.NetInfo, error) {88 devs, err := sysfs.GetNetworkDevices()
89 if err != nil {
90 return nil, err
91 }
92 netDevices := []info.NetInfo{}
... ...
? ~ cat /sys/class/net/eth0/address
f0:76:1c:6d:26:d6
? ~ cat /sys/class/net/eth0/mtu
? ~ cat /sys/class/net/eth0/speed
10

system UUID /sys/class/dmi/id/product_uuid

? ~ sudo cat /sys/class/dmi/id/product_uuid
F27316D5-4DB3-E411-A26A-F0761C6D26D6
? ~

Docker Info

# github.com/google/cadvisor/manager/manager.go
201 // 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 {206 glog.Errorf( Docker container factory registration failed: %v. , err)
207 }
... ...

cAdvisor 啟動 container manager,通過調用 Linux 系統 inotify 監測 cgroup docker 目錄的文件變化判斷 docker 的創建和刪除。

Getprocesslist

cAdvisor 首先判斷自己是否運行在 container 中,如果是則 chroot /rootfs(cAdvisor 在 container 中運行會通過 volume 方式把系統 / mount 到 /rootfs 下)再執行 ps -e -o user,pid,ppid,stime,pcpu,pmem,rss,vsz,stat,time,comm,cgrou,否則直接執行獲取。(github.com/google/cadvisor/manager/container.go GetProcessList() 函數實現 )

# github.com/google/cadvisor/manager/manager.go
687 func (m *manager) GetProcessList(containerName string, options v2.RequestOptions) ([]v2.ProcessInfo, error) {
688 // override recursive. Only support single container listing.
689 options.Recursive = false
690 conts, err := m.getRequestedContainers(containerName, options)
691 if err != nil {
692 return nil, err
693 }
694 if len(conts) != 1 {695 return nil, fmt.Errorf( Expected the request to match only one container)
696 }
... ...

如果是獲取全局而非某個 container 的 processlist,則 containername 默認為 /,判斷邏輯如下:

# github.com/google/cadvisor/manager/container.go
273 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],
279 PercentCpu: float32(percentCpu),
... ...

ContainerInfo

獲取指定 container 的 info 數據:

# github.com/google/cadvisor manager/manager.go
531 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{}, err
535 }
... ...

具體獲取函數:

# github.com/google/cadvisor/manager/container.go
102 func (c *containerData) GetInfo() (*containerInfo, error) {
103 // Get spec and subcontainers.
104 if time.Since(c.lastUpdatedTime)   5*time.Second { //  可以看出當上一次更新時間超過  5s  的時候才會更新  info  數據  5
105 err := c.updateSpec()
106 if err != nil {
107 return nil, err
108 }
... ...

ContainerSpec

cAdvisor 獲取 ContainerSpec 總體的邏輯是找出對應 container 對應的系統 Spec json 文件。

container info handler:

# github.com/google/cadvisor/container/docker/handler.go
220 func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {221 mi, err := self.machineInfoFactory.GetMachineInfo()
222 if err != nil {223 return info.ContainerSpec{}, err
224 }

/proc/self/mountinfo 當前運行進程的掛載信息

/proc/cgroups 當前內核支持的 cgroup 類型

libcontainer configpath /var/run/docker/execdriver/native/containerId

# github.com/google/cadvisor/container/libcontainer/compatibility.go  讀取  libcontainer config  文件信息
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) {154 out, err := ioutil.ReadFile(configPath)
155 if err != nil {
156 return nil, err
157 }
159 var state libcontainer.State
160 err = json.Unmarshal(out,  state)
161 if err != nil {
162 return nil, err
163 }
164 return  state.Config, nil
165 }
# github.com/google/cadvisor/container/docker/handler.go  磁盤使用率統計目前支持  aufs,這是目前  CentOS7  上沒有  filesystem  大小的原因
... ...
232 // For now only enable for aufs filesystems
233 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 nil
245 }
... ...

文件系統相關 # github.com/google/cadvisor/fs/fs.go

aufs storage dir: /var/lib/docker/aufs/diff/containerId

獲取 cgroup 和 網絡狀態

# github.com/google/cadvisor/container/docker/handler.go
# cgroup  信息是調用  github.com/docker/libcontainer/cgroups  獲取
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, err
280 }
281 // Clean up stats for containers that don t have their own network - this
282 // includes containers running in Kubernetes pods that use the network of the
283 // infrastructure container. This stops metrics being reported multiple times
284 // for each container in a pod.  如果  container  沒有自己的網絡,則返回空。對于  K8s pod  內部  container  都是通過  pause container  網絡通信
285 if !hasNet(self.networkMode) {286 stats.Network = info.NetworkStats{}
287 }
289 // Get filesystem stats.
290 err = self.getFsStats(stats)
291 if err != nil {
292 return stats, err
293 }
295 return stats, nil
296 }

具體獲取 cgroup 和 network 的函數實現 GetStats()

container 網絡狀態 /proc/ pid /net/dev

# github.com/google/cadvisor/container/libcontainer/helpers.go
81 // Get cgroup and networking stats of the specified container
82 func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int) (*info.ContainerStats, error) {83 cgroupStats, err := cgroupManager.GetStats()
84 if err != nil {
85 return nil, err
86 }
87 libcontainerStats :=  libcontainer.Stats{
88 CgroupStats: cgroupStats,
89 }
90 stats := toContainerStats(libcontainerStats)
92 // If we know the pid then get network stats from /proc/ pid /net/dev
93 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 包含信息如下 (cadVisor 調用 licontainer/cgroups 獲取 container 對應 cgroup 信息):

# github.com/docker/libcontainer/cgroups/stats.go
88 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 }

到此,關于“cAdvisor 如何獲取到 machine 和 docker container 的信息”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計11391字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 四会市| 鹤峰县| 禹州市| 延长县| 原阳县| 锡林郭勒盟| 法库县| 西乡县| 新余市| 建湖县| 丹棱县| 荣昌县| 寻乌县| 迁安市| 平塘县| 翁牛特旗| 全椒县| 新邵县| 旬邑县| 荔波县| 汶上县| 鹤山市| 迁安市| 文水县| 来凤县| 龙陵县| 黑山县| 揭东县| 平乐县| 青岛市| 广安市| 始兴县| 鹿邑县| 钦州市| 沾化县| 闵行区| 房产| 海晏县| 绿春县| 龙口市| 讷河市|