Skip to content

Commit

Permalink
Add official k8s support
Browse files Browse the repository at this point in the history
See k8s/README.md doc
  • Loading branch information
Leonid Bugaev authored and Leonid Bugaev committed Feb 7, 2022
1 parent b520511 commit 8f5f307
Show file tree
Hide file tree
Showing 12 changed files with 1,451 additions and 26 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ vendor:
go mod vendor

release-bin: vendor
docker run --rm -v `pwd`:$(SOURCE_PATH) -t --env GOOS=linux --env GOARCH=amd64 -i $(CONTAINER) go build -mod=vendor -o $(BIN_NAME) -tags netgo $(LDFLAGS)
docker run --rm -v `pwd`:$(SOURCE_PATH) -t --env GOOS=linux --env GOARCH=amd64 -i $(CONTAINER) go build -mod=vendor -o $(BIN_NAME) -tags netgo $(LDFLAGS)

release-arm64-bin: vendor
docker run --rm -v `pwd`:$(SOURCE_PATH) -t --env GOOS=linux --env GOARCH=arm64 -i $(CONTAINER) go build -mod=vendor -o $(BIN_NAME) -tags netgo $(LDFLAGS)

release-bin-mac: vendor
GOOS=darwin go build -mod=vendor -o $(BIN_NAME) $(MAC_LDFLAGS)
Expand Down Expand Up @@ -80,9 +83,17 @@ build:
install:
go install $(MAC_LDFLAGS)

build-env:
build-env: build-x64-env build-arm64-env

build-x64-env:
docker buildx build --platform linux/amd64 -t $(CONTAINER) -f Dockerfile.dev .

build-arm64-env:
docker buildx build --platform linux/arm64 -t $(CONTAINER) -f Dockerfile.dev .

build-docker:
docker build -t gor-dev -f Dockerfile .

profile:
go build && ./$(BIN_NAME) --output-http="http://localhost:9000" --input-dummy 0 --input-raw :9000 --input-http :9000 --memprofile=./mem.out --cpuprofile=./cpu.out --stats --output-http-stats --output-http-timeout 100ms

Expand Down
83 changes: 80 additions & 3 deletions capture/capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

var stats *expvar.Map
Expand Down Expand Up @@ -206,14 +210,81 @@ func (l *Listener) ListenBackground(ctx context.Context) chan error {
return err
}

// Allowed format:
// [namespace/]pod/[pod_name]
// [namespace/]deployment/[deployment_name]
// [namespace/]daemonset/[daemonset_name]
// [namespace/]labelSelector/[selector]
// [namespace/]fieldSelector/[selector]
func k8sIPs(addr string) []string {
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}

// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}

sections := strings.Split(addr, "/")

if len(sections) < 2 {
panic("Not supported k8s scheme. Allowed values: [namespace/]pod/[pod_name], [namespace/]deployment/[deployment_name], [namespace/]daemonset/[daemonset_name], [namespace/]label/[label-name]/[label-value]")
}

// If no namespace passed, assume it is ALL
switch sections[0] {
case "pod", "deployment", "daemonset", "labelSelector", "fieldSelector":
sections = append([]string{""}, sections...)
}

namespace, selectorType, selectorValue := sections[0], sections[1], sections[2]

labelSelector := ""
fieldSelector := ""

switch selectorType {
case "pod":
fieldSelector = "metadata.name=" + selectorValue
case "deployment":
labelSelector = "app=" + selectorValue
case "daemonset":
labelSelector = "pod-template-generation=1,name=" + selectorValue
case "labelSelector":
labelSelector = selectorValue
case "fieldSelector":
fieldSelector = selectorValue
}

pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: labelSelector, FieldSelector: fieldSelector})
if err != nil {
panic(err.Error())
}

var podIPs []string
for _, pod := range pods.Items {
for _, podIP := range pod.Status.PodIPs {
podIPs = append(podIPs, podIP.IP)
}
}
return podIPs
}

// Filter returns automatic filter applied by goreplay
// to a pcap handle of a specific interface
func (l *Listener) Filter(ifi pcap.Interface) (filter string) {
// https://www.tcpdump.org/manpages/pcap-filter.7.html

hosts := []string{l.host}
if listenAll(l.host) || isDevice(l.host, ifi) {
hosts = interfaceAddresses(ifi)

if strings.HasPrefix(l.host, "k8s://") {
hosts = k8sIPs(l.host[6:])
} else {
if listenAll(l.host) || isDevice(l.host, ifi) {
hosts = interfaceAddresses(ifi)
}
}

filter = portsFilter(l.Transport, "dst", l.ports)
Expand Down Expand Up @@ -357,7 +428,7 @@ func http1EndHint(m *tcp.Message) bool {
if m.MissingChunk() {
return false
}

req, res := http1StartHint(m.Packets()[0])
return proto.HasFullPayload(m, m.PacketData()...) && (req || res)
}
Expand Down Expand Up @@ -575,6 +646,12 @@ func (l *Listener) setInterfaces() (err error) {
}

for _, pi := range pifis {
if strings.HasPrefix(l.host, "k8s://") {
if !strings.HasPrefix(pi.Name, "veth") {
continue
}
}

if isDevice(l.host, pi) {
l.Interfaces = []pcap.Interface{pi}
return
Expand Down
3 changes: 2 additions & 1 deletion capture/sock_linux.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// +build linux
//go:build linux && !arm64
// +build linux,!arm64

package capture

Expand Down
3 changes: 2 additions & 1 deletion capture/sock_others.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// +build !linux
//go:build (!linux && ignore) || arm64 || darwin
// +build !linux,ignore arm64 darwin

package capture

Expand Down
15 changes: 10 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ require (
github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61 // indirect
github.com/aws/aws-sdk-go v1.33.2
github.com/bitly/go-hostpool v0.1.0 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/containerd/containerd v1.5.9 // indirect
github.com/docker/distribution v2.8.0+incompatible // indirect
github.com/docker/docker v20.10.12+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325
github.com/klauspost/compress v1.10.10 // indirect
github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b
github.com/morikuni/aec v1.0.0 // indirect
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.5.1
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.0.0-20211209124913-491a49abca63
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e
k8s.io/apimachinery v0.23.3
k8s.io/client-go v0.23.3
)
Loading

0 comments on commit 8f5f307

Please sign in to comment.