Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New 'node-agent' that listens to pod events and loads eBPF programs #224

Closed
wants to merge 44 commits into from

Conversation

orishavit
Copy link
Contributor

Please see the contributing guidelines for how to create and submit a high-quality PR for this repo. This template is based on Auth0's excellent template.

Description

Describe the purpose of this PR along with any background information and the impacts of the proposed change. For the benefit of the community, please do not assume prior context.

Provide details that support your chosen implementation, including: breaking changes, alternatives considered, changes to the API, etc.

References

Include any links supporting this change such as a:

  • GitHub Issue/PR number addressed or fixed
  • StackOverflow post
  • Related pull requests/issues from other repos

If there are no references, simply delete this section.

Testing

Describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.

Please include any manual steps for testing end-to-end or functionality not covered by unit/integration tests.

Also include details of the environment this PR was developed in (language/platform/browser version).

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation for new/changed functionality in this PR and in github.com/otterize/docs

@orishavit orishavit force-pushed the shavit/node-agent-ebpf branch 15 times, most recently from b751a18 to df51970 Compare July 17, 2024 13:41
@orishavit orishavit force-pushed the shavit/node-agent-ebpf branch 2 times, most recently from 438e380 to e2cea47 Compare September 10, 2024 00:57
@orishavit orishavit force-pushed the shavit/node-agent-ebpf branch 2 times, most recently from df7bcf4 to 4b891d7 Compare September 11, 2024 16:15
@amitlicht amitlicht self-requested a review September 16, 2024 11:20
- only handle pods on the same node
- fix a crash where accessing a static var before it is initialized
@orishavit orishavit marked this pull request as ready for review September 19, 2024 16:04
@@ -0,0 +1,20 @@
FROM --platform=$TARGETPLATFORM golang:1.22.1 AS ebpf-buildenv
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need this? it's not referenced anywhere and AFAIU bpfman is no longer in use

Comment on lines +41 to +51
var sectionsToSearchForSymbol []*elf.Section

for i := range f.Sections {
if f.Sections[i].Flags == elf.SHF_ALLOC+elf.SHF_EXECINSTR {
sectionsToSearchForSymbol = append(sectionsToSearchForSymbol, f.Sections[i])
}
}

if len(sectionsToSearchForSymbol) == 0 {
return 0, fmt.Errorf("symbol %q not found in file - no sections to search", symbol)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider splitting this to a dedicated function getSectionsToSearchForSymbol(f) ([]*elf.Section) for readability and to shorten SymbolToOffset.

Comment on lines +53 to +67
var executableSection *elf.Section

// Find what section the symbol is in by checking the executable section's addr space.
for m := range sectionsToSearchForSymbol {
sectionStart := sectionsToSearchForSymbol[m].Addr
sectionEnd := sectionStart + sectionsToSearchForSymbol[m].Size
if symbol.Value >= sectionStart && symbol.Value < sectionEnd {
executableSection = sectionsToSearchForSymbol[m]
break
}
}

if executableSection == nil {
return 0, errors.New("could not find symbol in executable sections of binary")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here - consider splitting to a dedicated function findExecutableSection(sectionsToSearchForSymbol, symbol) *elf.Section.
This will also help with replacing the break with a return (which will help readability).

"github.com/otterize/network-mapper/src/bintools/bininfo"
)

// FunctionMetadata used to attach a uprobe to a function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// FunctionMetadata used to attach a uprobe to a function.
// FunctionMetadata used to attach a uprobe to a function.

Comment on lines +20 to +22
if cErr == nil {
err = cErr
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you really want to fail the entire flow if Close() failed? perhaps just log and continue

}, nil
}

func (e *EventReader) Start() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using context.Context to be able to trigger graceful shutdown here.

Comment on lines +105 to +115
if containerInfo.ExecutableInfo.Language == bininfo.SourceLanguageNodeJs {
err := r.tracer.AttachToOpenSSL(containerInfo)
if err != nil {
return errors.Wrap(err)
}
} else if containerInfo.ExecutableInfo.Language == bininfo.SourceLanguageGoLang {
err := r.tracer.AttachToGoTls(containerInfo)
if err != nil {
return errors.Wrap(err)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using switch containerInfo.ExecutableInfo.Language, which is more idiomatic here.

printHttpRequests = false
)

func init() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we typically use viper rather than raw env vars, which provides better control over argument types etc. Consider switching to it, both for consistency with other portions of our application, and for better code. you can take a look at the sniffer code for a relatively simple example.


EnvPodKey = "pod"
EnvNamespaceKey = "namespace"

// experimental features

EnableEBPFKey = "experimental-ebpf"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be called enable-ebpf (the experimental portion can go into description), or enable-ebpf-experimental if you really insist on including the experimental part in the flag name.

@@ -37,6 +37,7 @@ func main() {
})
errgrp, errGroupCtx := errgroup.WithContext(signals.SetupSignalHandler())
clusterUID := clusterutils.GetOrCreateClusterUID(errGroupCtx)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this

@amitlicht amitlicht closed this Oct 6, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Oct 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants