The change is necessitated by the removal of procspied/ebpf endpoint
filtering in the renderers, as a result of which the odd
conntracked-only, unconnected pseudo node can sneak through.
This new way of doing things also makes renderers more composable and
robust, and more directly reflects the objective:
- in the process topologies, filter out all unconnected nodes
- in all other topologies, filter out unconnected pseudo nodes
The filtering of endpoints causes some connections to get missed for
non-eBPF-tracked connections. Furthermore, the filtering of endpoints
is entirely pointless when the probes run eBPF since the filters just
pass through eBPF-tracked endpoints (for good reason too; because
otherwise some connections would be missed). So in that case it is
just costing CPU and removing it actually improves performance.
Note that removing the filtering does not result in over-counting
connections since that is done by source ip:port pairs.
Fixes#2551.
Fixes#2558.
We have to introduce the kinda hacky concept of a 'No Stack' stack
to reconcile it with the idea of a 'default' k8s namespace. This is important
because swarm services without a stack don't have the same docker labels as ones that do.
Curiously, they still have what appears to be a stack name 'prefix' on their names,
but I can't isolate that name anywhere easily so they'll just have to make do.
I basically copy-pasted updateFilters to make this work, todo go back and refactor
to not duplicate 90% of the code.
This field changes the option group behaviour depending on its value.
Currently only supports two values:
"one" (default): Old behaviour, one option can be selected
"union": Any number of options can be selected, and the filters are OR-ed togther
It is written in such a way as to easily enable a future "intersection" option,
as per union but AND-ing the filters. But this is not done here. YAGNI.
This reverts commit 76ddc75fb8, reversing
changes made to 3ade2933eb.
We are rolling this back for now because it's causing a bug where sub-topologies
would have ~3000 repeated cases of the k8s filters, causing performance issues clientside.
To facilitate this, we replace the existing functionality of updateFilters which
sets k8s topologies to have the filters [namespace, managed], to instead append the namespace filter
to any existing. This lets it apply to both k8s and container topologies without overwriting existing
container filters. We instead set the managed filter in the static definition.
This however has the side effect that the ordering of the namespace filter and the managed filter
in k8s topologies has been reversed, so it reads:
Show Unmanaged | Hide Unmanaged
foo | bar | default | baz | All Namespaces
instead of:
foo | bar | default | baz | All Namespaces
Show Unmanaged | Hide Unmanaged
Based on work from Lorenzo, updated by Iago, Alban, Alessandro and
Michael.
This PR adds connection tracking using eBPF. This feature is not enabled by default.
For now, you can enable it by launching scope with the following command:
```
sudo ./scope launch --probe.ebpf.connections=true
```
This patch allows scope to get notified of every connection event,
without relying on the parsing of /proc/$pid/net/tcp{,6} and
/proc/$pid/fd/*, and therefore improve performance.
We vendor https://github.com/iovisor/gobpf in Scope to load the
pre-compiled ebpf program and https://github.com/weaveworks/tcptracer-bpf
to guess the offsets of the structures we need in the kernel. In this
way we don't need a different pre-compiled ebpf object file per kernel.
The pre-compiled ebpf program is included in the vendoring of
tcptracer-bpf.
The ebpf program uses kprobes/kretprobes on the following kernel functions:
- tcp_v4_connect
- tcp_v6_connect
- tcp_set_state
- inet_csk_accept
- tcp_close
It generates "connect", "accept" and "close" events containing the
connection tuple but also pid and netns.
Note: the IPv6 events are not supported in Scope and thus not passed on.
probe/endpoint/ebpf.go maintains the list of connections. Similarly to
conntrack, it also keeps the dead connections for one iteration in order
to report short-lived connections.
The code for parsing /proc/$pid/net/tcp{,6} and /proc/$pid/fd/* is still
there and still used at start-up because eBPF only brings us the events
and not the initial state. However, the /proc parsing for the initial
state is now done in foreground instead of background, via
newForegroundReader().
NAT resolution on connections from eBPF works in the same way as it did
on connections from /proc: by using conntrack. One of the two conntrack
instances is only started to get the initial state and then it is
stopped since eBPF detects short-lived connections.
The Scope Docker image size comparison:
- weaveworks/scope in current master: 22 MB (compressed), 68 MB
(uncompressed)
- weaveworks/scope with this patchset: 23 MB (compressed), 69 MB
(uncompressed)
Fixes#1168 (walking /proc to obtain connections is very expensive)
Fixes#1260 (Short-lived connections not tracked for containers in
shared networking namespaces)
Fixes#1962 (Port ebpf tracker to Go)
Fixes#1961 (Remove runtime kernel header dependency from ebpf tracker)
gofmt load_container_filters.go
removed the environment variable for container label filters
Added the --app.container-label-filter command line argument, and load_container_filters.go now uses the results from that
Changed init() to InitializeTopologies()
Changed init() to InitializeTopologies() so that it can be called after the container filters are loaded from the command line argument. init() executes before main() in prog/main.go, so the flag parsing isn't finished before init() is called
Applied lint fixes
fixed lint issues
brought back the init function for api_topologies.go
Addressed many of the PR comments, except escaping colons
Renamed IsDesired to HasLabel in render/filters.go
Allows for the user to escape colons
added registry function for modifying the container filters
created a separate function that parses the container filter flags
simplified registry.addContainerFilters()
addressed review comments
switched API Topology Description IDs to constants
addressed review comments
joined constants
added test functions
addressed most of the review comments
Changed containerLabelFilters to an array of APItopologyOptions, placing the parsing in the Set() function. Removed parsing from HasLabel in render/filters.go
refactored code
added test that applies to the container filtering by labels
applied golint
made Registry items private and added a MakeRegistry() function
fixed usage of topologyRegistry.RendererForTopology
Added container label filters by exclusion
minor update to report_fixture
Modified container labels test to use existing report
I added labels to the existing containers in the fixed report for testing.
refactored code
refactored code
further code refactoring
addressed @ijsnellf's review comments
unexported Registry, and reduced duplicate code
addressed @ijsnellf's review comments
Addressed review comments
Addressed final review comments
* Add filters for pseudo nodes.
- Don't filter the internet node as a pseudo node.
- Rename pseudo filter to unmanaged/uncontained.
- Review feedback
- Move the FilterFoo funcs into the tests
- Drop the 'nodes' from filter labels.
* Fix experimental
Squash of:
* We have to keep all the container hostnames until the end so we can
count how many we've filtered
* Adding tests for ContainerHostnameRenderer and PodServiceRenderer with
filters
* Because we filter on image name we need the image name before
filtering
* Alternative approach to passing decorators.
* Refactor out some of the decorator capture
* Don't memoise decorated calls to Render
* Fixing filtered counts on containers topology
Tricky, because we need the filters to be silent sometimes (when they're
in the middle), but not when they're at the top, so we take the "top"
filter's stats. However, this means we have to compose all
user-specified filters into a single Filter layer, so we can get all
stats.
There are no more Silent filters, as all filters are silent (unless they
are at the top).
Additionally, I clarified some of the filters as their usage/terminology
was inconsistent and confused. Now Filter(IsFoo, ...) *keeps* only nodes
where IsFoo is true.
Squash of:
- including children in topologies_test.go
- report.Node.Prune should prune children also
- rewrote ShortLivedInternetConnections test to express its intent
- adding tests for detail Summary rendering
Squash of:
- use detailed.Summaries to render topology nodes
- ban merging nodes of different topologies (they should be mapped)
- need to prune parents when mapping node types
- render container images by id if they have no name
- remove separate render ids and prune parents in NewDerived*
- don't render metrics/metadata for groups of nodes
- fixing up tests
- removing pending unit tests (for mapping.go, for now)
- updating experimental dir for RenderableNode removal
Megasquish:
[app] remove unused edge endpoint
[WIP] refactoring node details api endpoint
[WIP] plumbing the children through the rendering process
adding IDList.Remove and StringSet.Remove
[WIP] working on adding parents to detailed node renderings
WIP UI components with mock backend data for new details
grouping children by type
UI components for node details health and info
metric formatters for details panel
Column headers and links for details table
[WIP] started on rendering node metadata and metrics in the detail view
DetailedNode.LabelMajor -> DetailedNode.Label
rendering decent labels for parents of detailed nodes
render metrics onto the top-level detailed node
removing dead code
Links to relatives
metrics have a Format not Unit
Show more/less actions for tables and relatives
adjusted metric formatter
TopologyTagger should tag k8s topology nodes
make renderablenode ids more consistent, e.g. container:abcd1234
working on rendering correct summaries for each node
adding report.Node.Rank, so that merging is independent of order
rendering children and parents correctly
output child renderableNode ids, so we can link to them
add group field to metrics, so they can be grouped
Refactored details health items to prepare for grouping
add metrics to processNodeSummaries
hide summary section if there is no data for it
fixing up tests
moving detailed node rendering into a separate package
Node ID/Topology are fields not metadata
- This way I think we don't have to care about Metadata being non-commutative.
- ID and topology are still non-commutative, as I'm not sure how to sanely
merge them, but it's possible we don't care.
host memory usage is a filesize, not a percent
working on fixing some tests
adding children to hosts detail panel
- Had to redo how parents are calculated, so that children wouldn't interfere with it
- have to have the host at the end because it is non-commutative
only render links for linkable children (i.e. not unconnected processes)
resolving TODOs
fixing up lint errors
make nil a valid value for render.Children so tests are cleaner
working on backend tests
make client handle missing metrics property
Stop rendering container image nodes with process summaries/parents
fix parent link to container images
Calculate parents as a set on report.Node (except k8s)
refactoring detailed.NodeSummary stuff
removing RenderableNode.Summary*, we already track it on report.Node
working on tests
add Columns field to NodeSummaryGroup
fixing up render/topologies_test
fix children links to container images
get children of hosts rendering right
working on host renderer tests
Change container report.Node.ID to a1b2c3;<container>
The id should be globally unique, so we don't need the host id.
This lets the kubernetes probe return a container node with the pod id,
which will get merged into the real containers with other reports. The
catch is that the kubernetes api doesn't tell us which hostname the
container is running on, so we can't populate the old-style node ids.
change terminology of system pods and services
Fix kubernetes services with no selector
Fixes handling of kubernetes service, which has no pods
fix parent links for pods/services
refactor detailed metadata to include sets and latest data
fixing up host rendering tests
fleshing out tests for node metadata and metrics
don't render container pseudo-nodes as processes
Update test for id format change.