Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cadvisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func main() {

collectorHttpClient := createCollectorHttpClient(*collectorCert, *collectorKey)

containerManager, err := manager.New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
containerManager, err := New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
if err != nil {
klog.Fatalf("Failed to create a Container Manager: %s", err)
}
Expand Down
167 changes: 167 additions & 0 deletions cadvisor_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// Copyright 2019 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 main

import (
"context"
"fmt"
"net/http"
"os"
"time"

"github.com/google/cadvisor/accelerators"
"github.com/google/cadvisor/cache/memory"
"github.com/google/cadvisor/container"
_ "github.com/google/cadvisor/container/containerd"
"github.com/google/cadvisor/container/crio"
"github.com/google/cadvisor/container/docker"
_ "github.com/google/cadvisor/container/mesos"
_ "github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/container/rkt"
_ "github.com/google/cadvisor/container/systemd"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine"
"github.com/google/cadvisor/manager"
"github.com/google/cadvisor/utils/sysfs"
"github.com/google/cadvisor/watcher"

"github.com/opencontainers/runc/libcontainer/cgroups"
"k8s.io/klog"
)

const dockerClientTimeout = 10 * time.Second

// New takes a memory storage and returns a new manager.
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, includedMetricsSet container.MetricSet, collectorHttpClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string) (manager.Manager, error) {
if memoryCache == nil {
return nil, fmt.Errorf("manager requires memory storage")
}

// Detect the container we are running on.
selfContainer, err := cgroups.GetOwnCgroupPath("cpu")
if err != nil {
return nil, err
}
klog.V(2).Infof("cAdvisor running in container: %q", selfContainer)

var (
dockerStatus info.DockerStatus
rktPath string
)
docker.SetTimeout(dockerClientTimeout)
// Try to connect to docker indefinitely on startup.
dockerStatus = retryDockerStatus()

if tmpRktPath, err := rkt.RktPath(); err != nil {
klog.V(5).Infof("Rkt not connected: %v", err)
} else {
rktPath = tmpRktPath
}

crioClient, err := crio.Client()
if err != nil {
return nil, err
}
crioInfo, err := crioClient.Info()
if err != nil {
klog.V(5).Infof("CRI-O not connected: %v", err)
}

context := fs.Context{
Docker: fs.DockerContext{
Root: docker.RootDir(),
Driver: dockerStatus.Driver,
DriverStatus: dockerStatus.DriverStatus,
},
RktPath: rktPath,
Crio: fs.CrioContext{
Root: crioInfo.StorageRoot,
},
}
fsInfo, err := fs.NewFsInfo(context)
if err != nil {
return nil, err
}

// If cAdvisor was started with host's rootfs mounted, assume that its running
// in its own namespaces.
inHostNamespace := false
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
inHostNamespace = true
}

// Register for new subcontainers.
eventsChannel := make(chan watcher.ContainerEvent, 16)

machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
if err != nil {
return nil, err
}
klog.V(1).Infof("Machine: %+v", *machineInfo)

newManager := manager.New(
memoryCache,
fsInfo,
sysfs,
*machineInfo,
make([]chan error, 0, 2),
selfContainer,
inHostNamespace,
time.Now(),
maxHousekeepingInterval,
allowDynamicHousekeeping,
includedMetricsSet,
[]watcher.ContainerWatcher{},
eventsChannel,
collectorHttpClient,
&accelerators.NvidiaManager{},
rawContainerCgroupPathPrefixWhiteList)

versionInfo, err := newManager.GetVersionInfo()
if err != nil {
return nil, err
}
klog.V(1).Infof("Version: %+v", *versionInfo)
return newManager, nil
}

