2017-07-19 53 views
0

我是cgroups的新手,並試圖使用cgroup獲取容器統計信息。以前我使用的是docker stats,但是也試圖收集類似的指標,cgroups也是如此。來自碼頭統計vs cgroup的cpuPercent度量

在泊塢窗統計,CPU統計部分是象下面這樣:

"cpu_usage": { 
     "total_usage": 27120642519, 
     "percpu_usage": [27120642519], 
     "usage_in_kernelmode": 4550000000, 
     "usage_in_usermode": 19140000000 
    }, 
    "system_cpu_usage": 42803030000000, 

而且,CPU%度量使用下面的公式計算:

cpuDelta = float64(v.CpuStats.CpuUsage.TotalUsage - previousCPU) 
systemDelta = float64(v.CpuStats.SystemUsage - previousSystem) 
cpuPct = cpuDelta/systemDelta 

我在看的cgroup收集systemUsagetotalUsage,但它似乎沒有類似的指標:

cgroups有一個僞文件cpuacct.stats其中有usersystem刻度,但這些僅與來自docker stats輸出的usage_in_user_modeusage_in_kernel_mode相匹配。

和cpuacct.usage_per_cpu僞文件每個cpu有一個用法,它與上面docker stats輸出中的total_usage匹配。

$cat cpuacct.stat 
user 1914 
system 455 

$cat cpuacct.usage_percpu 
27120642519 

但是,我找不到任何方法來弄清楚如何從cgroups收集「systemUsage」。

任何線索都會有很大的幫助!

謝謝!

回答

1

您的問題的答案不在於cgroups。請參考下文提到的一點:

func calculateCPUPercentUnix(previousCPU, previousSystem uint64, v *types.StatsJSON) float64 { 
    var (
     cpuPercent = 0.0 
     // calculate the change for the cpu usage of the container in between readings 
     cpuDelta = float64(v.CPUStats.CPUUsage.TotalUsage) - float64(previousCPU) 
     // calculate the change for the entire system between readings 
     systemDelta = float64(v.CPUStats.SystemUsage) - float64(previousSystem) 
    ) 
    if systemDelta > 0.0 && cpuDelta > 0.0 { 
     cpuPercent = (cpuDelta/systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0 
    } 
    return cpuPercent 
} 
  1. 的「system_cpu_usage」的泊塢窗統計API指的是主機的CPU使用情況。
  2. Docker統計信息API的「cpu_usage」>「total_usage」指的是容器的每CPU使用情況。
  3. 因此,在計算(cpuDelta/systemDelta)之後,我們得到每個系統CPU的每CPU使用量。
  4. 現在我們需要將步驟3的結果和分配給docker容器的CPU總數相乘,以獲得每個系統CPU的總CPU使用量。
  5. 步驟4乘以100後的結果爲我們提供了百分比的CPU利用率。

返回到問題: 系統CPU如何由docker進行計算?

要計算系統CPU使用率,docker使用POSIX定義的「/ proc/stat」。它查找CPU統計數據行,然後總結提供的前七個字段。下面將介紹爲執行所需步驟而編寫的golang代碼。

https://github.com/rancher/docker/blob/3f1b16e236ad4626e02f3da4643023454d7dbb3f/daemon/stats_collector_unix.go#L137

// getSystemCPUUsage returns the host system's cpu usage in 
// nanoseconds. An error is returned if the format of the underlying 
// file does not match. 
// 
// Uses /proc/stat defined by POSIX. Looks for the cpu 
// statistics line and then sums up the first seven fields 
// provided. See `man 5 proc` for details on specific field 
// information. 
func (s *statsCollector) getSystemCPUUsage() (uint64, error) { 
    var line string 
    f, err := os.Open("/proc/stat") 
    if err != nil { 
     return 0, err 
    } 
    defer func() { 
     s.bufReader.Reset(nil) 
     f.Close() 
    }() 
    s.bufReader.Reset(f) 
    err = nil 
    for err == nil { 
     line, err = s.bufReader.ReadString('\n') 
     if err != nil { 
      break 
     } 
     parts := strings.Fields(line) 
     switch parts[0] { 
     case "cpu": 
      if len(parts) < 8 { 
       return 0, derr.ErrorCodeBadCPUFields 
      } 
      var totalClockTicks uint64 
      for _, i := range parts[1:8] { 
       v, err := strconv.ParseUint(i, 10, 64) 
       if err != nil { 
        return 0, derr.ErrorCodeBadCPUInt.WithArgs(i, err) 
       } 
       totalClockTicks += v 
      } 
      return (totalClockTicks * nanoSecondsPerSecond)/
       s.clockTicksPerSecond, nil 
     } 
    } 
    return 0, derr.ErrorCodeBadStatFormat 
} 

請匹配搬運工的 「system_cpu_usage」 統計API與下面提到命令的輸出,以確認:

cat /proc/stat|grep -w cpu|awk '{split($0,a,\" \"); sum=0; for(i=2;i<8;i++)(sum+=a[i])} END{print sum }'