mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-06-27 08:39:49 +00:00
support linkerd (#547)
* support linkerd - initial commit * renaming readEnvironmentVariable
This commit is contained in:
parent
2d78785558
commit
a75bac181d
38
tap/source/discoverer_util.go
Normal file
38
tap/source/discoverer_util.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package source
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
var numberRegex = regexp.MustCompile("[0-9]+")
|
||||||
|
|
||||||
|
func getSingleValueFromEnvironmentVariableFile(filePath string, variableName string) (string, error) {
|
||||||
|
bytes, err := ioutil.ReadFile(filePath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Warningf("Error reading environment file %v - %v", filePath, err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
envs := strings.Split(string(bytes), string([]byte{0}))
|
||||||
|
|
||||||
|
for _, env := range envs {
|
||||||
|
if !strings.Contains(env, "=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(env, "=")
|
||||||
|
varName := parts[0]
|
||||||
|
value := parts[1]
|
||||||
|
|
||||||
|
if variableName == varName {
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
@ -13,8 +12,6 @@ import (
|
|||||||
|
|
||||||
const envoyBinary = "/envoy"
|
const envoyBinary = "/envoy"
|
||||||
|
|
||||||
var numberRegex = regexp.MustCompile("[0-9]+")
|
|
||||||
|
|
||||||
func discoverRelevantEnvoyPids(procfs string, pods []v1.Pod) ([]string, error) {
|
func discoverRelevantEnvoyPids(procfs string, pods []v1.Pod) ([]string, error) {
|
||||||
result := make([]string, 0)
|
result := make([]string, 0)
|
||||||
|
|
||||||
@ -36,7 +33,7 @@ func discoverRelevantEnvoyPids(procfs string, pods []v1.Pod) ([]string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if checkPid(procfs, pid.Name(), pods) {
|
if checkEnvoyPid(procfs, pid.Name(), pods) {
|
||||||
result = append(result, pid.Name())
|
result = append(result, pid.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,7 +43,7 @@ func discoverRelevantEnvoyPids(procfs string, pods []v1.Pod) ([]string, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkPid(procfs string, pid string, pods []v1.Pod) bool {
|
func checkEnvoyPid(procfs string, pid string, pods []v1.Pod) bool {
|
||||||
execLink := fmt.Sprintf("%v/%v/exe", procfs, pid)
|
execLink := fmt.Sprintf("%v/%v/exe", procfs, pid)
|
||||||
exec, err := os.Readlink(execLink)
|
exec, err := os.Readlink(execLink)
|
||||||
|
|
||||||
@ -63,7 +60,7 @@ func checkPid(procfs string, pid string, pods []v1.Pod) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
environmentFile := fmt.Sprintf("%v/%v/environ", procfs, pid)
|
environmentFile := fmt.Sprintf("%v/%v/environ", procfs, pid)
|
||||||
podIp, err := readEnvironmentVariable(environmentFile, "INSTANCE_IP")
|
podIp, err := getSingleValueFromEnvironmentVariableFile(environmentFile, "INSTANCE_IP")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -84,30 +81,3 @@ func checkPid(procfs string, pid string, pods []v1.Pod) bool {
|
|||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func readEnvironmentVariable(file string, name string) (string, error) {
|
|
||||||
bytes, err := ioutil.ReadFile(file)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Log.Warningf("Error reading environment file %v - %v", file, err)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
envs := strings.Split(string(bytes), string([]byte{0}))
|
|
||||||
|
|
||||||
for _, env := range envs {
|
|
||||||
if !strings.Contains(env, "=") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := strings.Split(env, "=")
|
|
||||||
varName := parts[0]
|
|
||||||
value := parts[1]
|
|
||||||
|
|
||||||
if name == varName {
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
83
tap/source/linkerd_discoverer.go
Normal file
83
tap/source/linkerd_discoverer.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package source
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const linkerdBinary = "/linkerd2-proxy"
|
||||||
|
|
||||||
|
func discoverRelevantLinkerdPids(procfs string, pods []v1.Pod) ([]string, error) {
|
||||||
|
result := make([]string, 0)
|
||||||
|
|
||||||
|
pids, err := ioutil.ReadDir(procfs)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("Starting linkerd auto discoverer %v %v - scanning %v potential pids",
|
||||||
|
procfs, pods, len(pids))
|
||||||
|
|
||||||
|
for _, pid := range pids {
|
||||||
|
if !pid.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !numberRegex.MatchString(pid.Name()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkLinkerdPid(procfs, pid.Name(), pods) {
|
||||||
|
result = append(result, pid.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("Found %v relevant linkerd processes - %v", len(result), result)
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkLinkerdPid(procfs string, pid string, pods []v1.Pod) bool {
|
||||||
|
execLink := fmt.Sprintf("%v/%v/exe", procfs, pid)
|
||||||
|
exec, err := os.Readlink(execLink)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// Debug on purpose - it may happen due to many reasons and we only care
|
||||||
|
// for it during troubleshooting
|
||||||
|
//
|
||||||
|
logger.Log.Debugf("Unable to read link %v - %v\n", execLink, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasSuffix(exec, linkerdBinary) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
environmentFile := fmt.Sprintf("%v/%v/environ", procfs, pid)
|
||||||
|
podName, err := getSingleValueFromEnvironmentVariableFile(environmentFile, "_pod_name")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if podName == "" {
|
||||||
|
logger.Log.Debugf("Found a linkerd process without _pod_name variable %v\n", pid)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("Found linkerd pid %v with pod name %v", pid, podName)
|
||||||
|
|
||||||
|
for _, pod := range pods {
|
||||||
|
if pod.Name == podName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
@ -16,7 +16,7 @@ type PacketSourceManager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketSourceManager(procfs string, pids string, filename string, interfaceName string,
|
func NewPacketSourceManager(procfs string, pids string, filename string, interfaceName string,
|
||||||
istio bool, pods []v1.Pod, behaviour TcpPacketSourceBehaviour) (*PacketSourceManager, error) {
|
mtls bool, pods []v1.Pod, behaviour TcpPacketSourceBehaviour) (*PacketSourceManager, error) {
|
||||||
sources := make([]*tcpPacketSource, 0)
|
sources := make([]*tcpPacketSource, 0)
|
||||||
sources, err := createHostSource(sources, filename, interfaceName, behaviour)
|
sources, err := createHostSource(sources, filename, interfaceName, behaviour)
|
||||||
|
|
||||||
@ -25,7 +25,8 @@ func NewPacketSourceManager(procfs string, pids string, filename string, interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
sources = createSourcesFromPids(sources, procfs, pids, interfaceName, behaviour)
|
sources = createSourcesFromPids(sources, procfs, pids, interfaceName, behaviour)
|
||||||
sources = createSourcesFromEnvoy(sources, istio, procfs, pods, interfaceName, behaviour)
|
sources = createSourcesFromEnvoy(sources, mtls, procfs, pods, interfaceName, behaviour)
|
||||||
|
sources = createSourcesFromLinkerd(sources, mtls, procfs, pods, interfaceName, behaviour)
|
||||||
|
|
||||||
return &PacketSourceManager{
|
return &PacketSourceManager{
|
||||||
sources: sources,
|
sources: sources,
|
||||||
@ -54,13 +55,13 @@ func createSourcesFromPids(sources []*tcpPacketSource, procfs string, pids strin
|
|||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSourcesFromEnvoy(sources []*tcpPacketSource, istio bool, procfs string, clusterIps []v1.Pod,
|
func createSourcesFromEnvoy(sources []*tcpPacketSource, mtls bool, procfs string, pods []v1.Pod,
|
||||||
interfaceName string, behaviour TcpPacketSourceBehaviour) []*tcpPacketSource {
|
interfaceName string, behaviour TcpPacketSourceBehaviour) []*tcpPacketSource {
|
||||||
if !istio {
|
if !mtls {
|
||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
|
|
||||||
envoyPids, err := discoverRelevantEnvoyPids(procfs, clusterIps)
|
envoyPids, err := discoverRelevantEnvoyPids(procfs, pods)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Warningf("Unable to discover envoy pids - %v", err)
|
logger.Log.Warningf("Unable to discover envoy pids - %v", err)
|
||||||
@ -73,6 +74,25 @@ func createSourcesFromEnvoy(sources []*tcpPacketSource, istio bool, procfs strin
|
|||||||
return sources
|
return sources
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createSourcesFromLinkerd(sources []*tcpPacketSource, mtls bool, procfs string, pods []v1.Pod,
|
||||||
|
interfaceName string, behaviour TcpPacketSourceBehaviour) []*tcpPacketSource {
|
||||||
|
if !mtls {
|
||||||
|
return sources
|
||||||
|
}
|
||||||
|
|
||||||
|
linkerdPids, err := discoverRelevantLinkerdPids(procfs, pods)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Warningf("Unable to discover linkerd pids - %v", err)
|
||||||
|
return sources
|
||||||
|
}
|
||||||
|
|
||||||
|
netnsSources := newNetnsPacketSources(procfs, linkerdPids, interfaceName, behaviour)
|
||||||
|
sources = append(sources, netnsSources...)
|
||||||
|
|
||||||
|
return sources
|
||||||
|
}
|
||||||
|
|
||||||
func newHostPacketSource(filename string, interfaceName string,
|
func newHostPacketSource(filename string, interfaceName string,
|
||||||
behaviour TcpPacketSourceBehaviour) (*tcpPacketSource, error) {
|
behaviour TcpPacketSourceBehaviour) (*tcpPacketSource, error) {
|
||||||
var name string
|
var name string
|
||||||
|
Loading…
Reference in New Issue
Block a user