func retryDockerStatus() info.DockerStatus {
startupTimeout := dockerClientTimeout
maxTimeout := 4 * startupTimeout
for {
ctx, e := context.WithTimeout(context.Background(), startupTimeout)
if e != nil {
klog.V(5).Infof("error during timeout: %v", e)
}
dockerStatus, err := docker.StatusWithContext(ctx)
if err == nil {
return dockerStatus
}

switch err {
case context.DeadlineExceeded:
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
default:
klog.V(5).Infof("Docker not connected: %v", err)
return info.DockerStatus{}
}

startupTimeout = 2 * startupTimeout
if startupTimeout > maxTimeout {
startupTimeout = maxTimeout
}
}
}
2 changes: 1 addition & 1 deletion container/containerd/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher"
"github.com/google/cadvisor/watcher"
)

var ArgContainerdEndpoint = flag.String("containerd", "/run/containerd/containerd.sock", "containerd endpoint")
Expand Down
33 changes: 33 additions & 0 deletions container/containerd/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 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 containerd

import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
"k8s.io/klog"
)

func init() {
err := container.RegisterPlugin("containerd", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
})
if err != nil {
klog.Fatalf("Failed to register containerd plugin: %v", err)
}
}
2 changes: 1 addition & 1 deletion container/crio/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher"
"github.com/google/cadvisor/watcher"

"k8s.io/klog"
)
Expand Down
33 changes: 33 additions & 0 deletions container/crio/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 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 crio

import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
"k8s.io/klog"
)

func init() {
err := container.RegisterPlugin("crio", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
})
if err != nil {
klog.Fatalf("Failed to register crio plugin: %v", err)
}
}
2 changes: 1 addition & 1 deletion container/docker/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import (
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine"
"github.com/google/cadvisor/manager/watcher"
dockerutil "github.com/google/cadvisor/utils/docker"
"github.com/google/cadvisor/watcher"
"github.com/google/cadvisor/zfs"

docker "github.com/docker/docker/client"
Expand Down
33 changes: 33 additions & 0 deletions container/docker/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 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 docker

import (
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
"k8s.io/klog"
)

func init() {
err := container.RegisterPlugin("docker", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
err := Register(factory, fsInfo, includedMetrics)
return nil, err
})
if err != nil {
klog.Fatalf("Failed to register docker plugin: %v", err)
}
}
38 changes: 37 additions & 1 deletion container/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"fmt"
"sync"

"github.com/google/cadvisor/manager/watcher"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"

"k8s.io/klog"
)
Expand Down Expand Up @@ -71,6 +73,40 @@ func (ms MetricSet) Add(mk MetricKind) {
ms[mk] = struct{}{}
}

type Register func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)

// All registered auth provider plugins.
var pluginsLock sync.Mutex
var plugins = make(map[string]Register)

func RegisterPlugin(name string, plugin Register) error {
pluginsLock.Lock()
defer pluginsLock.Unlock()
if _, found := plugins[name]; found {
return fmt.Errorf("Plugin %q was registered twice", name)
}
klog.V(4).Infof("Registered Plugin %q", name)
plugins[name] = plugin
return nil
}

func InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) []watcher.ContainerWatcher {
pluginsLock.Lock()
defer pluginsLock.Unlock()

containerWatchers := []watcher.ContainerWatcher{}
for name, register := range plugins {
watcher, err := register(factory, fsInfo, includedMetrics)
if err != nil {
klog.V(5).Infof("Registration of the %s container factory failed: %v", name, err)
}
if watcher != nil {
containerWatchers = append(containerWatchers, watcher)
}
}
return containerWatchers
}

// TODO(vmarmol): Consider not making this global.
// Global list of factories.
var (
Expand Down
2 changes: 1 addition & 1 deletion container/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

"github.com/google/cadvisor/container"
containertest "github.com/google/cadvisor/container/testing"
"github.com/google/cadvisor/manager/watcher"
"github.com/google/cadvisor/watcher"

"github.com/stretchr/testify/mock"
)
Expand Down
2 changes: 1 addition & 1 deletion container/mesos/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher"
"github.com/google/cadvisor/watcher"
"k8s.io/klog"
)

Expand Down
Loading