Implement ebpf proc fallback

This commit is contained in:
Michael Schubert
2017-03-10 08:22:58 +01:00
parent 5f2ba891a4
commit 22ae6c45a0
3 changed files with 30 additions and 35 deletions

View File

@@ -19,6 +19,7 @@ type connectionTrackerConfig struct {
UseEbpfConn bool
ProcRoot string
BufferSize int
ProcessCache *process.CachingWalker
Scanner procspy.ConnectionScanner
DNSSnooper *DNSSnooper
}
@@ -28,43 +29,36 @@ type connectionTracker struct {
flowWalker flowWalker // Interface
ebpfTracker eventTracker
reverseResolver *reverseResolver
processCache *process.CachingWalker
}
func newProcfsConnectionTracker(conf connectionTrackerConfig) connectionTracker {
if conf.WalkProc && conf.Scanner == nil {
conf.Scanner = procspy.NewConnectionScanner(conf.ProcessCache)
}
return connectionTracker{
conf: conf,
flowWalker: newConntrackFlowWalker(conf.UseConntrack, conf.ProcRoot, conf.BufferSize, "--any-nat"),
ebpfTracker: nil,
reverseResolver: newReverseResolver(),
}
}
func newConnectionTracker(conf connectionTrackerConfig) connectionTracker {
if !conf.UseEbpfConn {
// ebpf OFF, use flowWalker
return connectionTracker{
conf: conf,
flowWalker: newConntrackFlowWalker(conf.UseConntrack, conf.ProcRoot, conf.BufferSize, "--any-nat"),
ebpfTracker: nil,
reverseResolver: newReverseResolver(),
}
// ebpf off, use proc scanning for connection tracking
return newProcfsConnectionTracker(conf)
}
// When ebpf will be active by default, check if it starts correctly otherwise fallback to flowWalk
et, err := newEbpfTracker()
if err != nil {
// TODO: fallback to flowWalker, when ebpf is enabled by default
log.Errorf("Error setting up the ebpfTracker, connections will not be reported: %s", err)
noopConnectionTracker := connectionTracker{
conf: conf,
flowWalker: nil,
ebpfTracker: nil,
reverseResolver: nil,
}
return noopConnectionTracker
// ebpf failed, fallback to proc scanning for connection tracking
log.Warnf("Error setting up the eBPF tracker, falling back to proc scanning: %v", err)
return newProcfsConnectionTracker(conf)
}
var processCache *process.CachingWalker
processCache = process.NewCachingWalker(process.NewWalker(conf.ProcRoot))
processCache.Tick()
ct := connectionTracker{
conf: conf,
flowWalker: nil,
ebpfTracker: et,
reverseResolver: newReverseResolver(),
processCache: processCache,
}
go ct.getInitialState()
return ct
@@ -89,8 +83,7 @@ func flowToTuple(f flow) (ft fourTuple) {
return ft
}
// ReportConnections calls trackers accordingly to the configuration.
// When ebpf is enabled, only performEbpfTrack() is called
// ReportConnections calls trackers according to the configuration.
func (t *connectionTracker) ReportConnections(rpt *report.Report) {
hostNodeID := report.MakeHostNodeID(t.conf.HostID)
@@ -164,9 +157,14 @@ func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID strin
return nil
}
// getInitialState runs conntrack and proc parsing synchronously only
// once to initialize ebpfTracker
func (t *connectionTracker) getInitialState() {
scanner := procspy.NewSyncConnectionScanner(t.processCache)
// Run conntrack and proc parsing synchronously only once to initialize ebpfTracker
var processCache *process.CachingWalker
processCache = process.NewCachingWalker(process.NewWalker(t.conf.ProcRoot))
processCache.Tick()
scanner := procspy.NewSyncConnectionScanner(processCache)
seenTuples := map[string]fourTuple{}
// Consult the flowWalker to get the initial state
if err := IsConntrackSupported(t.conf.ProcRoot); t.conf.UseConntrack && err != nil {

View File

@@ -5,6 +5,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/weaveworks/scope/probe/endpoint/procspy"
"github.com/weaveworks/scope/probe/process"
"github.com/weaveworks/scope/report"
)
@@ -29,6 +30,7 @@ type ReporterConfig struct {
UseEbpfConn bool
ProcRoot string
BufferSize int
ProcessCache *process.CachingWalker
Scanner procspy.ConnectionScanner
DNSSnooper *DNSSnooper
}
@@ -69,6 +71,7 @@ func NewReporter(conf ReporterConfig) *Reporter {
UseEbpfConn: conf.UseEbpfConn,
ProcRoot: conf.ProcRoot,
BufferSize: conf.BufferSize,
ProcessCache: conf.ProcessCache,
Scanner: conf.Scanner,
DNSSnooper: conf.DNSSnooper,
}),

View File

@@ -27,7 +27,6 @@ import (
"github.com/weaveworks/scope/probe/controls"
"github.com/weaveworks/scope/probe/docker"
"github.com/weaveworks/scope/probe/endpoint"
"github.com/weaveworks/scope/probe/endpoint/procspy"
"github.com/weaveworks/scope/probe/host"
"github.com/weaveworks/scope/probe/kubernetes"
"github.com/weaveworks/scope/probe/overlay"
@@ -158,13 +157,8 @@ func probeMain(flags probeFlags, targets []appclient.Target) {
p.AddTagger(probe.NewTopologyTagger(), host.NewTagger(hostID))
var processCache *process.CachingWalker
var scanner procspy.ConnectionScanner
if flags.procEnabled {
processCache = process.NewCachingWalker(process.NewWalker(flags.procRoot))
// The eBPF tracker finds connections itself and does not need the connection scanner
if !flags.useEbpfConn {
scanner = procspy.NewConnectionScanner(processCache)
}
p.AddTicker(processCache)
p.AddReporter(process.NewReporter(processCache, hostID, process.GetDeltaTotalJiffies, flags.noCommandLineArguments))
}
@@ -185,7 +179,7 @@ func probeMain(flags probeFlags, targets []appclient.Target) {
UseEbpfConn: flags.useEbpfConn,
ProcRoot: flags.procRoot,
BufferSize: flags.conntrackBufferSize,
Scanner: scanner,
ProcessCache: processCache,
DNSSnooper: dnsSnooper,
})
defer endpointReporter.Stop()