pinned cadvisor to a latest commit

Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
This commit is contained in:
Tarun Pothulapati
2019-08-08 17:56:37 +05:30
parent 6d49d69c91
commit ce31366baf
28 changed files with 165 additions and 525 deletions

View File

@@ -70,7 +70,7 @@ type InMemoryCache struct {
lock sync.RWMutex
containerCacheMap map[string]*containerCache
maxAge time.Duration
backend storage.StorageDriver
backend []storage.StorageDriver
}
func (self *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.ContainerStats) error {
@@ -86,11 +86,11 @@ func (self *InMemoryCache) AddStats(cInfo *info.ContainerInfo, stats *info.Conta
}
}()
if self.backend != nil {
for _, backend := range self.backend {
// TODO(monnand): To deal with long delay write operations, we
// may want to start a pool of goroutines to do write
// operations.
if err := self.backend.AddStats(cInfo, stats); err != nil {
if err := backend.AddStats(cInfo, stats); err != nil {
klog.Error(err)
}
}
@@ -131,7 +131,7 @@ func (self *InMemoryCache) RemoveContainer(containerName string) error {
func New(
maxAge time.Duration,
backend storage.StorageDriver,
backend []storage.StorageDriver,
) *InMemoryCache {
ret := &InMemoryCache{
containerCacheMap: make(map[string]*containerCache, 32),

View File

@@ -18,8 +18,8 @@ go_library(
"//vendor/github.com/google/cadvisor/utils:go_default_library",
"//vendor/github.com/karrick/godirwalk:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/inotify:go_default_library",
],
)

View File

@@ -116,6 +116,15 @@ func GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoF
}
}
// Processes, read it's value from pids path directly
pidsRoot, ok := cgroupPaths["pids"]
if ok {
if utils.FileExists(pidsRoot) {
spec.HasProcesses = true
spec.Processes.Limit = readUInt64(pidsRoot, "pids.max")
}
}
spec.HasNetwork = hasNetwork
spec.HasFilesystem = hasFilesystem
@@ -143,7 +152,7 @@ func readString(dirpath string, file string) string {
func readUInt64(dirpath string, file string) uint64 {
out := readString(dirpath, file)
if out == "" {
if out == "" || out == "max" {
return 0
}

View File

@@ -17,7 +17,7 @@ package common
import (
"sync"
inotify "github.com/sigma/go-inotify"
inotify "k8s.io/utils/inotify"
)
// Watcher for container-related inotify events in the cgroup hierarchy.
@@ -55,7 +55,7 @@ func (iw *InotifyWatcher) AddWatch(containerName, dir string) (bool, error) {
// Register an inotify notification.
if !cgroupsWatched[dir] {
err := iw.watcher.AddWatch(dir, inotify.IN_CREATE|inotify.IN_DELETE|inotify.IN_MOVE)
err := iw.watcher.AddWatch(dir, inotify.InCreate|inotify.InDelete|inotify.InMove)
if err != nil {
return alreadyWatched, err
}

View File

@@ -6,7 +6,6 @@ go_library(
"handler.go",
"helpers.go",
],
cgo = True,
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/container/libcontainer",
importpath = "github.com/google/cadvisor/container/libcontainer",
visibility = ["//visibility:public"],
@@ -15,6 +14,7 @@ go_library(
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)

View File

@@ -27,18 +27,15 @@ import (
"github.com/google/cadvisor/container"
info "github.com/google/cadvisor/info/v1"
"golang.org/x/sys/unix"
"bytes"
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/cgroups"
"k8s.io/klog"
)
/*
#include <unistd.h>
*/
import "C"
type Handler struct {
cgroupManager cgroups.Manager
rootFs string
@@ -133,6 +130,9 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
klog.V(4).Infof("Unable to get Process Stats: %v", err)
}
}
// if include processes metrics, just set threads metrics if exist, and has no relationship with cpu path
setThreadsStats(cgroupStats, stats)
}
// For backwards compatibility.
@@ -144,7 +144,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
}
func processStatsFromProcs(rootFs string, cgroupPath string) (info.ProcessStats, error) {
var fdCount uint64
var fdCount, socketCount uint64
filePath := path.Join(cgroupPath, "cgroup.procs")
out, err := ioutil.ReadFile(filePath)
if err != nil {
@@ -168,11 +168,23 @@ func processStatsFromProcs(rootFs string, cgroupPath string) (info.ProcessStats,
continue
}
fdCount += uint64(len(fds))
for _, fd := range fds {
fdPath := path.Join(dirPath, fd.Name())
linkName, err := os.Readlink(fdPath)
if err != nil {
klog.V(4).Infof("error while reading %q link: %v", fdPath, err)
continue
}
if strings.HasPrefix(linkName, "socket") {
socketCount++
}
}
}
processStats := info.ProcessStats{
ProcessCount: uint64(len(pids)),
FdCount: fdCount,
SocketCount: socketCount,
}
return processStats, nil
@@ -514,19 +526,12 @@ func setCpuStats(s *cgroups.Stats, ret *info.ContainerStats, withPerCPU bool) {
}
// Copied from
// https://github.com/moby/moby/blob/8b1adf55c2af329a4334f21d9444d6a169000c81/daemon/stats/collector_unix.go#L73
// Apache 2.0, Copyright Docker, Inc.
func getNumberOnlineCPUs() (uint32, error) {
i, err := C.sysconf(C._SC_NPROCESSORS_ONLN)
// According to POSIX - errno is undefined after successful
// sysconf, and can be non-zero in several cases, so look for
// error in returned value not in errno.
// (https://sourceware.org/bugzilla/show_bug.cgi?id=21536)
if i == -1 {
var availableCPUs unix.CPUSet
if err := unix.SchedGetaffinity(0, &availableCPUs); err != nil {
return 0, err
}
return uint32(i), nil
return uint32(availableCPUs.Count()), nil
}
func setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) {
@@ -598,6 +603,15 @@ func setNetworkStats(libcontainerStats *libcontainer.Stats, ret *info.ContainerS
}
}
// read from pids path not cpu
func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) {
if s != nil {
ret.Processes.ThreadsCurrent = s.PidsStats.Current
ret.Processes.ThreadsMax = s.PidsStats.Limit
}
}
func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats {
ret := &info.ContainerStats{
Timestamp: time.Now(),

View File

@@ -106,6 +106,7 @@ var supportedSubsystems map[string]struct{} = map[string]struct{}{
"cpu": {},
"cpuacct": {},
"memory": {},
"pids": {},
"cpuset": {},
"blkio": {},
"devices": {},

View File

@@ -20,8 +20,8 @@ go_library(
"//vendor/github.com/google/cadvisor/watcher:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs:go_default_library",
"//vendor/github.com/opencontainers/runc/libcontainer/configs:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/inotify:go_default_library",
],
)

View File

@@ -77,6 +77,9 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
pid := 0
if isRootCgroup(name) {
pid = 1
// delete pids from cgroup paths because /sys/fs/cgroup/pids/pids.current not exist
delete(cgroupPaths, "pids")
}
handler := libcontainer.NewHandler(cgroupManager, rootFs, pid, includedMetrics)

View File

@@ -26,7 +26,7 @@ import (
"github.com/google/cadvisor/container/common"
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/watcher"
inotify "github.com/sigma/go-inotify"
inotify "k8s.io/utils/inotify"
"k8s.io/klog"
)
@@ -172,13 +172,13 @@ func (self *rawContainerWatcher) processEvent(event *inotify.Event, events chan
// Convert the inotify event type to a container create or delete.
var eventType watcher.ContainerEventType
switch {
case (event.Mask & inotify.IN_CREATE) > 0:
case (event.Mask & inotify.InCreate) > 0:
eventType = watcher.ContainerAdd
case (event.Mask & inotify.IN_DELETE) > 0:
case (event.Mask & inotify.InDelete) > 0:
eventType = watcher.ContainerDelete
case (event.Mask & inotify.IN_MOVED_FROM) > 0:
case (event.Mask & inotify.InMovedFrom) > 0:
eventType = watcher.ContainerDelete
case (event.Mask & inotify.IN_MOVED_TO) > 0:
case (event.Mask & inotify.InMovedTo) > 0:
eventType = watcher.ContainerAdd
default:
// Ignore other events.

View File

@@ -41,6 +41,10 @@ type MemorySpec struct {
SwapLimit uint64 `json:"swap_limit,omitempty"`
}
type ProcessSpec struct {
Limit uint64 `json:"limit,omitempty"`
}
type ContainerSpec struct {
// Time at which the container was created.
CreationTime time.Time `json:"creation_time,omitempty"`
@@ -58,6 +62,9 @@ type ContainerSpec struct {
HasNetwork bool `json:"has_network"`
HasProcesses bool `json:"has_processes"`
Processes ProcessSpec `json:"processes,omitempty"`
HasFilesystem bool `json:"has_filesystem"`
// HasDiskIo when true, indicates that DiskIo stats will be available.
@@ -563,6 +570,15 @@ type ProcessStats struct {
// Number of open file descriptors
FdCount uint64 `json:"fd_count"`
// Number of sockets
SocketCount uint64 `json:"socket_count"`
// Number of threads currently in container
ThreadsCurrent uint64 `json:"threads_current,omitempty"`
// Maxium number of threads allowed in container
ThreadsMax uint64 `json:"threads_max,omitempty"`
}
type ContainerStats struct {
@@ -630,6 +646,9 @@ func (a *ContainerStats) StatsEq(b *ContainerStats) bool {
if !reflect.DeepEqual(a.Network, b.Network) {
return false
}
if !reflect.DeepEqual(a.Processes, b.Processes) {
return false
}
if !reflect.DeepEqual(a.Filesystem, b.Filesystem) {
return false
}

View File

@@ -90,6 +90,9 @@ type ContainerSpec struct {
HasCustomMetrics bool `json:"has_custom_metrics"`
CustomMetrics []v1.MetricSpec `json:"custom_metrics,omitempty"`
HasProcesses bool `json:"has_processes"`
Processes v1.ProcessSpec `json:"processes,omitempty"`
// Following resources have no associated spec, but are being isolated.
HasNetwork bool `json:"has_network"`
HasFilesystem bool `json:"has_filesystem"`
@@ -117,6 +120,9 @@ type DeprecatedContainerStats struct {
// Network statistics
HasNetwork bool `json:"has_network"`
Network NetworkStats `json:"network,omitempty"`
// Processes statistics
HasProcesses bool `json:"has_processes"`
Processes v1.ProcessStats `json:"processes,omitempty"`
// Filesystem statistics
HasFilesystem bool `json:"has_filesystem"`
Filesystem []v1.FsStats `json:"filesystem,omitempty"`
@@ -142,6 +148,8 @@ type ContainerStats struct {
Memory *v1.MemoryStats `json:"memory,omitempty"`
// Network statistics
Network *NetworkStats `json:"network,omitempty"`
// Processes statistics
Processes *v1.ProcessStats `json:"processes,omitempty"`
// Filesystem statistics
Filesystem *FilesystemStats `json:"filesystem,omitempty"`
// Task load statistics

View File

@@ -124,6 +124,9 @@ func ContainerStatsFromV1(containerName string, spec *v1.ContainerSpec, stats []
Interfaces: val.Network.Interfaces,
}
}
if spec.HasProcesses {
stat.Processes = &val.Processes
}
if spec.HasFilesystem {
if len(val.Filesystem) == 1 {
stat.Filesystem = &FilesystemStats{
@@ -180,6 +183,9 @@ func DeprecatedStatsFromV1(cont *v1.ContainerInfo) []DeprecatedContainerStats {
if stat.HasNetwork {
stat.Network.Interfaces = val.Network.Interfaces
}
if stat.HasProcesses {
stat.Processes = val.Processes
}
if stat.HasFilesystem {
stat.Filesystem = val.Filesystem
}
@@ -255,6 +261,7 @@ func ContainerSpecFromV1(specV1 *v1.ContainerSpec, aliases []string, namespace s
HasMemory: specV1.HasMemory,
HasFilesystem: specV1.HasFilesystem,
HasNetwork: specV1.HasNetwork,
HasProcesses: specV1.HasProcesses,
HasDiskIo: specV1.HasDiskIo,
HasCustomMetrics: specV1.HasCustomMetrics,
Image: specV1.Image,

View File

@@ -1045,7 +1045,42 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri
return metricValues{{value: float64(s.Processes.FdCount), timestamp: s.Timestamp}}
},
},
{
name: "container_sockets",
help: "Number of open sockets for the container.",
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Processes.SocketCount), timestamp: s.Timestamp}}
},
},
{
name: "container_threads_max",
help: "Maximum number of threads allowed inside the container, infinity if value is zero",
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.Processes.ThreadsMax),
timestamp: s.Timestamp,
},
}
},
},
{
name: "container_threads",
help: "Number of threads running inside the container",
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.Processes.ThreadsCurrent),
timestamp: s.Timestamp,
},
}
},
},
}...)
}
return c
@@ -1156,8 +1191,18 @@ func (c *PrometheusCollector) collectContainersInfo(ch chan<- prometheus.Metric)
labels := make([]string, 0, len(rawLabels))
containerLabels := c.containerLabelsFunc(cont)
for l := range rawLabels {
labels = append(labels, sanitizeLabelName(l))
values = append(values, containerLabels[l])
duplicate := false
sl := sanitizeLabelName(l)
for _, x := range labels {
if sl == x {
duplicate = true
break
}
}
if !duplicate {
labels = append(labels, sl)
values = append(values, containerLabels[l])
}
}
// Container spec

View File

@@ -16,7 +16,6 @@ package cloudinfo
import (
"io/ioutil"
"os"
"strings"
"github.com/aws/aws-sdk-go/aws"
@@ -28,9 +27,10 @@ import (
)
const (
productVerFileName = "/sys/class/dmi/id/product_version"
biosVerFileName = "/sys/class/dmi/id/bios_vendor"
amazon = "amazon"
productVerFileName = "/sys/class/dmi/id/product_version"
biosVerFileName = "/sys/class/dmi/id/bios_vendor"
systemdOSReleaseFileName = "/etc/os-release"
amazon = "amazon"
)
func init() {
@@ -42,23 +42,18 @@ type provider struct{}
var _ cloudinfo.CloudProvider = provider{}
func (provider) IsActiveProvider() bool {
var dataProduct []byte
var dataBios []byte
if _, err := os.Stat(productVerFileName); err == nil {
dataProduct, err = ioutil.ReadFile(productVerFileName)
if err != nil {
return false
}
return fileContainsAmazonIdentifier(productVerFileName) ||
fileContainsAmazonIdentifier(biosVerFileName) ||
fileContainsAmazonIdentifier(systemdOSReleaseFileName)
}
func fileContainsAmazonIdentifier(filename string) bool {
fileContent, err := ioutil.ReadFile(filename)
if err != nil {
return false
}
if _, err := os.Stat(biosVerFileName); err == nil {
dataBios, err = ioutil.ReadFile(biosVerFileName)
if err != nil {
return false
}
}
return strings.Contains(string(dataProduct), amazon) || strings.Contains(strings.ToLower(string(dataBios)), amazon)
return strings.Contains(string(fileContent), amazon)
}
func getAwsMetadata(name string) string {

View File

@@ -4,16 +4,15 @@ go_library(
name = "go_default_library",
srcs = [
"conn.go",
"defs.go",
"netlink.go",
"reader.go",
],
cgo = True,
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/utils/cpuload/netlink",
importpath = "github.com/google/cadvisor/utils/cpuload/netlink",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)

View File

@@ -1,26 +0,0 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package netlink
/*
#include <linux/taskstats.h>
*/
import "C"
type TaskStats C.struct_taskstats
const (
__TASKSTATS_CMD_MAX = C.__TASKSTATS_CMD_MAX
)

View File

@@ -22,16 +22,7 @@ import (
"syscall"
info "github.com/google/cadvisor/info/v1"
)
const (
// Kernel constants for tasks stats.
genlIdCtrl = syscall.NLMSG_MIN_TYPE // GENL_ID_CTRL
taskstatsGenlName = "TASKSTATS" // TASKSTATS_GENL_NAME
cgroupStatsCmdAttrFd = 0x1 // CGROUPSTATS_CMD_ATTR_FD
ctrlAttrFamilyId = 0x1 // CTRL_ATTR_FAMILY_ID
ctrlAttrFamilyName = 0x2 // CTRL_ATTR_FAMILY_NAME
ctrlCmdGetFamily = 0x3 // CTRL_CMD_GETFAMILY
"golang.org/x/sys/unix"
)
var (
@@ -124,15 +115,15 @@ func prepareMessage(headerType uint16, cmd uint8, attributes []byte) (msg netlin
// Prepares message to query family id for task stats.
func prepareFamilyMessage() (msg netlinkMessage) {
buf := bytes.NewBuffer([]byte{})
addAttribute(buf, ctrlAttrFamilyName, taskstatsGenlName, len(taskstatsGenlName)+1)
return prepareMessage(genlIdCtrl, ctrlCmdGetFamily, buf.Bytes())
addAttribute(buf, unix.CTRL_ATTR_FAMILY_NAME, unix.TASKSTATS_GENL_NAME, len(unix.TASKSTATS_GENL_NAME)+1)
return prepareMessage(unix.GENL_ID_CTRL, unix.CTRL_CMD_GETFAMILY, buf.Bytes())
}
// Prepares message to query task stats for a task group.
func prepareCmdMessage(id uint16, cfd uintptr) (msg netlinkMessage) {
buf := bytes.NewBuffer([]byte{})
addAttribute(buf, cgroupStatsCmdAttrFd, uint32(cfd), 4)
return prepareMessage(id, __TASKSTATS_CMD_MAX+1, buf.Bytes())
addAttribute(buf, unix.CGROUPSTATS_CMD_ATTR_FD, uint32(cfd), 4)
return prepareMessage(id, unix.CGROUPSTATS_CMD_GET, buf.Bytes())
}
// Extracts returned family id from the response.
@@ -158,7 +149,7 @@ func parseFamilyResp(msg syscall.NetlinkMessage) (uint16, error) {
if err != nil {
return 0, err
}
if attr.Type == ctrlAttrFamilyId {
if attr.Type == unix.CTRL_ATTR_FAMILY_ID {
err = binary.Read(buf, Endian, &id)
if err != nil {
return 0, err