Compare commits

..

1 Commits

Author SHA1 Message Date
M. Mert Yildiran
428024004d 🔖 Bump the Helm chart version to 52.3.75 2024-08-17 14:47:42 +03:00
62 changed files with 2099 additions and 3913 deletions

2
.gitignore vendored
View File

@@ -63,4 +63,4 @@ bin
scripts/
# CWD config YAML
kubeshark.yaml
kubeshark.yaml

View File

@@ -7,7 +7,7 @@ Please read and follow the guidelines below.
## Communication
* Before starting work on a major feature, please reach out to us via [GitHub](https://github.com/kubeshark/kubeshark), [Discord](https://discord.gg/WkvRGMUcx7), [Slack](https://join.slack.com/t/kubeshark/shared_invite/zt-1k3sybpq9-uAhFkuPJiJftKniqrGHGhg), [email](mailto:info@kubehq.io), etc. We will make sure no one else is already working on it. A _major feature_ is defined as any change that is > 100 LOC altered (not including tests), or changes any user-facing behavior
* Before starting work on a major feature, please reach out to us via [GitHub](https://github.com/kubeshark/kubeshark), [Discord](https://discord.gg/WkvRGMUcx7), [Slack](https://join.slack.com/t/kubeshark/shared_invite/zt-1k3sybpq9-uAhFkuPJiJftKniqrGHGhg), [email](mailto:info@kubeshark.co), etc. We will make sure no one else is already working on it. A _major feature_ is defined as any change that is > 100 LOC altered (not including tests), or changes any user-facing behavior
* Small patches and bug fixes don't need prior communication.
## Contribution Requirements

View File

@@ -84,10 +84,7 @@ kubectl-view-kubeshark-resources: ## This command outputs all Kubernetes resourc
./kubectl.sh view-kubeshark-resources
generate-helm-values: ## Generate the Helm values from config.yaml
# [ -f ~/.kubeshark/config.yaml ] && mv ~/.kubeshark/config.yaml ~/.kubeshark/config.yaml.old
bin/kubeshark__ config>helm-chart/values.yaml
# [ -f ~/.kubeshark/config.yaml.old ] && mv ~/.kubeshark/config.yaml.old ~/.kubeshark/config.yaml
# sed -i 's/^license:.*/license: ""/' helm-chart/values.yaml && sed -i '1i # find a detailed description here: https://github.com/kubeshark/kubeshark/blob/master/helm-chart/README.md' helm-chart/values.yaml
./bin/kubeshark__ config > ./helm-chart/values.yaml && sed -i 's/^license:.*/license: ""/' helm-chart/values.yaml
generate-manifests: ## Generate the manifests from the Helm chart using default configuration
helm template kubeshark -n default ./helm-chart > ./manifests/complete.yaml
@@ -168,7 +165,7 @@ helm-install-debug:
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) --set tap.debug=true && cd ..
helm-install-profile:
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) --set tap.pprof.enabled=true && cd ..
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) --set tap.misc.profile=true && cd ..
helm-uninstall:
helm uninstall kubeshark
@@ -181,32 +178,13 @@ port-forward:
release:
@cd ../worker && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../tracer && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../hub && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../front && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../kubeshark && git checkout master && git pull && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make
@if [ "$(shell uname)" = "Darwin" ]; then \
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
fi
@make generate-helm-values && make generate-manifests
@cd ../kubeshark && sed -i 's/^version:.*/version: "$(VERSION)"/' helm-chart/Chart.yaml && make && make generate-helm-values && make generate-manifests
@git add -A . && git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)" && git push
@git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@rm -rf ../kubeshark.github.io/charts/chart && mkdir ../kubeshark.github.io/charts/chart && cp -r helm-chart/ ../kubeshark.github.io/charts/chart/
@cd ../kubeshark.github.io/ && git add -A . && git commit -m ":sparkles: Update the Helm chart" && git push
@cd ../kubeshark
release-dry-run:
@cd ../worker && git checkout master && git pull
@cd ../tracer && git checkout master && git pull
@cd ../hub && git checkout master && git pull
@cd ../front && git checkout master && git pull
@cd ../kubeshark && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make
@if [ "$(shell uname)" = "Darwin" ]; then \
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
fi
@make generate-helm-values && make generate-manifests
@rm -rf ../kubeshark.github.io/charts/chart && mkdir ../kubeshark.github.io/charts/chart && cp -r helm-chart/ ../kubeshark.github.io/charts/chart/
@cd ../kubeshark.github.io/
@git tag v$(VERSION) && git push origin --tags
@cd helm-chart && cp -r . ../../kubeshark.github.io/charts/chart
@cd ../../kubeshark.github.io/ && git add -A . && git commit -m ":sparkles: Update the Helm chart" && git push
@cd ../kubeshark
branch:

View File

@@ -12,89 +12,70 @@
<a href="https://hub.docker.com/r/kubeshark/worker">
<img alt="Image size" src="https://img.shields.io/docker/image-size/kubeshark/kubeshark/latest?logo=Docker&style=flat-square">
</a>
<a href="https://discord.gg/WkvRGMUcx7">
<a href="https://discord.gg/WkvRGMUcx7">
<img alt="Discord" src="https://img.shields.io/discord/1042559155224973352?logo=Discord&style=flat-square&label=discord">
</a>
<a href="https://join.slack.com/t/kubeshark/shared_invite/zt-3jdcdgxdv-1qNkhBh9c6CFoE7bSPkpBQ">
<a href="https://join.slack.com/t/kubeshark/shared_invite/zt-1m90td3n7-VHxN_~V5kVp80SfQW3SfpA">
<img alt="Slack" src="https://img.shields.io/badge/slack-join_chat-green?logo=Slack&style=flat-square&label=slack">
</a>
</p>
<p align="center">
<b>
Want to see Kubeshark in action right now? Visit this
<a href="https://kubeshark.kubehq.com/">live demo deployment</a> of Kubeshark.
Want to see Kubeshark in action, right now? Visit this
<a href="https://demo.kubeshark.co/">live demo deployment</a> of Kubeshark.
</b>
</p>
> Latest release enables free deployment on clusters with up to 100 nodes.
**Kubeshark** is an API traffic analyzer for Kubernetes, providing deep packet inspection with complete API and Kubernetes contexts, retaining cluster-wide L4 traffic (PCAP), and using minimal production compute resources.
**Kubeshark** is an API Traffic Analyzer for [**Kubernetes**](https://kubernetes.io/) providing real-time, protocol-level visibility into Kubernetes internal network, capturing and monitoring all traffic and payloads going in, out and across containers, pods, nodes and clusters.
![Simple UI](https://github.com/kubeshark/assets/raw/master/png/kubeshark-ui.png)
Think [TCPDump](https://en.wikipedia.org/wiki/Tcpdump) and [Wireshark](https://www.wireshark.org/) reimagined for Kubernetes.
Access cluster-wide PCAP traffic by pressing a single button, without the need to install `tcpdump` or manually copy files. Understand the traffic context in relation to the API and Kubernetes contexts.
#### Service-Map w/Kubernetes Context
![Service Map with Kubernetes Context](https://github.com/kubeshark/assets/raw/master/png/kubeshark-servicemap.png)
#### Export Cluster-Wide L4 Traffic (PCAP)
Imagine having a cluster-wide [TCPDump](https://www.tcpdump.org/)-like capability—exporting a single [PCAP](https://www.ietf.org/archive/id/draft-gharris-opsawg-pcap-01.html) file that consolidates traffic from multiple nodes, all accessible with a single click.
1. Go to the **Snapshots** tab
2. Create a new snapshot
3. **Optionally** select the nodes (default: all nodes)
4. **Optionally** select the time frame (default: last one hour)
5. Press **Create**
<img width="3342" height="1206" alt="image" src="https://github.com/user-attachments/assets/e8e47996-52b7-4028-9698-f059a13ffdb7" />
Once the snapshot is ready, click the PCAP file to export its contents and open it in Wireshark.
Think [TCPDump](https://en.wikipedia.org/wiki/Tcpdump) and [Wireshark](https://www.wireshark.org/) re-invented for Kubernetes
## Getting Started
Download **Kubeshark**'s binary distribution [latest release](https://github.com/kubeshark/kubeshark/releases/latest) or use one of the following methods to deploy **Kubeshark**. The [web-based dashboard](https://docs.kubehq.com/en/ui) should open in your browser, showing a real-time view of your cluster's traffic.
### Homebrew
[Homebrew](https://brew.sh/) :beer: users can install the Kubeshark CLI with:
Download **Kubeshark**'s binary distribution [latest release](https://github.com/kubeshark/kubeshark/releases/latest) and run following one of these examples:
```shell
brew install kubeshark
kubeshark tap
```
To clean up:
```shell
kubeshark clean
kubeshark tap -n sock-shop "(catalo*|front-end*)"
```
Running any of the :point_up: above commands will open the [Web UI](https://docs.kubeshark.co/en/ui) in your browser which streams the traffic in your Kubernetes cluster in real-time.
### Homebrew
[Homebrew](https://brew.sh/) :beer: users install Kubeshark CLI with:
```shell
brew install kubeshark
```
### Helm
Add the Helm repository and install the chart:
Add the helm repository and install the chart:
```shell
helm repo add kubeshark https://helm.kubehq.com
helm install kubeshark kubeshark/kubeshark
```
Follow the on-screen instructions how to connect to the dashboard.
To clean up:
```shell
helm uninstall kubeshark
helm repo add kubeshark https://helm.kubeshark.co
helm install kubeshark kubeshark/kubeshark
```
## Building From Source
Clone this repository and run the `make` command to build it. After the build is complete, the executable can be found at `./bin/kubeshark`.
Clone this repository and run `make` command to build it. After the build is complete, the executable can be found at `./bin/kubeshark__`.
## Documentation
To learn more, read the [documentation](https://docs.kubehq.com).
To learn more, read the [documentation](https://docs.kubeshark.co).
## Contributing
We :heart: pull requests! See [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution guide.
## Code of Conduct
This project is for everyone. We ask that our users and contributors take a few minutes to review our [Code of Conduct](CODE_OF_CONDUCT.md).

View File

@@ -10,7 +10,7 @@ curl -Lo kubeshark https://github.com/kubeshark/kubeshark/releases/download/_VER
**Mac** (AArch64/Apple M1 silicon)
```
curl -Lo kubeshark https://github.com/kubeshark/kubeshark/releases/download/_VER_/kubeshark_darwin_arm64 && chmod 755 kubeshark
rm -f kubeshark && curl -Lo kubeshark https://github.com/kubeshark/kubeshark/releases/download/_VER_/kubeshark_darwin_arm64 && chmod 755 kubeshark
```
**Linux** (x86-64)

View File

@@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"path"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config"
@@ -51,5 +52,5 @@ func init() {
log.Debug().Err(err).Send()
}
configCmd.Flags().BoolP(configStructs.RegenerateConfigName, "r", defaultConfig.Config.Regenerate, fmt.Sprintf("Regenerate the config file with default values to path %s", config.GetConfigFilePath(nil)))
configCmd.Flags().BoolP(configStructs.RegenerateConfigName, "r", defaultConfig.Config.Regenerate, fmt.Sprintf("Regenerate the config file with default values to path %s", path.Join(misc.GetDotFolderPath(), "config.yaml")))
}

View File

@@ -41,116 +41,76 @@ func init() {
consoleCmd.Flags().StringP(configStructs.ReleaseNamespaceLabel, "s", defaultTapConfig.Release.Namespace, "Release namespace of Kubeshark")
}
func runConsoleWithoutProxy() {
log.Info().Msg("Starting scripting console ...")
time.Sleep(5 * time.Second)
hubUrl := kubernetes.GetHubUrl()
for {
// Attempt to connect to the Hub every second
response, err := http.Get(fmt.Sprintf("%s/echo", hubUrl))
if err != nil || response.StatusCode != 200 {
log.Info().Msg(fmt.Sprintf(utils.Yellow, "Couldn't connect to Hub."))
time.Sleep(5 * time.Second)
continue
}
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
log.Info().Str("host", config.Config.Tap.Proxy.Host).Str("url", hubUrl).Msg("Connecting to:")
u := url.URL{
Scheme: "ws",
Host: fmt.Sprintf("%s:%d", config.Config.Tap.Proxy.Host, config.Config.Tap.Proxy.Front.Port),
Path: "/api/scripts/logs",
}
headers := http.Header{}
headers.Set(utils.X_KUBESHARK_CAPTURE_HEADER_KEY, utils.X_KUBESHARK_CAPTURE_HEADER_IGNORE_VALUE)
headers.Set("License-Key", config.Config.License)
c, _, err := websocket.DefaultDialer.Dial(u.String(), headers)
if err != nil {
log.Error().Err(err).Msg("Websocket dial error, retrying in 5 seconds...")
time.Sleep(5 * time.Second) // Delay before retrying
continue
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Error().Err(err).Msg("Error reading websocket message, reconnecting...")
break // Break to reconnect
}
msg := string(message)
if strings.Contains(msg, ":ERROR]") {
msg = fmt.Sprintf(utils.Red, msg)
fmt.Fprintln(os.Stderr, msg)
} else {
fmt.Fprintln(os.Stdout, msg)
}
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
select {
case <-done:
log.Warn().Msg(fmt.Sprintf(utils.Yellow, "Connection closed, reconnecting..."))
time.Sleep(5 * time.Second) // Delay before reconnecting
continue // Reconnect after error
case <-interrupt:
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Error().Err(err).Send()
continue
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
func runConsole() {
go runConsoleWithoutProxy()
hubUrl := kubernetes.GetHubUrl()
response, err := http.Get(fmt.Sprintf("%s/echo", hubUrl))
if err != nil || response.StatusCode != 200 {
log.Info().Msg(fmt.Sprintf(utils.Yellow, "Couldn't connect to Hub. Establishing proxy..."))
runProxy(false, true)
}
// Create interrupt channel and setup signal handling once
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
log.Info().Str("host", config.Config.Tap.Proxy.Host).Str("url", hubUrl).Msg("Connecting to:")
u := url.URL{
Scheme: "ws",
Host: fmt.Sprintf("%s:%d/api", config.Config.Tap.Proxy.Host, config.Config.Tap.Proxy.Front.Port),
Path: "/scripts/logs",
}
headers := http.Header{}
headers.Set(utils.X_KUBESHARK_CAPTURE_HEADER_KEY, utils.X_KUBESHARK_CAPTURE_HEADER_IGNORE_VALUE)
headers.Set("License-Key", config.Config.License)
c, _, err := websocket.DefaultDialer.Dial(u.String(), headers)
if err != nil {
log.Error().Err(err).Send()
return
}
defer c.Close()
done := make(chan struct{})
ticker := time.NewTicker(5 * time.Second)
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Error().Err(err).Send()
return
}
msg := string(message)
if strings.Contains(msg, ":ERROR]") {
msg = fmt.Sprintf(utils.Red, msg)
fmt.Fprintln(os.Stderr, msg)
} else {
fmt.Fprintln(os.Stdout, msg)
}
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case <-interrupt:
// Handle interrupt and exit gracefully
log.Warn().Msg(fmt.Sprintf(utils.Yellow, "Received interrupt, exiting..."))
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Error().Err(err).Send()
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
case <-ticker.C:
// Attempt to connect to the Hub every second
hubUrl := kubernetes.GetHubUrl()
response, err := http.Get(fmt.Sprintf("%s/echo", hubUrl))
if err != nil || response.StatusCode != 200 {
log.Info().Msg(fmt.Sprintf(utils.Yellow, "Couldn't connect to Hub. Establishing proxy..."))
runProxy(false, true)
}
}
}
}

62
cmd/export.go Normal file
View File

@@ -0,0 +1,62 @@
package cmd
import (
"fmt"
"net/http"
"os"
"path/filepath"
"time"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/kubeshark/kubeshark/internal/connect"
"github.com/kubeshark/kubeshark/kubernetes"
"github.com/kubeshark/kubeshark/utils"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var exportCmd = &cobra.Command{
Use: "export",
Short: "Exports the captured traffic into a TAR file that contains PCAP files",
RunE: func(cmd *cobra.Command, args []string) error {
runExport()
return nil
},
}
func init() {
rootCmd.AddCommand(exportCmd)
defaultTapConfig := configStructs.TapConfig{}
if err := defaults.Set(&defaultTapConfig); err != nil {
log.Debug().Err(err).Send()
}
exportCmd.Flags().Uint16(configStructs.ProxyFrontPortLabel, defaultTapConfig.Proxy.Front.Port, "Provide a custom port for the Kubeshark")
exportCmd.Flags().String(configStructs.ProxyHostLabel, defaultTapConfig.Proxy.Host, "Provide a custom host for the Kubeshark")
exportCmd.Flags().StringP(configStructs.ReleaseNamespaceLabel, "s", defaultTapConfig.Release.Namespace, "Release namespace of Kubeshark")
}
func runExport() {
hubUrl := kubernetes.GetHubUrl()
response, err := http.Get(fmt.Sprintf("%s/echo", hubUrl))
if err != nil || response.StatusCode != 200 {
log.Info().Msg(fmt.Sprintf(utils.Yellow, "Couldn't connect to Hub. Establishing proxy..."))
runProxy(false, true)
}
dstPath, err := filepath.Abs(fmt.Sprintf("./%d.tar.gz", time.Now().Unix()))
if err != nil {
panic(err)
}
out, err := os.Create(dstPath)
if err != nil {
panic(err)
}
defer out.Close()
connector := connect.NewConnector(kubernetes.GetHubUrl(), connect.DefaultRetries, connect.DefaultTimeout)
connector.PostPcapsMerge(out)
}

View File

@@ -1,110 +0,0 @@
package cmd
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"
)
// pcapDumpCmd represents the consolidated pcapdump command
var pcapDumpCmd = &cobra.Command{
Use: "pcapdump",
Short: "Store all captured traffic (including decrypted TLS) in a PCAP file.",
RunE: func(cmd *cobra.Command, args []string) error {
// Retrieve the kubeconfig path from the flag
kubeconfig, _ := cmd.Flags().GetString(configStructs.PcapKubeconfig)
// If kubeconfig is not provided, use the default location
if kubeconfig == "" {
if home := homedir.HomeDir(); home != "" {
kubeconfig = filepath.Join(home, ".kube", "config")
} else {
return errors.New("kubeconfig flag not provided and no home directory available for default config location")
}
}
debugEnabled, _ := cmd.Flags().GetBool("debug")
if debugEnabled {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
log.Debug().Msg("Debug logging enabled")
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
// Use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
return fmt.Errorf("Error building kubeconfig: %w", err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return fmt.Errorf("Error creating Kubernetes client: %w", err)
}
// Parse the `--time` flag
timeIntervalStr, _ := cmd.Flags().GetString("time")
var cutoffTime *time.Time // Use a pointer to distinguish between provided and not provided
if timeIntervalStr != "" {
duration, err := time.ParseDuration(timeIntervalStr)
if err != nil {
return fmt.Errorf("Invalid format %w", err)
}
tempCutoffTime := time.Now().Add(-duration)
cutoffTime = &tempCutoffTime
}
// Test the dest dir if provided
destDir, _ := cmd.Flags().GetString(configStructs.PcapDest)
if destDir != "" {
info, err := os.Stat(destDir)
if os.IsNotExist(err) {
return fmt.Errorf("Directory does not exist: %s", destDir)
}
if err != nil {
return fmt.Errorf("Error checking dest directory: %w", err)
}
if !info.IsDir() {
return fmt.Errorf("Dest path is not a directory: %s", destDir)
}
tempFile, err := os.CreateTemp(destDir, "write-test-*")
if err != nil {
return fmt.Errorf("Directory %s is not writable", destDir)
}
_ = os.Remove(tempFile.Name())
}
log.Info().Msg("Copying PCAP files")
err = copyPcapFiles(clientset, config, destDir, cutoffTime)
if err != nil {
return err
}
return nil
},
}
func init() {
rootCmd.AddCommand(pcapDumpCmd)
defaultPcapDumpConfig := configStructs.PcapDumpConfig{}
if err := defaults.Set(&defaultPcapDumpConfig); err != nil {
log.Debug().Err(err).Send()
}
pcapDumpCmd.Flags().String(configStructs.PcapTime, "", "Time interval (e.g., 10m, 1h) in the past for which the pcaps are copied")
pcapDumpCmd.Flags().String(configStructs.PcapDest, "", "Local destination path for copied PCAP files (can not be used together with --enabled)")
pcapDumpCmd.Flags().String(configStructs.PcapKubeconfig, "", "Path for kubeconfig (if not provided the default location will be checked)")
pcapDumpCmd.Flags().Bool("debug", false, "Enable debug logging")
}

View File

@@ -1,371 +0,0 @@
package cmd
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/kubeshark/gopacket/pcapgo"
"github.com/rs/zerolog/log"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
clientk8s "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
)
const (
label = "app.kubehq.com/app=worker"
srcDir = "pcapdump"
maxSnaplen uint32 = 262144
maxTimePerFile = time.Minute * 5
)
// PodFileInfo represents information about a pod, its namespace, and associated files
type PodFileInfo struct {
Pod corev1.Pod
SrcDir string
Files []string
CopiedFiles []string
}
// listWorkerPods fetches all worker pods from multiple namespaces
func listWorkerPods(ctx context.Context, clientset *clientk8s.Clientset, namespaces []string) ([]*PodFileInfo, error) {
var podFileInfos []*PodFileInfo
var errs []error
labelSelector := label
for _, namespace := range namespaces {
// List all pods matching the label in the current namespace
pods, err := clientset.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{
LabelSelector: labelSelector,
})
if err != nil {
errs = append(errs, fmt.Errorf("failed to list worker pods in namespace %s: %w", namespace, err))
continue
}
for _, pod := range pods.Items {
podFileInfos = append(podFileInfos, &PodFileInfo{
Pod: pod,
})
}
}
return podFileInfos, errors.Join(errs...)
}
// listFilesInPodDir lists all files in the specified directory inside the pod across multiple namespaces
func listFilesInPodDir(ctx context.Context, clientset *clientk8s.Clientset, config *rest.Config, pod *PodFileInfo, cutoffTime *time.Time) error {
nodeName := pod.Pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir)
cmd := []string{"ls", srcFilePath}
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(pod.Pod.Name).
Namespace(pod.Pod.Namespace).
SubResource("exec").
Param("container", "sniffer").
Param("stdout", "true").
Param("stderr", "true").
Param("command", cmd[0]).
Param("command", cmd[1])
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return err
}
var stdoutBuf bytes.Buffer
var stderrBuf bytes.Buffer
// Execute the command to list files
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdout: &stdoutBuf,
Stderr: &stderrBuf,
})
if err != nil {
return err
}
// Split the output (file names) into a list
files := strings.Split(strings.TrimSpace(stdoutBuf.String()), "\n")
if len(files) == 0 {
// No files were found in the target dir for this pod
return nil
}
var filteredFiles []string
var fileProcessingErrs []error
// Filter files based on cutoff time if provided
for _, file := range files {
if cutoffTime != nil {
parts := strings.Split(file, "-")
if len(parts) < 2 {
continue
}
timestampStr := parts[len(parts)-2] + parts[len(parts)-1][:6] // Extract YYYYMMDDHHMMSS
fileTime, err := time.Parse("20060102150405", timestampStr)
if err != nil {
fileProcessingErrs = append(fileProcessingErrs, fmt.Errorf("failed parse file timestamp %s: %w", file, err))
continue
}
if fileTime.Before(*cutoffTime) {
continue
}
}
// Add file to filtered list
filteredFiles = append(filteredFiles, file)
}
pod.SrcDir = srcDir
pod.Files = filteredFiles
return errors.Join(fileProcessingErrs...)
}
// copyFileFromPod copies a single file from a pod to a local destination
func copyFileFromPod(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, pod *PodFileInfo, srcFile, destFile string) error {
// Construct the complete path using /data, the node name, srcDir, and srcFile
nodeName := pod.Pod.Spec.NodeName
srcFilePath := filepath.Join("data", nodeName, srcDir, srcFile)
// Execute the `cat` command to read the file at the srcFilePath
cmd := []string{"cat", srcFilePath}
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(pod.Pod.Name).
Namespace(pod.Pod.Namespace).
SubResource("exec").
Param("container", "sniffer").
Param("stdout", "true").
Param("stderr", "true").
Param("command", cmd[0]).
Param("command", cmd[1])
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return fmt.Errorf("failed to initialize executor for pod %s in namespace %s: %w", pod.Pod.Name, pod.Pod.Namespace, err)
}
// Create the local file to write the content to
outFile, err := os.Create(destFile)
if err != nil {
return fmt.Errorf("failed to create destination file: %w", err)
}
defer outFile.Close()
// Capture stderr for error logging
var stderrBuf bytes.Buffer
// Stream the file content from the pod to the local file
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdout: outFile,
Stderr: &stderrBuf,
})
if err != nil {
return err
}
return nil
}
func mergePCAPs(outputFile string, inputFiles []string) error {
// Create the output file
f, err := os.Create(outputFile)
if err != nil {
return fmt.Errorf("failed to create output file: %w", err)
}
defer f.Close()
bufWriter := bufio.NewWriterSize(f, 4*1024*1024)
defer bufWriter.Flush()
// Create the PCAP writer
writer := pcapgo.NewWriter(bufWriter)
err = writer.WriteFileHeader(maxSnaplen, 1)
if err != nil {
return fmt.Errorf("failed to write PCAP file header: %w", err)
}
var mergingErrs []error
for _, inputFile := range inputFiles {
// Open the input file
file, err := os.Open(inputFile)
if err != nil {
mergingErrs = append(mergingErrs, fmt.Errorf("failed to open %s: %w", inputFile, err))
continue
}
fileInfo, err := file.Stat()
if err != nil {
mergingErrs = append(mergingErrs, fmt.Errorf("failed to stat file %s: %w", inputFile, err))
file.Close()
continue
}
if fileInfo.Size() == 0 {
// Skip empty files
log.Debug().Msgf("Skipped empty file: %s", inputFile)
file.Close()
continue
}
// Create the PCAP reader for the input file
reader, err := pcapgo.NewReader(file)
if err != nil {
mergingErrs = append(mergingErrs, fmt.Errorf("failed to create pcapng reader for %v: %w", file.Name(), err))
file.Close()
continue
}
for {
// Read packet data
data, ci, err := reader.ReadPacketData()
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
break
}
mergingErrs = append(mergingErrs, fmt.Errorf("error reading packet from file %s: %w", file.Name(), err))
break
}
// Write the packet to the output file
err = writer.WritePacket(ci, data)
if err != nil {
log.Error().Err(err).Msgf("Error writing packet to output file")
mergingErrs = append(mergingErrs, fmt.Errorf("error writing packet to output file: %w", err))
break
}
}
file.Close()
}
log.Debug().Err(errors.Join(mergingErrs...))
return nil
}
func copyPcapFiles(clientset *kubernetes.Clientset, config *rest.Config, destDir string, cutoffTime *time.Time) error {
// List all namespaces
namespaceList, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
if err != nil {
return err
}
var targetNamespaces []string
for _, ns := range namespaceList.Items {
targetNamespaces = append(targetNamespaces, ns.Name)
}
// List all worker pods
workerPods, err := listWorkerPods(context.Background(), clientset, targetNamespaces)
if err != nil {
if len(workerPods) == 0 {
return err
}
log.Debug().Err(err).Msg("error while listing worker pods")
}
var wg sync.WaitGroup
// Launch a goroutine for each pod
for _, pod := range workerPods {
wg.Add(1)
go func(pod *PodFileInfo) {
defer wg.Done()
// List files for the current pod
err := listFilesInPodDir(context.Background(), clientset, config, pod, cutoffTime)
if err != nil {
log.Debug().Err(err).Msgf("error listing files in pod %s", pod.Pod.Name)
return
}
// Copy files from the pod
for _, file := range pod.Files {
destFile := filepath.Join(destDir, file)
// Add a timeout context for file copy
ctx, cancel := context.WithTimeout(context.Background(), maxTimePerFile)
err := copyFileFromPod(ctx, clientset, config, pod, file, destFile)
cancel()
if err != nil {
log.Debug().Err(err).Msgf("error copying file %s from pod %s in namespace %s", file, pod.Pod.Name, pod.Pod.Namespace)
continue
}
log.Info().Msgf("Copied file %s from pod %s to %s", file, pod.Pod.Name, destFile)
pod.CopiedFiles = append(pod.CopiedFiles, destFile)
}
}(pod)
}
// Wait for all goroutines to complete
wg.Wait()
var copiedFiles []string
for _, pod := range workerPods {
copiedFiles = append(copiedFiles, pod.CopiedFiles...)
}
if len(copiedFiles) == 0 {
log.Info().Msg("No pcaps available to copy on the workers")
return nil
}
// Generate a temporary filename for the merged file
tempMergedFile := copiedFiles[0] + "_temp"
// Merge PCAP files
err = mergePCAPs(tempMergedFile, copiedFiles)
if err != nil {
os.Remove(tempMergedFile)
return fmt.Errorf("error merging files: %w", err)
}
// Remove the original files after merging
for _, file := range copiedFiles {
if err = os.Remove(file); err != nil {
log.Debug().Err(err).Msgf("error removing file %s", file)
}
}
clusterID, err := getClusterID(clientset)
if err != nil {
return fmt.Errorf("failed to get cluster ID: %w", err)
}
timestamp := time.Now().Format("2006-01-02_15-04")
// Rename the temp file to the final name
finalMergedFile := filepath.Join(destDir, fmt.Sprintf("%s-%s.pcap", clusterID, timestamp))
err = os.Rename(tempMergedFile, finalMergedFile)
if err != nil {
return err
}
log.Info().Msgf("Merged file created: %s", finalMergedFile)
return nil
}
func getClusterID(clientset *kubernetes.Clientset) (string, error) {
namespace, err := clientset.CoreV1().Namespaces().Get(context.TODO(), "kube-system", metav1.GetOptions{})
if err != nil {
return "", fmt.Errorf("failed to get kube-system namespace UID: %w", err)
}
return string(namespace.UID), nil
}

View File

@@ -1,32 +0,0 @@
package cmd
import (
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var pprofCmd = &cobra.Command{
Use: "pprof",
Short: "Select a Kubeshark container and open the pprof web UI in the browser",
RunE: func(cmd *cobra.Command, args []string) error {
runPprof()
return nil
},
}
func init() {
rootCmd.AddCommand(pprofCmd)
defaultTapConfig := configStructs.TapConfig{}
if err := defaults.Set(&defaultTapConfig); err != nil {
log.Debug().Err(err).Send()
}
pprofCmd.Flags().Uint16(configStructs.ProxyFrontPortLabel, defaultTapConfig.Proxy.Front.Port, "Provide a custom port for the proxy/port-forward")
pprofCmd.Flags().String(configStructs.ProxyHostLabel, defaultTapConfig.Proxy.Host, "Provide a custom host for the proxy/port-forward")
pprofCmd.Flags().StringP(configStructs.ReleaseNamespaceLabel, "s", defaultTapConfig.Release.Namespace, "Release namespace of Kubeshark")
pprofCmd.Flags().Uint16(configStructs.PprofPortLabel, defaultTapConfig.Pprof.Port, "Provide a custom port for the pprof server")
pprofCmd.Flags().String(configStructs.PprofViewLabel, defaultTapConfig.Pprof.View, "Change the default view of the pprof web interface")
}

View File

@@ -1,176 +0,0 @@
package cmd
import (
"context"
"fmt"
"github.com/go-cmd/cmd"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/kubernetes"
"github.com/kubeshark/kubeshark/utils"
"github.com/rivo/tview"
"github.com/rs/zerolog/log"
v1 "k8s.io/api/core/v1"
)
func runPprof() {
runProxy(false, true)
provider, err := getKubernetesProviderForCli(false, false)
if err != nil {
return
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
hubPods, err := provider.ListPodsByAppLabel(ctx, config.Config.Tap.Release.Namespace, map[string]string{kubernetes.AppLabelKey: "hub"})
if err != nil {
log.Error().
Err(err).
Msg("Failed to list hub pods!")
cancel()
return
}
workerPods, err := provider.ListPodsByAppLabel(ctx, config.Config.Tap.Release.Namespace, map[string]string{kubernetes.AppLabelKey: "worker"})
if err != nil {
log.Error().
Err(err).
Msg("Failed to list worker pods!")
cancel()
return
}
fullscreen := true
app := tview.NewApplication()
list := tview.NewList()
var currentCmd *cmd.Cmd
i := 48
for _, pod := range hubPods {
for _, container := range pod.Spec.Containers {
log.Info().Str("pod", pod.Name).Str("container", container.Name).Send()
homeUrl := fmt.Sprintf("%s/debug/pprof/", kubernetes.GetHubUrl())
modal := buildNewModal(
pod,
container,
homeUrl,
app,
list,
fullscreen,
currentCmd,
)
list.AddItem(fmt.Sprintf("pod: %s container: %s", pod.Name, container.Name), pod.Spec.NodeName, rune(i), func() {
app.SetRoot(modal, fullscreen)
})
i++
}
}
for _, pod := range workerPods {
for _, container := range pod.Spec.Containers {
log.Info().Str("pod", pod.Name).Str("container", container.Name).Send()
homeUrl := fmt.Sprintf("%s/pprof/%s/%s/", kubernetes.GetHubUrl(), pod.Status.HostIP, container.Name)
modal := buildNewModal(
pod,
container,
homeUrl,
app,
list,
fullscreen,
currentCmd,
)
list.AddItem(fmt.Sprintf("pod: %s container: %s", pod.Name, container.Name), pod.Spec.NodeName, rune(i), func() {
app.SetRoot(modal, fullscreen)
})
i++
}
}
list.AddItem("Quit", "Press to exit", 'q', func() {
if currentCmd != nil {
err = currentCmd.Stop()
if err != nil {
log.Error().Err(err).Str("name", currentCmd.Name).Msg("Failed to stop process!")
}
}
app.Stop()
})
if err := app.SetRoot(list, fullscreen).EnableMouse(true).Run(); err != nil {
panic(err)
}
}
func buildNewModal(
pod v1.Pod,
container v1.Container,
homeUrl string,
app *tview.Application,
list *tview.List,
fullscreen bool,
currentCmd *cmd.Cmd,
) *tview.Modal {
return tview.NewModal().
SetText(fmt.Sprintf("pod: %s container: %s", pod.Name, container.Name)).
AddButtons([]string{
"Open Debug Home Page",
"Profile: CPU",
"Profile: Memory",
"Profile: Goroutine",
"Cancel",
}).
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
var err error
port := fmt.Sprintf(":%d", config.Config.Tap.Pprof.Port)
view := fmt.Sprintf("http://localhost%s/ui/%s", port, config.Config.Tap.Pprof.View)
switch buttonLabel {
case "Open Debug Home Page":
utils.OpenBrowser(homeUrl)
case "Profile: CPU":
if currentCmd != nil {
err = currentCmd.Stop()
if err != nil {
log.Error().Err(err).Str("name", currentCmd.Name).Msg("Failed to stop process!")
}
}
currentCmd = cmd.NewCmd("go", "tool", "pprof", "-http", port, "-no_browser", fmt.Sprintf("%sprofile", homeUrl))
currentCmd.Start()
utils.OpenBrowser(view)
case "Profile: Memory":
if currentCmd != nil {
err = currentCmd.Stop()
if err != nil {
log.Error().Err(err).Str("name", currentCmd.Name).Msg("Failed to stop process!")
}
}
currentCmd = cmd.NewCmd("go", "tool", "pprof", "-http", port, "-no_browser", fmt.Sprintf("%sheap", homeUrl))
currentCmd.Start()
utils.OpenBrowser(view)
case "Profile: Goroutine":
if currentCmd != nil {
err = currentCmd.Stop()
if err != nil {
log.Error().Err(err).Str("name", currentCmd.Name).Msg("Failed to stop process!")
}
}
currentCmd = cmd.NewCmd("go", "tool", "pprof", "-http", port, "-no_browser", fmt.Sprintf("%sgoroutine", homeUrl))
currentCmd.Start()
utils.OpenBrowser(view)
case "Cancel":
if currentCmd != nil {
err = currentCmd.Stop()
if err != nil {
log.Error().Err(err).Str("name", currentCmd.Name).Msg("Failed to stop process!")
}
}
fallthrough
default:
app.SetRoot(list, fullscreen)
}
})
}

View File

@@ -92,10 +92,10 @@ func runProxy(block bool, noBrowser bool) {
establishedProxy = true
okToOpen("Kubeshark", frontUrl, noBrowser)
}
if establishedProxy && block {
utils.WaitForTermination(ctx, cancel)
}
}
func okToOpen(name string, url string, noBrowser bool) {

View File

@@ -33,7 +33,6 @@ func init() {
rootCmd.PersistentFlags().StringSlice(config.SetCommandName, []string{}, fmt.Sprintf("Override values using --%s", config.SetCommandName))
rootCmd.PersistentFlags().BoolP(config.DebugFlag, "d", false, "Enable debug mode")
rootCmd.PersistentFlags().String(config.ConfigPathFlag, "", fmt.Sprintf("Set the config path, default: %s", config.GetConfigFilePath(nil)))
}
// Execute adds all child commands to the root command and sets flags appropriately.

View File

@@ -2,30 +2,24 @@ package cmd
import (
"context"
"encoding/json"
"errors"
"os"
"os/signal"
"strings"
"sync"
"time"
"fmt"
"net/http"
"github.com/creasty/defaults"
"github.com/fsnotify/fsnotify"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/kubeshark/kubeshark/internal/connect"
"github.com/kubeshark/kubeshark/kubernetes"
"github.com/kubeshark/kubeshark/misc"
"github.com/kubeshark/kubeshark/utils"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
)
var scriptsCmd = &cobra.Command{
Use: "scripts",
Short: "Watch the `scripting.source` and/or `scripting.sources` folders for changes and update the scripts",
Short: "Watch the `scripting.source` directory for changes and update the scripts",
RunE: func(cmd *cobra.Command, args []string) error {
runScripts()
return nil
@@ -46,145 +40,24 @@ func init() {
}
func runScripts() {
if config.Config.Scripting.Source == "" && len(config.Config.Scripting.Sources) == 0 {
log.Error().Msg("Both `scripting.source` and `scripting.sources` fields are empty.")
if config.Config.Scripting.Source == "" {
log.Error().Msg("`scripting.source` field is empty.")
return
}
kubernetesProvider, err := getKubernetesProviderForCli(false, false)
if err != nil {
log.Error().Err(err).Send()
return
hubUrl := kubernetes.GetHubUrl()
response, err := http.Get(fmt.Sprintf("%s/echo", hubUrl))
if err != nil || response.StatusCode != 200 {
log.Info().Msg(fmt.Sprintf(utils.Yellow, "Couldn't connect to Hub. Establishing proxy..."))
runProxy(false, true)
}
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
wg.Add(1)
go func() {
defer wg.Done()
watchConfigMap(ctx, kubernetesProvider)
}()
wg.Add(1)
go func() {
defer wg.Done()
watchScripts(ctx, kubernetesProvider, true)
}()
go func() {
<-signalChan
log.Debug().Msg("Received interrupt, stopping watchers.")
cancel()
}()
wg.Wait()
connector = connect.NewConnector(kubernetes.GetHubUrl(), connect.DefaultRetries, connect.DefaultTimeout)
watchScripts(true)
}
func createScript(provider *kubernetes.Provider, script misc.ConfigMapScript) (index int64, err error) {
const maxRetries = 5
var scripts map[int64]misc.ConfigMapScript
for i := 0; i < maxRetries; i++ {
scripts, err = kubernetes.ConfigGetScripts(provider)
if err != nil {
return
}
script.Active = kubernetes.IsActiveScript(provider, script.Title)
index = 0
if script.Title != "New Script" {
for i, v := range scripts {
if index <= i {
index = i + 1
}
if v.Title == script.Title {
index = int64(i)
}
}
}
scripts[index] = script
log.Info().Str("title", script.Title).Bool("Active", script.Active).Int64("Index", index).Msg("Creating script")
var data []byte
data, err = json.Marshal(scripts)
if err != nil {
return
}
_, err = kubernetes.SetConfig(provider, kubernetes.CONFIG_SCRIPTING_SCRIPTS, string(data))
if err == nil {
return index, nil
}
if k8serrors.IsConflict(err) {
log.Debug().Err(err).Msg("Conflict detected, retrying update...")
time.Sleep(500 * time.Millisecond)
continue
}
return 0, err
}
log.Error().Msg("Max retries reached for creating script due to conflicts.")
return 0, errors.New("max retries reached due to conflicts while creating script")
}
func updateScript(provider *kubernetes.Provider, index int64, script misc.ConfigMapScript) (err error) {
var scripts map[int64]misc.ConfigMapScript
scripts, err = kubernetes.ConfigGetScripts(provider)
if err != nil {
return
}
script.Active = kubernetes.IsActiveScript(provider, script.Title)
scripts[index] = script
var data []byte
data, err = json.Marshal(scripts)
if err != nil {
return
}
_, err = kubernetes.SetConfig(provider, kubernetes.CONFIG_SCRIPTING_SCRIPTS, string(data))
if err != nil {
return
}
return
}
func deleteScript(provider *kubernetes.Provider, index int64) (err error) {
var scripts map[int64]misc.ConfigMapScript
scripts, err = kubernetes.ConfigGetScripts(provider)
if err != nil {
return
}
err = kubernetes.DeleteActiveScriptByTitle(provider, scripts[index].Title)
if err != nil {
return
}
delete(scripts, index)
var data []byte
data, err = json.Marshal(scripts)
if err != nil {
return
}
_, err = kubernetes.SetConfig(provider, kubernetes.CONFIG_SCRIPTING_SCRIPTS, string(data))
if err != nil {
return
}
return
}
func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool) {
func watchScripts(block bool) {
files := make(map[string]int64)
scripts, err := config.Config.Scripting.GetScripts()
@@ -194,10 +67,10 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
}
for _, script := range scripts {
index, err := createScript(provider, script.ConfigMap())
index, err := connector.PostScript(script)
if err != nil {
log.Error().Err(err).Send()
continue
return
}
files[script.Path] = index
@@ -212,37 +85,11 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
defer watcher.Close()
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
go func() {
<-signalChan
log.Debug().Msg("Received interrupt, stopping script watch.")
cancel()
watcher.Close()
}()
if err := watcher.Add(config.Config.Scripting.Source); err != nil {
log.Error().Err(err).Msg("Failed to add scripting source to watcher")
return
}
go func() {
for {
select {
case <-ctx.Done():
log.Debug().Msg("Script watcher exiting gracefully.")
return
// watch for events
case event := <-watcher.Events:
if !strings.HasSuffix(event.Name, "js") {
log.Info().Str("file", event.Name).Msg("Ignoring file")
continue
}
switch event.Op {
case fsnotify.Create:
script, err := misc.ReadScriptFile(event.Name)
@@ -251,7 +98,7 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
continue
}
index, err := createScript(provider, script.ConfigMap())
index, err := connector.PostScript(script)
if err != nil {
log.Error().Err(err).Send()
continue
@@ -267,7 +114,7 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
continue
}
err = updateScript(provider, index, script.ConfigMap())
err = connector.PutScript(script, index)
if err != nil {
log.Error().Err(err).Send()
continue
@@ -275,7 +122,7 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
case fsnotify.Rename:
index := files[event.Name]
err := deleteScript(provider, index)
err := connector.DeleteScript(index)
if err != nil {
log.Error().Err(err).Send()
continue
@@ -285,12 +132,9 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
// pass
}
case err, ok := <-watcher.Errors:
if !ok {
log.Info().Msg("Watcher errors channel closed.")
return
}
log.Error().Err(err).Msg("Watcher error encountered")
// watch for errors
case err := <-watcher.Errors:
log.Error().Err(err).Send()
}
}
}()
@@ -299,85 +143,11 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool
log.Error().Err(err).Send()
}
for _, source := range config.Config.Scripting.Sources {
if err := watcher.Add(source); err != nil {
log.Error().Err(err).Send()
}
}
log.Info().Str("folder", config.Config.Scripting.Source).Interface("folders", config.Config.Scripting.Sources).Msg("Watching scripts against changes:")
log.Info().Str("directory", config.Config.Scripting.Source).Msg("Watching scripts against changes:")
if block {
<-ctx.Done()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
utils.WaitForTermination(ctx, cancel)
}
}
func watchConfigMap(ctx context.Context, provider *kubernetes.Provider) {
clientset := provider.GetClientSet()
configMapName := kubernetes.SELF_RESOURCES_PREFIX + kubernetes.SUFFIX_CONFIG_MAP
for {
select {
case <-ctx.Done():
log.Info().Msg("ConfigMap watcher exiting gracefully.")
return
default:
watcher, err := clientset.CoreV1().ConfigMaps(config.Config.Tap.Release.Namespace).Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=" + configMapName,
})
if err != nil {
log.Warn().Err(err).Msg("ConfigMap not found, retrying in 5 seconds...")
time.Sleep(5 * time.Second)
continue
}
// Create a goroutine to process events
watcherClosed := make(chan struct{})
go func() {
defer close(watcherClosed)
for event := range watcher.ResultChan() {
if event.Type == watch.Added {
log.Info().Msg("ConfigMap created or modified")
runScriptsSync(provider)
} else if event.Type == watch.Deleted {
log.Warn().Msg("ConfigMap deleted, waiting for recreation...")
break
}
}
}()
// Wait for either context cancellation or watcher completion
select {
case <-ctx.Done():
watcher.Stop()
log.Info().Msg("ConfigMap watcher stopping due to context cancellation")
return
case <-watcherClosed:
log.Info().Msg("Watcher closed, restarting...")
}
time.Sleep(5 * time.Second)
}
}
}
func runScriptsSync(provider *kubernetes.Provider) {
files := make(map[string]int64)
scripts, err := config.Config.Scripting.GetScripts()
if err != nil {
log.Error().Err(err).Send()
return
}
for _, script := range scripts {
index, err := createScript(provider, script.ConfigMap())
if err != nil {
log.Error().Err(err).Send()
continue
}
files[script.Path] = index
}
log.Info().Msg("Synchronized scripts with ConfigMap.")
}

View File

@@ -58,8 +58,7 @@ func init() {
tapCmd.Flags().Bool(configStructs.DryRunLabel, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them")
tapCmd.Flags().Bool(configStructs.ServiceMeshLabel, defaultTapConfig.ServiceMesh, "Capture the encrypted traffic if the cluster is configured with a service mesh and with mTLS")
tapCmd.Flags().Bool(configStructs.TlsLabel, defaultTapConfig.Tls, "Capture the traffic that's encrypted with OpenSSL or Go crypto/tls libraries")
tapCmd.Flags().Bool(configStructs.IgnoreTaintedLabel, defaultTapConfig.IgnoreTainted, "Ignore tainted pods while running Worker DaemonSet")
tapCmd.Flags().Bool(configStructs.IngressEnabledLabel, defaultTapConfig.Ingress.Enabled, "Enable Ingress")
tapCmd.Flags().Bool(configStructs.TelemetryEnabledLabel, defaultTapConfig.Telemetry.Enabled, "Enable/disable Telemetry")
tapCmd.Flags().Bool(configStructs.ResourceGuardEnabledLabel, defaultTapConfig.ResourceGuard.Enabled, "Enable/disable resource guard")
tapCmd.Flags().Bool(configStructs.WatchdogEnabled, defaultTapConfig.Watchdog.Enabled, "Enable/disable watchdog")
}

View File

@@ -10,6 +10,7 @@ import (
"sync"
"time"
"github.com/kubeshark/kubeshark/internal/connect"
"github.com/kubeshark/kubeshark/kubernetes/helm"
"github.com/kubeshark/kubeshark/misc"
"github.com/kubeshark/kubeshark/utils"
@@ -31,6 +32,7 @@ type tapState struct {
}
var state tapState
var connector *connect.Connector
type Readiness struct {
Hub bool
@@ -50,6 +52,8 @@ func tap() {
Str("limit", config.Config.Tap.StorageLimit).
Msg(fmt.Sprintf("%s will store the traffic up to a limit (per node). Oldest TCP/UDP streams will be removed once the limit is reached.", misc.Software))
connector = connect.NewConnector(kubernetes.GetHubUrl(), connect.DefaultRetries, connect.DefaultTimeout)
kubernetesProvider, err := getKubernetesProviderForCli(false, false)
if err != nil {
log.Error().Err(err).Send()
@@ -424,13 +428,8 @@ func postFrontStarted(ctx context.Context, kubernetesProvider *kubernetes.Provid
time.Sleep(100 * time.Millisecond)
}
if (config.Config.Scripting.Source != "" || len(config.Config.Scripting.Sources) > 0) && config.Config.Scripting.WatchScripts {
watchScripts(ctx, kubernetesProvider, false)
}
if config.Config.Scripting.Console {
go runConsoleWithoutProxy()
if config.Config.Scripting.Source != "" && config.Config.Scripting.WatchScripts {
watchScripts(false)
}
}

View File

@@ -28,7 +28,6 @@ const (
FieldNameTag = "yaml"
ReadonlyTag = "readonly"
DebugFlag = "debug"
ConfigPathFlag = "config-path"
)
var (
@@ -64,9 +63,6 @@ func InitConfig(cmd *cobra.Command) error {
Config = CreateDefaultConfig()
Config.Tap.Debug = DebugMode
if DebugMode {
Config.LogLevel = "debug"
}
cmdName = cmd.Name()
if utils.Contains([]string{
"clean",
@@ -74,7 +70,6 @@ func InitConfig(cmd *cobra.Command) error {
"pro",
"proxy",
"scripts",
"pprof",
}, cmdName) {
cmdName = "tap"
}
@@ -83,7 +78,7 @@ func InitConfig(cmd *cobra.Command) error {
return err
}
ConfigFilePath = GetConfigFilePath(cmd)
ConfigFilePath = path.Join(misc.GetDotFolderPath(), "config.yaml")
if err := loadConfigFile(&Config, utils.Contains([]string{
"manifests",
"license",
@@ -135,44 +130,21 @@ func WriteConfig(config *ConfigStruct) error {
return nil
}
func GetConfigFilePath(cmd *cobra.Command) string {
defaultConfigPath := path.Join(misc.GetDotFolderPath(), "config.yaml")
func loadConfigFile(config *ConfigStruct, silent bool) error {
cwd, err := os.Getwd()
if err != nil {
return defaultConfigPath
}
if cmd != nil {
configPathOverride, err := cmd.Flags().GetString(ConfigPathFlag)
if err == nil {
if configPathOverride != "" {
resolvedConfigPath, err := filepath.Abs(configPathOverride)
if err != nil {
log.Error().Err(err).Msg("--config-path flag path cannot be resolved")
} else {
return resolvedConfigPath
}
}
} else {
log.Error().Err(err).Msg("--config-path flag parser error")
}
return err
}
cwdConfig := filepath.Join(cwd, fmt.Sprintf("%s.yaml", misc.Program))
reader, err := os.Open(cwdConfig)
if err != nil {
return defaultConfigPath
reader, err = os.Open(ConfigFilePath)
if err != nil {
return err
}
} else {
reader.Close()
return cwdConfig
}
}
func loadConfigFile(config *ConfigStruct, silent bool) error {
reader, err := os.Open(ConfigFilePath)
if err != nil {
return err
ConfigFilePath = cwdConfig
}
defer reader.Close()
@@ -200,14 +172,9 @@ func initFlag(f *pflag.Flag) {
flagPath = append(flagPath, strings.Split(f.Name, "-")...)
flagPathJoined := strings.Join(flagPath, ".")
if strings.HasSuffix(flagPathJoined, ".config.path") {
return
}
sliceValue, isSliceValue := f.Value.(pflag.SliceValue)
if !isSliceValue {
if err := mergeFlagValue(configElemValue, flagPath, flagPathJoined, f.Value.String()); err != nil {
if err := mergeFlagValue(configElemValue, flagPath, strings.Join(flagPath, "."), f.Value.String()); err != nil {
log.Warn().Err(err).Send()
}
return
@@ -220,7 +187,7 @@ func initFlag(f *pflag.Flag) {
return
}
if err := mergeFlagValues(configElemValue, flagPath, flagPathJoined, sliceValue.GetSlice()); err != nil {
if err := mergeFlagValues(configElemValue, flagPath, strings.Join(flagPath, "."), sliceValue.GetSlice()); err != nil {
log.Warn().Err(err).Send()
}
}

View File

@@ -16,89 +16,46 @@ const (
func CreateDefaultConfig() ConfigStruct {
return ConfigStruct{
Tap: configStructs.TapConfig{
NodeSelectorTerms: configStructs.NodeSelectorTermsConfig{
Workers: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: v1.NodeSelectorOpIn,
Values: []string{"linux"},
},
},
},
},
Hub: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: v1.NodeSelectorOpIn,
Values: []string{"linux"},
},
},
},
},
Front: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: v1.NodeSelectorOpIn,
Values: []string{"linux"},
},
},
},
},
Dex: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: v1.NodeSelectorOpIn,
Values: []string{"linux"},
},
NodeSelectorTerms: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: v1.NodeSelectorOpIn,
Values: []string{"linux"},
},
},
},
},
Tolerations: configStructs.TolerationsConfig{
Workers: []v1.Toleration{
{
Effect: v1.TaintEffect("NoExecute"),
Operator: v1.TolerationOpExists,
},
Capabilities: configStructs.CapabilitiesConfig{
NetworkCapture: []string{
// NET_RAW is required to listen the network traffic
"NET_RAW",
// NET_ADMIN is required to listen the network traffic
"NET_ADMIN",
},
},
SecurityContext: configStructs.SecurityContextConfig{
Privileged: true,
// Capabilities used only when running in unprivileged mode
Capabilities: configStructs.CapabilitiesConfig{
NetworkCapture: []string{
// NET_RAW is required to listen the network traffic
"NET_RAW",
// NET_ADMIN is required to listen the network traffic
"NET_ADMIN",
},
ServiceMeshCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// DAC_OVERRIDE is required to read /proc/PID/environ
"DAC_OVERRIDE",
},
EBPFCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// SYS_RESOURCE is required to change rlimits for eBPF
"SYS_RESOURCE",
// IPC_LOCK is required for ebpf perf buffers allocations after some amount of size buffer size:
// https://github.com/kubeshark/tracer/blob/13e24725ba8b98216dd0e553262e6d9c56dce5fa/main.go#L82)
"IPC_LOCK",
},
ServiceMeshCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// DAC_OVERRIDE is required to read /proc/PID/environ
"DAC_OVERRIDE",
},
KernelModule: []string{
// SYS_MODULE is required to install kernel modules
"SYS_MODULE",
},
EBPFCapture: []string{
// SYS_ADMIN is required to read /proc/PID/net/ns + to install eBPF programs (kernel < 5.8)
"SYS_ADMIN",
// SYS_PTRACE is required to set netns to other process + to open libssl.so of other process
"SYS_PTRACE",
// SYS_RESOURCE is required to change rlimits for eBPF
"SYS_RESOURCE",
// IPC_LOCK is required for ebpf perf buffers allocations after some amount of size buffer size:
// https://github.com/kubeshark/tracer/blob/13e24725ba8b98216dd0e553262e6d9c56dce5fa/main.go#L82)
"IPC_LOCK",
},
},
Auth: configStructs.AuthConfig{
@@ -106,14 +63,9 @@ func CreateDefaultConfig() ConfigStruct {
RoleAttribute: "role",
Roles: map[string]configStructs.Role{
"admin": {
Filter: "",
CanDownloadPCAP: true,
CanUseScripting: true,
ScriptingPermissions: configStructs.ScriptingPermissions{
CanSave: true,
CanActivate: true,
CanDelete: true,
},
Filter: "",
CanDownloadPCAP: true,
CanUseScripting: true,
CanUpdateTargetedPods: true,
CanStopTrafficCapturing: true,
ShowAdminConsoleLink: true,
@@ -128,32 +80,10 @@ func CreateDefaultConfig() ConfigStruct {
"icmp",
"kafka",
"redis",
// "sctp",
// "syscall",
"sctp",
"syscall",
// "tcp",
// "udp",
"ws",
// "tlsx",
"ldap",
"radius",
"diameter",
"udp-flow",
"tcp-flow",
},
PortMapping: configStructs.PortMapping{
HTTP: []uint16{80, 443, 8080},
AMQP: []uint16{5671, 5672},
KAFKA: []uint16{9092},
REDIS: []uint16{6379},
LDAP: []uint16{389},
DIAMETER: []uint16{3868},
},
Dashboard: configStructs.DashboardConfig{
CompleteStreamingEnabled: true,
},
Capture: configStructs.CaptureConfig{
Stopped: false,
StopAfter: "5m",
},
},
}
@@ -172,21 +102,16 @@ type ConfigStruct struct {
Tap configStructs.TapConfig `yaml:"tap" json:"tap"`
Logs configStructs.LogsConfig `yaml:"logs" json:"logs"`
Config configStructs.ConfigConfig `yaml:"config,omitempty" json:"config,omitempty"`
PcapDump configStructs.PcapDumpConfig `yaml:"pcapdump" json:"pcapdump"`
Kube KubeConfig `yaml:"kube" json:"kube"`
DumpLogs bool `yaml:"dumpLogs" json:"dumpLogs" default:"false"`
HeadlessMode bool `yaml:"headless" json:"headless" default:"false"`
License string `yaml:"license" json:"license" default:"FN7QGAIBA5GGSY3FNZZWKAP7QAAACAYBARCGC5DBAEFAAAIBKIA77AQAAEAVGAP7QIAAAAAK76AQKAIC76CAAAAA7YAUX74AAH7566ZCMVWWC2LMEI5CE43VOBYG64TUIBVXKYTFNBYS42LPEIWCE5LTMVZESZBCHIRFKMZVPFTFMZT2KVQTGSLZNVLW2MRZON3E23CONNJFCQ2UEIWCEYLDMNSXG42UN5VWK3RCHIRCELBCMVSGS5DJN5XCEORCIVHFIRKSKBJESU2FEIWCE3TPMRSXGIR2GEYDALBCOBXWI4ZCHIYCYITFNZSCEORRG43TCMBYHAYDIMZQGAYCYITJNZUXI2LBNRBWC4DBMNUXI6JCHIYCYITDMFYGCY3JOR4SEORQFQRGC4DQL5UWIIR2EJIDEUDZMZ2E62LQOAZEKY2YLBJHS2LWJZ3WYSTLKVGUQ3JCPUATCATX7NHAP7U5DNNY5QYMLW22ZNBELDV24OYIWGD2J3BD5J27C7RS7XIYSSK2OMNLTBXDURVXYJ22ULZACMICQPHKXFSOOHBEBJABJBCHGJSZCEVY2C7US3FXWDPCWROGVSMCLIGBKLM4L6EPMGBZRA7JG7426LWLKAA="`
License string `yaml:"license" json:"license" default:""`
CloudLicenseEnabled bool `yaml:"cloudLicenseEnabled" json:"cloudLicenseEnabled" default:"true"`
AiAssistantEnabled bool `yaml:"aiAssistantEnabled" json:"aiAssistantEnabled" default:"true"`
DemoModeEnabled bool `yaml:"demoModeEnabled" json:"demoModeEnabled" default:"false"`
SupportChatEnabled bool `yaml:"supportChatEnabled" json:"supportChatEnabled" default:"false"`
BetaEnabled bool `yaml:"betaEnabled" json:"betaEnabled" default:"false"`
SupportChatEnabled bool `yaml:"supportChatEnabled" json:"supportChatEnabled" default:"true"`
InternetConnectivity bool `yaml:"internetConnectivity" json:"internetConnectivity" default:"true"`
Scripting configStructs.ScriptingConfig `yaml:"scripting" json:"scripting"`
Manifests ManifestsConfig `yaml:"manifests,omitempty" json:"manifests,omitempty"`
Timezone string `yaml:"timezone" json:"timezone"`
LogLevel string `yaml:"logLevel" json:"logLevel" default:"warning"`
}
func (config *ConfigStruct) ImagePullPolicy() v1.PullPolicy {

View File

@@ -1,11 +1,9 @@
package configStructs
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/kubeshark/kubeshark/misc"
"github.com/rs/zerolog/log"
@@ -14,79 +12,35 @@ import (
type ScriptingConfig struct {
Env map[string]interface{} `yaml:"env" json:"env" default:"{}"`
Source string `yaml:"source" json:"source" default:""`
Sources []string `yaml:"sources" json:"sources" default:"[]"`
WatchScripts bool `yaml:"watchScripts" json:"watchScripts" default:"true"`
Active []string `yaml:"active" json:"active" default:"[]"`
Console bool `yaml:"console" json:"console" default:"true"`
}
func (config *ScriptingConfig) GetScripts() (scripts []*misc.Script, err error) {
// Check if both Source and Sources are empty
if config.Source == "" && len(config.Sources) == 0 {
return nil, nil
if config.Source == "" {
return
}
var allFiles []struct {
Source string
File fs.DirEntry
var files []fs.DirEntry
files, err = os.ReadDir(config.Source)
if err != nil {
return
}
// Handle single Source directory
if config.Source != "" {
files, err := os.ReadDir(config.Source)
if err != nil {
return nil, fmt.Errorf("failed to read directory %s: %v", config.Source, err)
}
for _, file := range files {
allFiles = append(allFiles, struct {
Source string
File fs.DirEntry
}{Source: config.Source, File: file})
}
}
// Handle multiple Sources directories
if len(config.Sources) > 0 {
for _, source := range config.Sources {
files, err := os.ReadDir(source)
if err != nil {
return nil, fmt.Errorf("failed to read directory %s: %v", source, err)
}
for _, file := range files {
allFiles = append(allFiles, struct {
Source string
File fs.DirEntry
}{Source: source, File: file})
}
}
}
// Iterate over all collected files
for _, f := range allFiles {
if f.File.IsDir() {
for _, f := range files {
if f.IsDir() {
continue
}
// Construct the full path based on the relevant source directory
path := filepath.Join(f.Source, f.File.Name())
if !strings.HasSuffix(f.File.Name(), ".js") { // Use file name suffix for skipping non-JS files
log.Info().Str("path", path).Msg("Skipping non-JS file")
continue
}
// Read the script file
var script *misc.Script
path := filepath.Join(config.Source, f.Name())
script, err = misc.ReadScriptFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read script file %s: %v", path, err)
return
}
// Append the valid script to the scripts slice
scripts = append(scripts, script)
log.Debug().Str("path", path).Msg("Found script:")
}
// Return the collected scripts and nil error if successful
return scripts, nil
return
}

View File

@@ -31,30 +31,14 @@ const (
IgnoreTaintedLabel = "ignoreTainted"
IngressEnabledLabel = "ingress-enabled"
TelemetryEnabledLabel = "telemetry-enabled"
ResourceGuardEnabledLabel = "resource-guard-enabled"
PprofPortLabel = "pprof-port"
PprofViewLabel = "pprof-view"
DebugLabel = "debug"
ContainerPort = 8080
ContainerPortStr = "8080"
PcapDest = "dest"
PcapMaxSize = "maxSize"
PcapMaxTime = "maxTime"
PcapTimeInterval = "timeInterval"
PcapKubeconfig = "kubeconfig"
PcapDumpEnabled = "enabled"
PcapTime = "time"
WatchdogEnabled = "watchdogEnabled"
ContainerPort = 80
ContainerPortStr = "80"
)
type ResourceLimitsHub struct {
CPU string `yaml:"cpu" json:"cpu" default:"0"`
Memory string `yaml:"memory" json:"memory" default:"5Gi"`
}
type ResourceLimitsWorker struct {
CPU string `yaml:"cpu" json:"cpu" default:"0"`
Memory string `yaml:"memory" json:"memory" default:"3Gi"`
type ResourceLimits struct {
CPU string `yaml:"cpu" json:"cpu" default:"750m"`
Memory string `yaml:"memory" json:"memory" default:"1Gi"`
}
type ResourceRequests struct {
@@ -62,18 +46,13 @@ type ResourceRequests struct {
Memory string `yaml:"memory" json:"memory" default:"50Mi"`
}
type ResourceRequirementsHub struct {
Limits ResourceLimitsHub `yaml:"limits" json:"limits"`
Requests ResourceRequests `yaml:"requests" json:"requests"`
}
type ResourceRequirementsWorker struct {
Limits ResourceLimitsHub `yaml:"limits" json:"limits"`
Requests ResourceRequests `yaml:"requests" json:"requests"`
type ResourceRequirements struct {
Limits ResourceLimits `yaml:"limits" json:"limits"`
Requests ResourceRequests `yaml:"requests" json:"requests"`
}
type WorkerConfig struct {
SrvPort uint16 `yaml:"srvPort" json:"srvPort" default:"48999"`
SrvPort uint16 `yaml:"srvPort" json:"srvPort" default:"30001"`
}
type HubConfig struct {
@@ -91,11 +70,6 @@ type ProxyConfig struct {
Host string `yaml:"host" json:"host" default:"127.0.0.1"`
}
type OverrideImageConfig struct {
Worker string `yaml:"worker" json:"worker"`
Hub string `yaml:"hub" json:"hub"`
Front string `yaml:"front" json:"front"`
}
type OverrideTagConfig struct {
Worker string `yaml:"worker" json:"worker"`
Hub string `yaml:"hub" json:"hub"`
@@ -103,71 +77,26 @@ type OverrideTagConfig struct {
}
type DockerConfig struct {
Registry string `yaml:"registry" json:"registry" default:"docker.io/kubeshark"`
Tag string `yaml:"tag" json:"tag" default:""`
TagLocked bool `yaml:"tagLocked" json:"tagLocked" default:"true"`
ImagePullPolicy string `yaml:"imagePullPolicy" json:"imagePullPolicy" default:"Always"`
ImagePullSecrets []string `yaml:"imagePullSecrets" json:"imagePullSecrets"`
OverrideImage OverrideImageConfig `yaml:"overrideImage" json:"overrideImage"`
OverrideTag OverrideTagConfig `yaml:"overrideTag" json:"overrideTag"`
}
type DnsConfig struct {
Nameservers []string `yaml:"nameservers" json:"nameservers" default:"[]"`
Searches []string `yaml:"searches" json:"searches" default:"[]"`
Options []DnsConfigOption `yaml:"options" json:"options" default:"[]"`
}
type DnsConfigOption struct {
Name string `yaml:"name" json:"name"`
Value string `yaml:"value" json:"value"`
Registry string `yaml:"registry" json:"registry" default:"docker.io/kubeshark"`
Tag string `yaml:"tag" json:"tag" default:""`
ImagePullPolicy string `yaml:"imagePullPolicy" json:"imagePullPolicy" default:"Always"`
ImagePullSecrets []string `yaml:"imagePullSecrets" json:"imagePullSecrets"`
OverrideTag OverrideTagConfig `yaml:"overrideTag" json:"overrideTag"`
}
type ResourcesConfig struct {
Hub ResourceRequirementsHub `yaml:"hub" json:"hub"`
Sniffer ResourceRequirementsWorker `yaml:"sniffer" json:"sniffer"`
Tracer ResourceRequirementsWorker `yaml:"tracer" json:"tracer"`
}
type ProbesConfig struct {
Hub ProbeConfig `yaml:"hub" json:"hub"`
Sniffer ProbeConfig `yaml:"sniffer" json:"sniffer"`
}
type NodeSelectorTermsConfig struct {
Hub []v1.NodeSelectorTerm `yaml:"hub" json:"hub" default:"[]"`
Workers []v1.NodeSelectorTerm `yaml:"workers" json:"workers" default:"[]"`
Front []v1.NodeSelectorTerm `yaml:"front" json:"front" default:"[]"`
Dex []v1.NodeSelectorTerm `yaml:"dex" json:"dex" default:"[]"`
}
type TolerationsConfig struct {
Hub []v1.Toleration `yaml:"hub" json:"hub" default:"[]"`
Workers []v1.Toleration `yaml:"workers" json:"workers" default:"[]"`
Front []v1.Toleration `yaml:"front" json:"front" default:"[]"`
}
type ProbeConfig struct {
InitialDelaySeconds int `yaml:"initialDelaySeconds" json:"initialDelaySeconds" default:"5"`
PeriodSeconds int `yaml:"periodSeconds" json:"periodSeconds" default:"5"`
SuccessThreshold int `yaml:"successThreshold" json:"successThreshold" default:"1"`
FailureThreshold int `yaml:"failureThreshold" json:"failureThreshold" default:"3"`
}
type ScriptingPermissions struct {
CanSave bool `yaml:"canSave" json:"canSave" default:"true"`
CanActivate bool `yaml:"canActivate" json:"canActivate" default:"true"`
CanDelete bool `yaml:"canDelete" json:"canDelete" default:"true"`
Hub ResourceRequirements `yaml:"hub" json:"hub"`
Sniffer ResourceRequirements `yaml:"sniffer" json:"sniffer"`
Tracer ResourceRequirements `yaml:"tracer" json:"tracer"`
}
type Role struct {
Filter string `yaml:"filter" json:"filter" default:""`
CanDownloadPCAP bool `yaml:"canDownloadPCAP" json:"canDownloadPCAP" default:"false"`
CanUseScripting bool `yaml:"canUseScripting" json:"canUseScripting" default:"false"`
ScriptingPermissions ScriptingPermissions `yaml:"scriptingPermissions" json:"scriptingPermissions"`
CanUpdateTargetedPods bool `yaml:"canUpdateTargetedPods" json:"canUpdateTargetedPods" default:"false"`
CanStopTrafficCapturing bool `yaml:"canStopTrafficCapturing" json:"canStopTrafficCapturing" default:"false"`
ShowAdminConsoleLink bool `yaml:"showAdminConsoleLink" json:"showAdminConsoleLink" default:"false"`
Filter string `yaml:"filter" json:"filter" default:""`
CanDownloadPCAP bool `yaml:"canDownloadPCAP" json:"canDownloadPCAP" default:"false"`
CanUseScripting bool `yaml:"canUseScripting" json:"canUseScripting" default:"false"`
CanUpdateTargetedPods bool `yaml:"canUpdateTargetedPods" json:"canUpdateTargetedPods" default:"false"`
CanStopTrafficCapturing bool `yaml:"canStopTrafficCapturing" json:"canStopTrafficCapturing" default:"false"`
ShowAdminConsoleLink bool `yaml:"showAdminConsoleLink" json:"showAdminConsoleLink" default:"false"`
}
type SamlConfig struct {
@@ -188,26 +117,12 @@ type IngressConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
ClassName string `yaml:"className" json:"className" default:""`
Host string `yaml:"host" json:"host" default:"ks.svc.cluster.local"`
Path string `yaml:"path" json:"path" default:"/"`
TLS []networking.IngressTLS `yaml:"tls" json:"tls" default:"[]"`
Annotations map[string]string `yaml:"annotations" json:"annotations" default:"{}"`
}
type RoutingConfig struct {
Front FrontRoutingConfig `yaml:"front" json:"front"`
}
type DashboardConfig struct {
StreamingType string `yaml:"streamingType" json:"streamingType" default:"connect-rpc"`
CompleteStreamingEnabled bool `yaml:"completeStreamingEnabled" json:"completeStreamingEnabled" default:"true"`
}
type FrontRoutingConfig struct {
BasePath string `yaml:"basePath" json:"basePath" default:""`
}
type ReleaseConfig struct {
Repo string `yaml:"repo" json:"repo" default:"https://helm.kubehq.com"`
Repo string `yaml:"repo" json:"repo" default:"https://helm.kubeshark.co"`
Name string `yaml:"name" json:"name" default:"kubeshark"`
Namespace string `yaml:"namespace" json:"namespace" default:"default"`
}
@@ -216,167 +131,74 @@ type TelemetryConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"true"`
}
type ResourceGuardConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
}
type SentryConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
Environment string `yaml:"environment" json:"environment" default:"production"`
}
type WatchdogConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
}
type GitopsConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
}
type CapabilitiesConfig struct {
NetworkCapture []string `yaml:"networkCapture" json:"networkCapture" default:"[]"`
ServiceMeshCapture []string `yaml:"serviceMeshCapture" json:"serviceMeshCapture" default:"[]"`
KernelModule []string `yaml:"kernelModule" json:"kernelModule" default:"[]"`
EBPFCapture []string `yaml:"ebpfCapture" json:"ebpfCapture" default:"[]"`
}
type KernelModuleConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
Image string `yaml:"image" json:"image" default:"kubeshark/pf-ring-module:all"`
UnloadOnDestroy bool `yaml:"unloadOnDestroy" json:"unloadOnDestroy" default:"false"`
}
type MetricsConfig struct {
Port uint16 `yaml:"port" json:"port" default:"49100"`
}
type PprofConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
Port uint16 `yaml:"port" json:"port" default:"8000"`
View string `yaml:"view" json:"view" default:"flamegraph"`
}
type MiscConfig struct {
JsonTTL string `yaml:"jsonTTL" json:"jsonTTL" default:"5m"`
PcapTTL string `yaml:"pcapTTL" json:"pcapTTL" default:"0"`
PcapErrorTTL string `yaml:"pcapErrorTTL" json:"pcapErrorTTL" default:"0"`
PcapTTL string `yaml:"pcapTTL" json:"pcapTTL" default:"10s"`
PcapErrorTTL string `yaml:"pcapErrorTTL" json:"pcapErrorTTL" default:"60s"`
TrafficSampleRate int `yaml:"trafficSampleRate" json:"trafficSampleRate" default:"100"`
TcpStreamChannelTimeoutMs int `yaml:"tcpStreamChannelTimeoutMs" json:"tcpStreamChannelTimeoutMs" default:"10000"`
TcpStreamChannelTimeoutShow bool `yaml:"tcpStreamChannelTimeoutShow" json:"tcpStreamChannelTimeoutShow" default:"false"`
ResolutionStrategy string `yaml:"resolutionStrategy" json:"resolutionStrategy" default:"auto"`
Profile bool `yaml:"profile" json:"profile" default:"false"`
DuplicateTimeframe string `yaml:"duplicateTimeframe" json:"duplicateTimeframe" default:"200ms"`
DetectDuplicates bool `yaml:"detectDuplicates" json:"detectDuplicates" default:"false"`
StaleTimeoutSeconds int `yaml:"staleTimeoutSeconds" json:"staleTimeoutSeconds" default:"30"`
}
type PcapDumpConfig struct {
PcapDumpEnabled bool `yaml:"enabled" json:"enabled" default:"false"`
PcapTimeInterval string `yaml:"timeInterval" json:"timeInterval" default:"1m"`
PcapMaxTime string `yaml:"maxTime" json:"maxTime" default:"1h"`
PcapMaxSize string `yaml:"maxSize" json:"maxSize" default:"500MB"`
PcapTime string `yaml:"time" json:"time" default:"time"`
PcapDebug bool `yaml:"debug" json:"debug" default:"false"`
PcapDest string `yaml:"dest" json:"dest" default:""`
}
type PortMapping struct {
HTTP []uint16 `yaml:"http" json:"http"`
AMQP []uint16 `yaml:"amqp" json:"amqp"`
KAFKA []uint16 `yaml:"kafka" json:"kafka"`
REDIS []uint16 `yaml:"redis" json:"redis"`
LDAP []uint16 `yaml:"ldap" json:"ldap"`
DIAMETER []uint16 `yaml:"diameter" json:"diameter"`
}
type SecurityContextConfig struct {
Privileged bool `yaml:"privileged" json:"privileged" default:"true"`
AppArmorProfile AppArmorProfileConfig `yaml:"appArmorProfile" json:"appArmorProfile"`
SeLinuxOptions SeLinuxOptionsConfig `yaml:"seLinuxOptions" json:"seLinuxOptions"`
Capabilities CapabilitiesConfig `yaml:"capabilities" json:"capabilities"`
}
type AppArmorProfileConfig struct {
Type string `yaml:"type" json:"type"`
LocalhostProfile string `yaml:"localhostProfile" json:"localhostProfile"`
}
type SeLinuxOptionsConfig struct {
Level string `yaml:"level" json:"level"`
Role string `yaml:"role" json:"role"`
Type string `yaml:"type" json:"type"`
User string `yaml:"user" json:"user"`
}
type RawCaptureConfig struct {
Enabled bool `yaml:"enabled" json:"enabled" default:"true"`
StorageSize string `yaml:"storageSize" json:"storageSize" default:"1Gi"`
}
type SnapshotsConfig struct {
StorageClass string `yaml:"storageClass" json:"storageClass" default:""`
StorageSize string `yaml:"storageSize" json:"storageSize" default:"20Gi"`
}
type DelayedDissectionConfig struct {
Image string `yaml:"image" json:"image" default:"kubeshark/worker:master"`
CPU string `yaml:"cpu" json:"cpu" default:"1"`
Memory string `yaml:"memory" json:"memory" default:"2Gi"`
}
type CaptureConfig struct {
Stopped bool `yaml:"stopped" json:"stopped" default:"false"`
StopAfter string `yaml:"stopAfter" json:"stopAfter" default:"5m"`
Raw RawCaptureConfig `yaml:"raw" json:"raw"`
DbMaxSize string `yaml:"dbMaxSize" json:"dbMaxSize" default:"500Mi"`
}
type TapConfig struct {
Docker DockerConfig `yaml:"docker" json:"docker"`
Proxy ProxyConfig `yaml:"proxy" json:"proxy"`
PodRegexStr string `yaml:"regex" json:"regex" default:".*"`
Namespaces []string `yaml:"namespaces" json:"namespaces" default:"[]"`
ExcludedNamespaces []string `yaml:"excludedNamespaces" json:"excludedNamespaces" default:"[]"`
BpfOverride string `yaml:"bpfOverride" json:"bpfOverride" default:""`
Capture CaptureConfig `yaml:"capture" json:"capture"`
DelayedDissection DelayedDissectionConfig `yaml:"delayedDissection" json:"delayedDissection"`
Snapshots SnapshotsConfig `yaml:"snapshots" json:"snapshots"`
Release ReleaseConfig `yaml:"release" json:"release"`
PersistentStorage bool `yaml:"persistentStorage" json:"persistentStorage" default:"false"`
PersistentStorageStatic bool `yaml:"persistentStorageStatic" json:"persistentStorageStatic" default:"false"`
PersistentStoragePvcVolumeMode string `yaml:"persistentStoragePvcVolumeMode" json:"persistentStoragePvcVolumeMode" default:"FileSystem"`
EfsFileSytemIdAndPath string `yaml:"efsFileSytemIdAndPath" json:"efsFileSytemIdAndPath" default:""`
Secrets []string `yaml:"secrets" json:"secrets" default:"[]"`
StorageLimit string `yaml:"storageLimit" json:"storageLimit" default:"10Gi"`
StorageClass string `yaml:"storageClass" json:"storageClass" default:"standard"`
DryRun bool `yaml:"dryRun" json:"dryRun" default:"false"`
DnsConfig DnsConfig `yaml:"dns" json:"dns"`
Resources ResourcesConfig `yaml:"resources" json:"resources"`
Probes ProbesConfig `yaml:"probes" json:"probes"`
ServiceMesh bool `yaml:"serviceMesh" json:"serviceMesh" default:"true"`
Tls bool `yaml:"tls" json:"tls" default:"true"`
DisableTlsLog bool `yaml:"disableTlsLog" json:"disableTlsLog" default:"true"`
PacketCapture string `yaml:"packetCapture" json:"packetCapture" default:"best"`
Labels map[string]string `yaml:"labels" json:"labels" default:"{}"`
Annotations map[string]string `yaml:"annotations" json:"annotations" default:"{}"`
NodeSelectorTerms NodeSelectorTermsConfig `yaml:"nodeSelectorTerms" json:"nodeSelectorTerms" default:"{}"`
Tolerations TolerationsConfig `yaml:"tolerations" json:"tolerations" default:"{}"`
Auth AuthConfig `yaml:"auth" json:"auth"`
Ingress IngressConfig `yaml:"ingress" json:"ingress"`
PriorityClass string `yaml:"priorityClass" json:"priorityClass" default:""`
Routing RoutingConfig `yaml:"routing" json:"routing"`
IPv6 bool `yaml:"ipv6" json:"ipv6" default:"true"`
Debug bool `yaml:"debug" json:"debug" default:"false"`
Dashboard DashboardConfig `yaml:"dashboard" json:"dashboard"`
Telemetry TelemetryConfig `yaml:"telemetry" json:"telemetry"`
ResourceGuard ResourceGuardConfig `yaml:"resourceGuard" json:"resourceGuard"`
Watchdog WatchdogConfig `yaml:"watchdog" json:"watchdog"`
Gitops GitopsConfig `yaml:"gitops" json:"gitops"`
Sentry SentryConfig `yaml:"sentry" json:"sentry"`
DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter" default:""`
LiveConfigMapChangesDisabled bool `yaml:"liveConfigMapChangesDisabled" json:"liveConfigMapChangesDisabled" default:"false"`
GlobalFilter string `yaml:"globalFilter" json:"globalFilter" default:""`
EnabledDissectors []string `yaml:"enabledDissectors" json:"enabledDissectors"`
PortMapping PortMapping `yaml:"portMapping" json:"portMapping"`
CustomMacros map[string]string `yaml:"customMacros" json:"customMacros" default:"{\"https\":\"tls and (http or http2)\"}"`
Metrics MetricsConfig `yaml:"metrics" json:"metrics"`
Pprof PprofConfig `yaml:"pprof" json:"pprof"`
Misc MiscConfig `yaml:"misc" json:"misc"`
SecurityContext SecurityContextConfig `yaml:"securityContext" json:"securityContext"`
MountBpf bool `yaml:"mountBpf" json:"mountBpf" default:"true"`
HostNetwork bool `yaml:"hostNetwork" json:"hostNetwork" default:"true"`
Docker DockerConfig `yaml:"docker" json:"docker"`
Proxy ProxyConfig `yaml:"proxy" json:"proxy"`
PodRegexStr string `yaml:"regex" json:"regex" default:".*"`
Namespaces []string `yaml:"namespaces" json:"namespaces" default:"[]"`
ExcludedNamespaces []string `yaml:"excludedNamespaces" json:"excludedNamespaces" default:"[]"`
BpfOverride string `yaml:"bpfOverride" json:"bpfOverride" default:""`
Stopped bool `yaml:"stopped" json:"stopped" default:"true"`
Release ReleaseConfig `yaml:"release" json:"release"`
PersistentStorage bool `yaml:"persistentStorage" json:"persistentStorage" default:"false"`
PersistentStorageStatic bool `yaml:"persistentStorageStatic" json:"persistentStorageStatic" default:"false"`
EfsFileSytemIdAndPath string `yaml:"efsFileSytemIdAndPath" json:"efsFileSytemIdAndPath" default:""`
StorageLimit string `yaml:"storageLimit" json:"storageLimit" default:"500Mi"`
StorageClass string `yaml:"storageClass" json:"storageClass" default:"standard"`
DryRun bool `yaml:"dryRun" json:"dryRun" default:"false"`
Resources ResourcesConfig `yaml:"resources" json:"resources"`
ServiceMesh bool `yaml:"serviceMesh" json:"serviceMesh" default:"true"`
Tls bool `yaml:"tls" json:"tls" default:"true"`
PacketCapture string `yaml:"packetCapture" json:"packetCapture" default:"best"`
IgnoreTainted bool `yaml:"ignoreTainted" json:"ignoreTainted" default:"false"`
Labels map[string]string `yaml:"labels" json:"labels" default:"{}"`
Annotations map[string]string `yaml:"annotations" json:"annotations" default:"{}"`
NodeSelectorTerms []v1.NodeSelectorTerm `yaml:"nodeSelectorTerms" json:"nodeSelectorTerms" default:"[]"`
Auth AuthConfig `yaml:"auth" json:"auth"`
Ingress IngressConfig `yaml:"ingress" json:"ingress"`
IPv6 bool `yaml:"ipv6" json:"ipv6" default:"true"`
Debug bool `yaml:"debug" json:"debug" default:"false"`
KernelModule KernelModuleConfig `yaml:"kernelModule" json:"kernelModule"`
Telemetry TelemetryConfig `yaml:"telemetry" json:"telemetry"`
DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter"`
ScriptingDisabled bool `yaml:"scriptingDisabled" json:"scriptingDisabled" default:"false"`
TargetedPodsUpdateDisabled bool `yaml:"targetedPodsUpdateDisabled" json:"targetedPodsUpdateDisabled" default:"false"`
RecordingDisabled bool `yaml:"recordingDisabled" json:"recordingDisabled" default:"false"`
StopTrafficCapturingDisabled bool `yaml:"stopTrafficCapturingDisabled" json:"stopTrafficCapturingDisabled" default:"false"`
Capabilities CapabilitiesConfig `yaml:"capabilities" json:"capabilities"`
GlobalFilter string `yaml:"globalFilter" json:"globalFilter"`
EnabledDissectors []string `yaml:"enabledDissectors" json:"enabledDissectors"`
Metrics MetricsConfig `yaml:"metrics" json:"metrics"`
Misc MiscConfig `yaml:"misc" json:"misc"`
}
func (config *TapConfig) PodRegex() *regexp.Regexp {

View File

@@ -12,7 +12,7 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
)
// FormatError wraps error with a detailed message that is meant for the user.
// formatError wraps error with a detailed message that is meant for the user.
// While the errors are meant to be displayed, they are not meant to be exported as classes outsite of CLI.
func FormatError(err error) error {
var errorNew error

191
go.mod
View File

@@ -1,143 +1,166 @@
module github.com/kubeshark/kubeshark
go 1.24.0
toolchain go1.24.5
go 1.20
require (
github.com/creasty/defaults v1.5.2
github.com/fsnotify/fsnotify v1.7.0
github.com/go-cmd/cmd v1.4.3
github.com/fsnotify/fsnotify v1.6.0
github.com/gin-gonic/gin v1.9.1
github.com/goccy/go-yaml v1.11.2
github.com/google/go-github/v37 v37.0.0
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/kubeshark/gopacket v1.1.39
github.com/gorilla/websocket v1.4.2
github.com/pkg/errors v0.9.1
github.com/rivo/tview v0.0.0-20240818110301-fd649dbf1223
github.com/robertkrimen/otto v0.2.1
github.com/rs/zerolog v1.28.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/tanqiangyes/grep-go v0.0.0-20220515134556-b36bff9c3d8e
helm.sh/helm/v3 v3.18.4
k8s.io/api v0.33.2
k8s.io/apimachinery v0.33.2
k8s.io/client-go v0.33.2
k8s.io/kubectl v0.33.2
helm.sh/helm/v3 v3.12.0
k8s.io/api v0.28.3
k8s.io/apimachinery v0.28.3
k8s.io/client-go v0.28.3
k8s.io/kubectl v0.28.3
)
require (
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/containerd/containerd v1.7.27 // indirect
github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v20.10.21+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v20.10.24+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.7.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-gorp/gorp/v3 v3.0.5 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/kubeshark/tracerproto v1.0.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lib/pq v1.10.7 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rubenv/sql-migrate v1.8.0 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.9.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.33.2 // indirect
k8s.io/apiserver v0.33.2 // indirect
k8s.io/cli-runtime v0.33.2 // indirect
k8s.io/component-base v0.33.2 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
k8s.io/apiextensions-apiserver v0.27.1 // indirect
k8s.io/apiserver v0.27.1 // indirect
k8s.io/cli-runtime v0.28.3 // indirect
k8s.io/component-base v0.28.3 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
oras.land/oras-go v1.2.2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

1237
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
apiVersion: v2
name: kubeshark
version: "52.11.7"
version: "52.3.75"
description: The API Traffic Analyzer for Kubernetes
home: https://www.kubehq.com
home: https://kubeshark.co
keywords:
- kubeshark
- packet capture
@@ -16,9 +16,9 @@ keywords:
- api
kubeVersion: '>= 1.16.0-0'
maintainers:
- email: info@kubehq.com
- email: info@kubeshark.co
name: Kubeshark
url: https://www.kubehq.com
url: https://kubeshark.co
sources:
- https://github.com/kubeshark/kubeshark/tree/master/helm-chart
type: application

152
helm-chart/PF_RING.md Normal file
View File

@@ -0,0 +1,152 @@
# PF_RING
<!-- TOC -->
- [PF\_RING](#pf_ring)
- [Overview](#overview)
- [Loading PF\_RING module on Kubernetes nodes](#loading-pf_ring-module-on-kubernetes-nodes)
- [Pre-built kernel module exists and external egress allowed](#pre-built-kernel-module-exists-and-external-egress-allowed)
- [Pre-built kernel module doesn't exist or external egress isn't allowed](#pre-built-kernel-module-doesnt-exist-or-external-egress-isnt-allowed)
- [Appendix A: PF\_RING kernel module compilation](#appendix-a-pf_ring-kernel-module-compilation)
- [Automated complilation](#automated-complilation)
- [Manual compilation](#manual-compilation)
<!-- /TOC -->
## Overview
PF_RING™ is an advanced Linux kernel module and user-space framework designed for high-speed packet processing. It offers a uniform API for packet processing applications, enabling efficient handling of large volumes of network data.
For comprehensive information on PF_RING™, please visit the [User's Guide]((https://www.ntop.org/guides/pf_ring) and access detailed [API Documentation](http://www.ntop.org/guides/pf_ring_api/files.html).
## Loading PF_RING module on Kubernetes nodes
PF_RING kernel module loading is performed via of the `worker` component pod.
The target container `tap.kernelModule.image` must contain `pf_ring.ko` file under path `/opt/lib/modules/<kernel version>/pf_ring.ko`.
Kubeshark provides ready to use containers with kernel modules for the most popular kernel versions running in different managed clouds.
Prior to deploying `kubeshark` with PF_RING enabled, it is essential to verify if a PF_RING kernel module is already built for your kernel version.
Kubeshark provides additional CLI tool for this purpose - [pf-ring-compiler](https://github.com/kubeshark/pf-ring-compiler).
Compatibility verification can be done by running:
```bash
pfring-compiler compatibility
```
This command checks for the availability of kernel modules for the kernel versions running across all nodes in the Kubernetes cluster.
Example output for a compatible cluster:
```bash
Node Kernel Version Supported
ip-192-168-77-230.us-west-2.compute.internal 5.10.199-190.747.amzn2.x86_64 true
ip-192-168-34-216.us-west-2.compute.internal 5.10.199-190.747.amzn2.x86_64 true
Cluster is compatible
```
Another option to verify availability of kernel modules is just inspecting available kernel module versions via:
```bash
curl https://api.kubeshark.co/kernel-modules/meta/versions.jso
```
Based on Kubernetes cluster compatibility and external connection capabilities, user has two options:
1. Use Kubeshark provided container `kubeshark/pf-ring-module`
2. Build custom container with required kernel module version.
### Pre-built kernel module exists and external egress allowed
In this case no additional configuration required.
Kubeshark will load PF_RING kernel module from the default `kubeshark/pf-ring-module:all` container.
### Pre-built kernel module doesn't exist or external egress isn't allowed
In this case building custom Docker image is required.
1. Compile PF_RING kernel module for target version
Skip if you have `pf_ring.ko` for the target kernel version.
Otherwise, follow [Appendix A](#appendix-a-pf_ring-kernel-module-compilation) for details.
2. Build container
The same build process Kubeshark has can be reused (follow [pfring-compilier](https://github.com/kubeshark/pf-ring-compiler/tree/main/modules) for details).
3. Configure Helm values
```yaml
tap:
kernelModule:
image: <container from stage 2>
```
## Appendix A: PF_RING kernel module compilation
PF_RING kernel module compilation can be completed automatically or manually.
### Automated complilation
In case your Kubernetes workers run supported Linux distribution, `kubeshark` CLI can be used to build PF_RING module:
```bash
pfring-compiler compile --target <distro>
```
This command requires:
- kubectl to be installed and configured with a proper context
- egress connection to Internet available
This command:
1. Runs Kubernetes job with build container
2. Waits for job to be completed
3. Downloads `pf-ring-<kernel version>.ko` file into the current folder.
4. Cleans up created job.
Currently supported distros:
- Ubuntu
- RHEL 9
- Amazon Linux 2
### Manual compilation
The process description is based on Ubuntu 22.04 distribution.
1. Get terminal access to the node with target kernel version
This can be done either via SSH directly to node or with debug container running on the target node:
```bash
kubectl debug node/<target node> -it --attach=true --image=ubuntu:22.04
```
2. Install build tools and kernel headers
```bash
apt update
apt install -y gcc build-essential make git wget tar gzip
apt install -y linux-headers-$(uname -r)
```
3. Download PF_RING source code
```bash
wget https://github.com/ntop/PF_RING/archive/refs/tags/8.4.0.tar.gz
tar -xf 8.4.0.tar.gz
cd PF_RING-8.4.0/kernel
```
4. Compile the kernel module
```bash
make KERNEL_SRC=/usr/src/linux-headers-$(uname -r)
```
5. Copy `pf_ring.ko` to the local file system.
Use `scp` or `kubectl cp` depending on type of access(SSH or debug pod).

View File

@@ -5,7 +5,7 @@
Add the Helm repo for Kubeshark:
```shell
helm repo add kubeshark https://helm.kubehq.com
helm repo add kubeshark https://helm.kubeshark.co
```
then install Kubeshark:
@@ -59,9 +59,16 @@ kubectl port-forward service/kubeshark-front 8899:80
Visit [localhost:8899](http://localhost:8899)
You can also use `kubeshark proxy` for a more stable port-forward connection.
## Add a License Key
## Increase the Worker's Storage Limit
For example, change from the default 500Mi to 5Gi:
```shell
--set tap.storageLimit=5Gi
```
## Add a License
When it's necessary, you can use:
@@ -69,7 +76,7 @@ When it's necessary, you can use:
--set license=YOUR_LICENSE_GOES_HERE
```
Get your license from Kubeshark's [Admin Console](https://console.kubehq.com/).
Get your license from Kubeshark's [Admin Console](https://console.kubeshark.co/).
## Installing with Ingress (EKS) enabled
@@ -100,147 +107,92 @@ helm install kubeshark kubeshark/kubeshark \
--set tap.ipv6=false
```
## Prometheus Metrics
## Metrics
Please refer to [metrics](./metrics.md) documentation for details.
## Override Tag, Tags, Images
In addition to using a private registry, you can further override the images' tag, specific image tags and specific image names.
Example for overriding image names:
```yaml
docker:
overrideImage:
worker: docker.io/kubeshark/worker:v52.3.87
front: docker.io/kubeshark/front:v52.3.87
hub: docker.io/kubeshark/hub:v52.3.87
```
## Configuration
| Parameter | Description | Default |
|-------------------------------------------|-----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `tap.docker.registry` | Docker registry to pull from | `docker.io/kubeshark` |
| `tap.docker.tag` | Tag of the Docker images | `latest` |
| `tap.docker.tagLocked` | Lock the Docker image tags to prevent automatic upgrades to the latest branch image version. | `true` |
| `tap.docker.tagLocked` | If `false` - use latest minor tag | `true` |
| `tap.docker.imagePullPolicy` | Kubernetes image pull policy | `Always` |
| `tap.docker.imagePullSecrets` | Kubernetes secrets to pull the images | `[]` |
| `tap.docker.overrideImage` | Can be used to directly override image names | `""` |
| `tap.docker.overrideTag` | Can be used to override image tags | `""` |
| `tap.proxy.hub.srvPort` | Hub server port. Change if already occupied. | `8898` |
| `tap.proxy.worker.srvPort` | Worker server port. Change if already occupied.| `48999` |
| `tap.proxy.front.port` | Front service port. Change if already occupied.| `8899` |
| `tap.proxy.host` | Change to 0.0.0.0 top open up to the world. | `127.0.0.1` |
| `tap.regex` | Target (process traffic from) pods that match regex | `.*` |
| `tap.namespaces` | Target pods in namespaces | `[]` |
| `tap.excludedNamespaces` | Exclude pods in namespaces | `[]` |
| `tap.bpfOverride` | When using AF_PACKET as a traffic capture backend, override any existing pod targeting rules and set explicit BPF expression (e.g. `net 0.0.0.0/0`). | `[]` |
| `tap.capture.stopped` | Set to `false` to have traffic processing start automatically. When set to `true`, traffic processing is stopped by default, resulting in almost no resource consumption (e.g. Kubeshark is dormant). This property can be dynamically control via the dashboard. | `false` |
| `tap.capture.stopAfter` | Set to a duration (e.g. `30s`) to have traffic processing stop after no websocket activity between worker and hub. | `30s` |
| `tap.capture.raw.enabled` | Enable raw capture of packets and syscalls to disk for offline analysis | `true` |
| `tap.capture.raw.storageSize` | Maximum storage size for raw capture files (supports K8s quantity format: `1Gi`, `500Mi`, etc.) | `1Gi` |
| `tap.capture.dbMaxSize` | Maximum size for capture database (e.g., `4Gi`, `2000Mi`). When empty, automatically uses 80% of allocated storage (`tap.storageLimit`). | `""` |
| `tap.snapshots.storageClass` | Storage class for snapshots volume. When empty, uses `emptyDir`. When set, creates a PVC with this storage class | `""` |
| `tap.snapshots.storageSize` | Storage size for snapshots volume (supports K8s quantity format: `1Gi`, `500Mi`, etc.) | `10Gi` |
| `tap.release.repo` | URL of the Helm chart repository | `https://helm.kubehq.com` |
| `tap.release.name` | Helm release name | `kubeshark` |
| `tap.release.namespace` | Helm release namespace | `default` |
| `tap.persistentStorage` | Use `persistentVolumeClaim` instead of `emptyDir` | `false` |
| `tap.persistentStorageStatic` | Use static persistent volume provisioning (explicitly defined `PersistentVolume` ) | `false` |
| `tap.persistentStoragePvcVolumeMode` | Set the pvc volume mode (Filesystem\|Block) | `Filesystem` |
| `tap.efsFileSytemIdAndPath` | [EFS file system ID and, optionally, subpath and/or access point](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/access_points/README.md) `<FileSystemId>:<Path>:<AccessPointId>` | "" |
| `tap.storageLimit` | Limit of either the `emptyDir` or `persistentVolumeClaim` | `5Gi` |
| `tap.storageClass` | Storage class of the `PersistentVolumeClaim` | `standard` |
| `tap.dryRun` | Preview of all pods matching the regex, without tapping them | `false` |
| `tap.dnsConfig.nameservers` | Nameservers to use for DNS resolution | `[]` |
| `tap.dnsConfig.searches` | Search domains to use for DNS resolution | `[]` |
| `tap.dnsConfig.options` | DNS options to use for DNS resolution | `[]` |
| `tap.resources.hub.limits.cpu` | CPU limit for hub | `""` (no limit) |
| `tap.resources.hub.limits.memory` | Memory limit for hub | `5Gi` |
| `tap.resources.hub.requests.cpu` | CPU request for hub | `50m` |
| `tap.resources.hub.requests.memory` | Memory request for hub | `50Mi` |
| `tap.resources.sniffer.limits.cpu` | CPU limit for sniffer | `""` (no limit) |
| `tap.resources.sniffer.limits.memory` | Memory limit for sniffer | `3Gi` |
| `tap.resources.sniffer.requests.cpu` | CPU request for sniffer | `50m` |
| `tap.resources.sniffer.requests.memory` | Memory request for sniffer | `50Mi` |
| `tap.resources.tracer.limits.cpu` | CPU limit for tracer | `""` (no limit) |
| `tap.resources.tracer.limits.memory` | Memory limit for tracer | `3Gi` |
| `tap.resources.tracer.requests.cpu` | CPU request for tracer | `50m` |
| `tap.resources.tracer.requests.memory` | Memory request for tracer | `50Mi` |
| `tap.probes.hub.initialDelaySeconds` | Initial delay before probing the hub | `15` |
| `tap.probes.hub.periodSeconds` | Period between probes for the hub | `10` |
| `tap.probes.hub.successThreshold` | Number of successful probes before considering the hub healthy | `1` |
| `tap.probes.hub.failureThreshold` | Number of failed probes before considering the hub unhealthy | `3` |
| `tap.probes.sniffer.initialDelaySeconds` | Initial delay before probing the sniffer | `15` |
| `tap.probes.sniffer.periodSeconds` | Period between probes for the sniffer | `10` |
| `tap.probes.sniffer.successThreshold` | Number of successful probes before considering the sniffer healthy | `1` |
| `tap.probes.sniffer.failureThreshold` | Number of failed probes before considering the sniffer unhealthy | `3` |
| `tap.serviceMesh` | Capture traffic from service meshes like Istio, Linkerd, Consul, etc. | `true` |
| `tap.tls` | Capture the encrypted/TLS traffic from cryptography libraries like OpenSSL | `true` |
| `tap.disableTlsLog` | Suppress logging for TLS/eBPF | `true` |
| `tap.labels` | Kubernetes labels to apply to all Kubeshark resources | `{}` |
| `tap.annotations` | Kubernetes annotations to apply to all Kubeshark resources | `{}` |
| `tap.nodeSelectorTerms.workers` | Node selector terms for workers components | `[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]` |
| `tap.nodeSelectorTerms.hub` | Node selector terms for hub component | `[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]` |
| `tap.nodeSelectorTerms.front` | Node selector terms for front-end component | `[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]` |
| `tap.priorityClass` | Priority class name for Kubeshark components | `""` |
| `tap.tolerations.workers` | Tolerations for workers components | `[ {"operator": "Exists", "effect": "NoExecute"}` |
| `tap.tolerations.hub` | Tolerations for hub component | `[]` |
| `tap.tolerations.front` | Tolerations for front-end component | `[]` |
| `tap.auth.enabled` | Enable authentication | `false` |
| `tap.auth.type` | Authentication type (1 option available: `saml`) | `saml` |
| `tap.auth.approvedEmails` | List of approved email addresses for authentication | `[]` |
| `tap.auth.approvedDomains` | List of approved email domains for authentication | `[]` |
| `tap.auth.saml.idpMetadataUrl` | SAML IDP metadata URL <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509crt` | A self-signed X.509 `.cert` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509key` | A self-signed X.509 `.key` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.roleAttribute` | A SAML attribute name corresponding to user's authorization role <br/>(effective, if `tap.auth.type = saml`) | `role` |
| `tap.auth.saml.roles` | A list of SAML authorization roles and their permissions <br/>(effective, if `tap.auth.type = saml`) | `{"admin":{"canDownloadPCAP":true,"canUpdateTargetedPods":true,"canUseScripting":true, "scriptingPermissions":{"canSave":true, "canActivate":true, "canDelete":true}, "canStopTrafficCapturing":true, "filter":"","showAdminConsoleLink":true}}` |
| `tap.ingress.enabled` | Enable `Ingress` | `false` |
| `tap.ingress.className` | Ingress class name | `""` |
| `tap.ingress.host` | Host of the `Ingress` | `ks.svc.cluster.local` |
| `tap.ingress.tls` | `Ingress` TLS configuration | `[]` |
| `tap.ingress.annotations` | `Ingress` annotations | `{}` |
| `tap.routing.front.basePath` | Set this value to serve `front` under specific base path. Example: `/custompath` (forward slash must be present) | `""` |
| `tap.ipv6` | Enable IPv6 support for the front-end | `true` |
| `tap.debug` | Enable debug mode | `false` |
| `tap.telemetry.enabled` | Enable anonymous usage statistics collection | `true` |
| `tap.resourceGuard.enabled` | Enable resource guard worker process, which watches RAM/disk usage and enables/disables traffic capture based on available resources | `false` |
| `tap.secrets` | List of secrets to be used as source for environment variables (e.g. `kubeshark-license`) | `[]` |
| `tap.sentry.enabled` | Enable sending of error logs to Sentry | `true` (only for qualified users) |
| `tap.sentry.environment` | Sentry environment to label error logs with | `production` |
| `tap.defaultFilter` | Sets the default dashboard KFL filter (e.g. `http`). By default, this value is set to filter out noisy protocols such as DNS, UDP, ICMP and TCP. The user can easily change this, **temporarily**, in the Dashboard. For a permanent change, you should change this value in the `values.yaml` or `config.yaml` file. | `""` |
| `tap.liveConfigMapChangesDisabled` | If set to `true`, all user functionality (scripting, targeting settings, global & default KFL modification, traffic recording, traffic capturing on/off, protocol dissectors) involving dynamic ConfigMap changes from UI will be disabled | `false` |
| `tap.globalFilter` | Prepends to any KFL filter and can be used to limit what is visible in the dashboard. For example, `redact("request.headers.Authorization")` will redact the appropriate field. Another example `!dns` will not show any DNS traffic. | `""` |
| `tap.metrics.port` | Pod port used to expose Prometheus metrics | `49100` |
| `tap.enabledDissectors` | This is an array of strings representing the list of supported protocols. Remove or comment out redundant protocols (e.g., dns).| The default list excludes: `udp` and `tcp` |
| `tap.mountBpf` | BPF filesystem needs to be mounted for eBPF to work properly. This helm value determines whether Kubeshark will attempt to mount the filesystem. This option is not required if filesystem is already mounts. │ `true`|
| `tap.hostNetwork` | Enable host network mode for worker DaemonSet pods. When enabled, worker pods use the host's network namespace for direct network access. | `true` |
| `tap.gitops.enabled` | Enable GitOps functionality. This will allow you to use GitOps to manage your Kubeshark configuration. | `false` |
| `logs.file` | Logs dump path | `""` |
| `pcapdump.enabled` | Enable recording of all traffic captured according to other parameters. Whatever Kubeshark captures, considering pod targeting rules, will be stored in pcap files ready to be viewed by tools | `false` |
| `pcapdump.maxTime` | The time window into the past that will be stored. Older traffic will be discarded. | `2h` |
| `pcapdump.maxSize` | The maximum storage size the PCAP files will consume. Old files that cause to surpass storage consumption will get discarded. | `500MB` |
| `kube.configPath` | Path to the `kubeconfig` file (`$HOME/.kube/config`) | `""` |
| `kube.context` | Kubernetes context to use for the deployment | `""` |
| `dumpLogs` | Enable dumping of logs | `false` |
| `headless` | Enable running in headless mode | `false` |
| `license` | License key for the Pro/Enterprise edition | `""` |
| `scripting.env` | Environment variables for the scripting | `{}` |
| `scripting.source` | Source directory of the scripts | `""` |
| `scripting.watchScripts` | Enable watch mode for the scripts in source directory | `true` |
| `timezone` | IANA time zone applied to time shown in the front-end | `""` (local time zone applies) |
| `supportChatEnabled` | Enable real-time support chat channel based on Intercom | `false` |
| `internetConnectivity` | Turns off API requests that are dependent on Internet connectivity such as `telemetry` and `online-support`. | `true` |
| Parameter | Description | Default |
|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------|
| `tap.docker.registry` | Docker registry to pull from | `docker.io/kubeshark` |
| `tap.docker.tag` | Tag of the Docker images | `latest` |
| `tap.docker.imagePullPolicy` | Kubernetes image pull policy | `Always` |
| `tap.docker.imagePullSecrets` | Kubernetes secrets to pull the images | `[]` |
| `tap.proxy.worker.srvPort` | Worker server port | `30001` |
| `tap.proxy.hub.port` | Hub service port | `8898` |
| `tap.proxy.hub.srvPort` | Hub server port | `8898` |
| `tap.proxy.front.port` | Front-facing service port | `8899` |
| `tap.proxy.host` | Proxy server's IP | `127.0.0.1` |
| `tap.namespaces` | List of namespaces for the traffic capture | `[]` |
| `tap.excludedNamespaces` | List of namespaces to explicitly exclude | `[]` |
| `tap.release.repo` | URL of the Helm chart repository | `https://helm.kubeshark.co` |
| `tap.release.name` | Helm release name | `kubeshark` |
| `tap.release.namespace` | Helm release namespace | `default` |
| `tap.persistentStorage` | Use `persistentVolumeClaim` instead of `emptyDir` | `false` |
| `tap.persistentStorageStatic` | Use static persistent volume provisioning (explicitly defined `PersistentVolume` ) | `false` |
| `tap.efsFileSytemIdAndPath` | [EFS file system ID and, optionally, subpath and/or access point](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/access_points/README.md) `<FileSystemId>:<Path>:<AccessPointId>` | "" |
| `tap.storageLimit` | Limit of either the `emptyDir` or `persistentVolumeClaim` | `500Mi` |
| `tap.storageClass` | Storage class of the `PersistentVolumeClaim` | `standard` |
| `tap.dryRun` | Preview of all pods matching the regex, without tapping them | `false` |
| `tap.pcap` | | `""` |
| `tap.resources.worker.limits.cpu` | CPU limit for worker | `750m` |
| `tap.resources.worker.limits.memory` | Memory limit for worker | `1Gi` |
| `tap.resources.worker.requests.cpu` | CPU request for worker | `50m` |
| `tap.resources.worker.requests.memory` | Memory request for worker | `50Mi` |
| `tap.resources.hub.limits.cpu` | CPU limit for hub | `750m` |
| `tap.resources.hub.limits.memory` | Memory limit for hub | `1Gi` |
| `tap.resources.hub.requests.cpu` | CPU request for hub | `50m` |
| `tap.resources.hub.requests.memory` | Memory request for hub | `50Mi` |
| `tap.serviceMesh` | Capture traffic from service meshes like Istio, Linkerd, Consul, etc. | `true` |
| `tap.tls` | Capture the encrypted/TLS traffic from cryptography libraries like OpenSSL | `true` |
| `tap.ignoreTainted` | Whether to ignore tainted nodes | `false` |
| `tap.labels` | Kubernetes labels to apply to all Kubeshark resources | `{}` |
| `tap.annotations` | Kubernetes annotations to apply to all Kubeshark resources | `{}` |
| `tap.nodeSelectorTerms` | Node selector terms | `[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]` |
| `tap.auth.enabled` | Enable authentication | `false` |
| `tap.auth.type` | Authentication type (1 option available: `saml`) | `saml` |
| `tap.auth.approvedEmails` | List of approved email addresses for authentication | `[]` |
| `tap.auth.approvedDomains` | List of approved email domains for authentication | `[]` |
| `tap.auth.saml.idpMetadataUrl` | SAML IDP metadata URL <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509crt` | A self-signed X.509 `.cert` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509key` | A self-signed X.509 `.key` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.roleAttribute` | A SAML attribute name corresponding to user's authorization role <br/>(effective, if `tap.auth.type = saml`) | `role` |
| `tap.auth.saml.roles` | A list of SAML authorization roles and their permissions <br/>(effective, if `tap.auth.type = saml`) | `{"admin":{"canDownloadPCAP":true,"canUpdateTargetedPods":true,"canUseScripting":true, "canStopTrafficCapturing":true, "filter":"","showAdminConsoleLink":true}}` |
| `tap.ingress.enabled` | Enable `Ingress` | `false` |
| `tap.ingress.className` | Ingress class name | `""` |
| `tap.ingress.host` | Host of the `Ingress` | `ks.svc.cluster.local` |
| `tap.ingress.tls` | `Ingress` TLS configuration | `[]` |
| `tap.ingress.annotations` | `Ingress` annotations | `{}` |
| `tap.ipv6` | Enable IPv6 support for the front-end | `true` |
| `tap.debug` | Enable debug mode | `false` |
| `tap.kernelModule.enabled` | Use PF_RING kernel module([details](PF_RING.md)) | `false` |
| `tap.kernelModule.image` | Container image containing PF_RING kernel module with supported kernel version([details](PF_RING.md)) | "kubeshark/pf-ring-module:all" |
| `tap.kernelModule.unloadOnDestroy` | Create additional container which watches for pod termination and unloads PF_RING kernel module. | `false`|
| `tap.telemetry.enabled` | Enable anonymous usage statistics collection | `true` |
| `tap.defaultFilter` | Sets the default dashboard KFL filter (e.g. `http`) | `""` |
| `tap.globalFilter` | Prepends to any KFL filter and can be used to limit what is visible in the dashboard. For example, `redact("request.headers.Authorization")` will redact the appropriate field. Another example `!dns` will not show any DNS traffic. | `""` |
| `tap.metrics.port` | Pod port used to expose Prometheus metrics | `49100` |
| `tap.stopped` | A flag indicating whether to start Kubeshark with traffic processing stopped resulting in almost no resource consumption (e.g. Kubeshark is dormant). This property can be dynamically control via the dashboard. | `true` |
| `tap.enabledDissectors` | This is an array of strings representing the list of supported protocols. Remove or comment out redundant protocols (e.g., dns).| `["amqp","dns","http","icmp","kafka","redis","sctp","syscall","tcp","ws"]` |
| `logs.file` | Logs dump path | `""` |
| `kube.configPath` | Path to the `kubeconfig` file (`$HOME/.kube/config`) | `""` |
| `kube.context` | Kubernetes context to use for the deployment | `""` |
| `dumpLogs` | Enable dumping of logs | `false` |
| `headless` | Enable running in headless mode | `false` |
| `license` | License key for the Pro/Enterprise edition | `""` |
| `scripting.env` | Environment variables for the scripting | `{}` |
| `scripting.source` | Source directory of the scripts | `""` |
| `scripting.watchScripts` | Enable watch mode for the scripts in source directory | `true` |
| `timezone` | IANA time zone applied to time shown in the front-end | `""` (local time zone applies) |
| `supportChatEnabled` | Enable real-time support chat channel based on Intercom | `true` |
| `internetConnectivity` | Turns off API requests that are dependant on Internet connectivity such as `telemetry` and `online-support`. | `true` |
KernelMapping pairs kernel versions with a
DriverContainer image. Kernel versions can be matched
literally or using a regular expression
# Installing with SAML enabled
## Installing with SAML enabled
### Prerequisites:
@@ -287,7 +239,7 @@ tap:
enabled: true
type: saml
saml:
idpMetadataUrl: "https://ti..th0.com/samlp/metadata/MpWiDCM..qdnDG"
idpMetadataUrl: "https://tiptophelmet.us.auth0.com/samlp/metadata/MpWiDCMMB5ShU1HRnhdb1sHM6VWqdnDG"
x509crt: |
-----BEGIN CERTIFICATE-----
MIIDlTCCAn0CFFRUzMh+dZvp+FvWd4gRaiBVN8EvMA0GCSqGSIb3DQEBCwUAMIGG
@@ -305,239 +257,3 @@ tap:
UaV5sbRtTzYLxpOSQyi8CEFA+A==
-----END PRIVATE KEY-----
```
# Installing with Dex OIDC authentication
[**Click here to see full docs**](https://docs.kubehq.com/en/saml#installing-with-oidc-enabled-dex-idp).
Choose this option, if **you already have a running instance** of Dex in your cluster &
you want to set up Dex OIDC authentication for Kubeshark users.
Kubeshark supports authentication using [Dex - A Federated OpenID Connect Provider](https://dexidp.io/).
Dex is an abstraction layer designed for integrating a wide variety of Identity Providers.
**Requirement:**
Your Dex IdP must have a publicly accessible URL.
### Pre-requisites:
**1. If you configured Ingress for Kubeshark:**
(see section: "Installing with Ingress (EKS) enabled")
OAuth2 callback URL is: <br/>
`https://<kubeshark-ingress-hostname>/api/oauth2/callback`
**2. If you did not configure Ingress for Kubeshark:**
OAuth2 callback URL is: <br/>
`http://0.0.0.0:8899/api/oauth2/callback`
Use chosen OAuth2 callback URL to replace `<your-kubeshark-host>` in Step 3.
**3. Add this static client to your Dex IdP configuration (`config.yaml`):**
```yaml
staticClients:
- id: kubeshark
secret: create your own client password
name: Kubeshark
redirectURIs:
- https://<your-kubeshark-host>/api/oauth2/callback
```
**Final step:**
Add these helm values to set up OIDC authentication powered by your Dex IdP:
```yaml
# values.yaml
tap:
auth:
enabled: true
type: dex
dexOidc:
issuer: <put Dex IdP issuer URL here>
clientId: kubeshark
clientSecret: create your own client password
refreshTokenLifetime: "3960h" # 165 days
oauth2StateParamExpiry: "10m"
bypassSslCaCheck: false
```
---
**Note:**<br/>
Set `tap.auth.dexOidc.bypassSslCaCheck: true`
to allow Kubeshark communication with Dex IdP having an unknown SSL Certificate Authority.
This setting allows you to prevent such SSL CA-related errors:<br/>
`tls: failed to verify certificate: x509: certificate signed by unknown authority`
---
Once you run `helm install kubeshark kubeshark/kubeshark -f ./values.yaml`, Kubeshark will be installed with (Dex) OIDC authentication enabled.
---
# Installing your own Dex IdP along with Kubeshark
Choose this option, if **you need to deploy an instance of Dex IdP** along with Kubeshark &
set up Dex OIDC authentication for Kubeshark users.
Depending on Ingress enabled/disabled, your Dex configuration might differ.
**Requirement:**
Please, configure Ingress using `tap.ingress` for your Kubeshark installation. For example:
```yaml
tap:
ingress:
enabled: true
className: "alb"
host: ks.example.com
tls: []
annotations:
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:7..8:certificate/b...65c
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
```
The following Dex settings will have these values:
| Setting | Value |
|-------------------------------------------------------|----------------------------------------------|
| `tap.auth.dexOidc.issuer` | `https://ks.example.com/dex` |
| `tap.auth.dexConfig.issuer` | `https://ks.example.com/dex` |
| `tap.auth.dexConfig.staticClients -> redirectURIs` | `https://ks.example.com/api/oauth2/callback` |
| `tap.auth.dexConfig.connectors -> config.redirectURI` | `https://ks.example.com/dex/callback` |
---
### Before proceeding with Dex IdP installation:
Please, make sure to prepare the following things first.
1. Choose **[Connectors](https://dexidp.io/docs/connectors/)** to enable in Dex IdP.
- i.e. how many kind of "Log in with ..." options you'd like to offer your users
- You will need to specify connectors in `tap.auth.dexConfig.connectors`
2. Choose type of **[Storage](https://dexidp.io/docs/configuration/storage/)** to use in Dex IdP.
- You will need to specify storage settings in `tap.auth.dexConfig.storage`
- default: `memory`
3. Decide on the OAuth2 `?state=` param expiration time:
- field: `tap.auth.dexOidc.oauth2StateParamExpiry`
- default: `10m` (10 minutes)
- valid time units are `s`, `m`, `h`
4. Decide on the refresh token expiration:
- field 1: `tap.auth.dexOidc.expiry.refreshTokenLifetime`
- field 2: `tap.auth.dexConfig.expiry.refreshTokens.absoluteLifetime`
- default: `3960h` (165 days)
- valid time units are `s`, `m`, `h`
5. Create a unique & secure password to set in these fields:
- field 1: `tap.auth.dexOidc.clientSecret`
- field 2: `tap.auth.dexConfig.staticClients -> secret`
- password must be the same for these 2 fields
6. Discover more possibilities of **[Dex Configuration](https://dexidp.io/docs/configuration/)**
- if you decide to include more configuration options, make sure to add them into `tap.auth.dexConfig`
---
### Once you are ready with all the points described above:
Use these helm `values.yaml` fields to:
- Deploy your own instance of Dex IdP along with Kubeshark
- Enable OIDC authentication for Kubeshark users
Make sure to:
- Replace `<your-ingress-hostname>` with a correct Kubeshark Ingress host (`tap.auth.ingress.host`).
- refer to section **Installing with Ingress (EKS) enabled** to find out how you can configure Ingress host.
Helm `values.yaml`:
```yaml
tap:
auth:
enabled: true
type: dex
dexOidc:
issuer: https://<your-ingress-hostname>/dex
# Client ID/secret must be taken from `tap.auth.dexConfig.staticClients -> id/secret`
clientId: kubeshark
clientSecret: create your own client password
refreshTokenLifetime: "3960h" # 165 days
oauth2StateParamExpiry: "10m"
bypassSslCaCheck: false
dexConfig:
# This field is REQUIRED!
#
# The base path of Dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to Dex. If a
# path is provided, Dex's HTTP service will listen at a non-root URL.
issuer: https://<your-ingress-hostname>/dex
# Expiration configuration for tokens, signing keys, etc.
expiry:
refreshTokens:
validIfNotUsedFor: "2160h" # 90 days
absoluteLifetime: "3960h" # 165 days
# This field is REQUIRED!
#
# The storage configuration determines where Dex stores its state.
# See the documentation (https://dexidp.io/docs/storage/) for further information.
storage:
type: memory
# This field is REQUIRED!
#
# Attention:
# Do not change this field and its values.
# This field is required for internal Kubeshark-to-Dex communication.
#
# HTTP service configuration
web:
http: 0.0.0.0:5556
# This field is REQUIRED!
#
# Attention:
# Do not change this field and its values.
# This field is required for internal Kubeshark-to-Dex communication.
#
# Telemetry configuration
telemetry:
http: 0.0.0.0:5558
# This field is REQUIRED!
#
# Static clients registered in Dex by default.
staticClients:
- id: kubeshark
secret: create your own client password
name: Kubeshark
redirectURIs:
- https://<your-ingress-hostname>/api/oauth2/callback
# Enable the password database.
# It's a "virtual" connector (identity provider) that stores
# login credentials in Dex's store.
enablePasswordDB: true
# Connectors are used to authenticate users against upstream identity providers.
# See the documentation (https://dexidp.io/docs/connectors/) for further information.
#
# Attention:
# When you define a new connector, `config.redirectURI` must be:
# https://<your-ingress-hostname>/dex/callback
#
# Example with Google connector:
# connectors:
# - type: google
# id: google
# name: Google
# config:
# clientID: your Google Cloud Auth app client ID
# clientSecret: your Google Auth app client ID
# redirectURI: https://<your-ingress-hostname>/dex/callback
connectors: []
```

View File

@@ -41,7 +41,6 @@ prometheus:
| --- | --- | --- |
| kubeshark_received_packets_total | Counter | Total number of packets received |
| kubeshark_dropped_packets_total | Counter | Total number of packets dropped |
| kubeshark_dropped_chunks_total | Counter | Total number of dropped packet chunks |
| kubeshark_processed_bytes_total | Counter | Total number of bytes processed |
| kubeshark_tcp_packets_total | Counter | Total number of TCP packets |
| kubeshark_dns_packets_total | Counter | Total number of DNS packets |
@@ -53,4 +52,4 @@ prometheus:
## Ready-to-use Dashboard
You can import a ready-to-use dashboard from [Grafana's Dashboards Portal](https://grafana.com/grafana/dashboards/21332-kubeshark-dashboard-v3-4/).
You can import a ready-to-use dashboard from [Grafana's Dashboards Portal](https://grafana.com/grafana/dashboards/20359-kubeshark-dashboard-v1-0-003/).

View File

@@ -4,15 +4,9 @@ kind: ServiceAccount
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: {{ include "kubeshark.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- if .Values.tap.docker.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.tap.docker.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}

View File

@@ -4,8 +4,8 @@ kind: ClusterRole
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-cluster-role-{{ .Release.Namespace }}
@@ -31,19 +31,8 @@ rules:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- get
- list
- watch
- create
- update
- delete
resourceNames:
- kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
@@ -63,32 +52,11 @@ rules:
resourceNames:
- kubeshark-secret
- kubeshark-config-map
- kubeshark-secret-default
- kubeshark-config-map-default
resources:
- secrets
- configmaps
verbs:
- create
- get
- watch
- list
- update
- patch
- delete
- apiGroups:
- ""
- v1
resources:
- secrets
- configmaps
- pods/log
verbs:
- create
- get
- apiGroups:
- batch
resources:
- jobs
verbs:
- "*"

View File

@@ -4,8 +4,8 @@ kind: ClusterRoleBinding
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-cluster-role-binding-{{ .Release.Namespace }}

View File

@@ -3,10 +3,10 @@ apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: {{ include "kubeshark.name" . }}-hub
@@ -15,52 +15,24 @@ spec:
replicas: 1 # Set the desired number of replicas
selector:
matchLabels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 8 }}
spec:
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: {{ include "kubeshark.serviceAccountName" . }}
{{- if .Values.tap.priorityClass }}
priorityClassName: {{ .Values.tap.priorityClass | quote }}
{{- end }}
containers:
- name: hub
- name: kubeshark-hub
command:
- ./hub
- -port
- "8080"
- -loglevel
- '{{ .Values.logLevel | default "warning" }}'
- -capture-stop-after
- "{{ if hasKey .Values.tap.capture "stopAfter" }}{{ .Values.tap.capture.stopAfter }}{{ else }}5m{{ end }}"
- -snapshot-size-limit
- '{{ .Values.tap.snapshots.storageSize }}'
{{- if .Values.tap.delayedDissection.image }}
- -dissector-image
- '{{ .Values.tap.delayedDissection.image }}'
{{- end }}
{{- if .Values.tap.delayedDissection.cpu }}
- -dissector-cpu
- '{{ .Values.tap.delayedDissection.cpu }}'
{{- end }}
{{- if .Values.tap.delayedDissection.memory }}
- -dissector-memory
- '{{ .Values.tap.delayedDissection.memory }}'
{{- end }}
{{- if .Values.tap.gitops.enabled }}
- -gitops
{{- end }}
{{- if .Values.tap.secrets }}
envFrom:
{{- range .Values.tap.secrets }}
- secretRef:
name: {{ . }}
{{- end }}
{{- if .Values.tap.debug }}
- -debug
{{- end }}
env:
- name: POD_NAME
@@ -71,104 +43,39 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SENTRY_ENABLED
value: '{{ (include "sentry.enabled" .) }}'
- name: SENTRY_ENVIRONMENT
value: '{{ .Values.tap.sentry.environment }}'
- name: KUBESHARK_CLOUD_API_URL
value: 'https://api.kubehq.com'
- name: PROFILING_ENABLED
value: '{{ .Values.tap.pprof.enabled }}'
{{- if .Values.tap.docker.overrideImage.hub }}
image: '{{ .Values.tap.docker.overrideImage.hub }}'
{{- else if .Values.tap.docker.overrideTag.hub }}
value: 'https://api.kubeshark.co'
{{- if .Values.tap.docker.overrideTag.hub }}
image: '{{ .Values.tap.docker.registry }}/hub:{{ .Values.tap.docker.overrideTag.hub }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/hub:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}'
image: '{{ .Values.tap.docker.registry }}/hub:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (printf "v%s" .Chart.Version) }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
readinessProbe:
periodSeconds: {{ .Values.tap.probes.hub.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.hub.failureThreshold }}
successThreshold: {{ .Values.tap.probes.hub.successThreshold }}
initialDelaySeconds: {{ .Values.tap.probes.hub.initialDelaySeconds }}
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 3
tcpSocket:
port: 8080
livenessProbe:
periodSeconds: {{ .Values.tap.probes.hub.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.hub.failureThreshold }}
successThreshold: {{ .Values.tap.probes.hub.successThreshold }}
initialDelaySeconds: {{ .Values.tap.probes.hub.initialDelaySeconds }}
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 3
tcpSocket:
port: 8080
resources:
limits:
{{ if ne (toString .Values.tap.resources.hub.limits.cpu) "0" }}
cpu: {{ .Values.tap.resources.hub.limits.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.hub.limits.memory) "0" }}
memory: {{ .Values.tap.resources.hub.limits.memory }}
{{ end }}
requests:
{{ if ne (toString .Values.tap.resources.hub.requests.cpu) "0" }}
cpu: {{ .Values.tap.resources.hub.requests.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.hub.requests.memory) "0" }}
memory: {{ .Values.tap.resources.hub.requests.memory }}
{{ end }}
volumeMounts:
- name: saml-x509-volume
mountPath: "/etc/saml/x509"
readOnly: true
- name: snapshots-volume
mountPath: "/app/data/snapshots"
{{- if gt (len .Values.tap.nodeSelectorTerms.hub) 0}}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
{{- toYaml .Values.tap.nodeSelectorTerms.hub | nindent 12 }}
{{- end }}
{{- if or .Values.tap.dns.nameservers .Values.tap.dns.searches .Values.tap.dns.options }}
dnsConfig:
{{- if .Values.tap.dns.nameservers }}
nameservers:
{{- range .Values.tap.dns.nameservers }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.searches }}
searches:
{{- range .Values.tap.dns.searches }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.options }}
options:
{{- range .Values.tap.dns.options }}
- name: {{ .name | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.tap.tolerations.hub }}
tolerations:
{{- range .Values.tap.tolerations.hub }}
- key: {{ .key | quote }}
operator: {{ .operator | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- if .effect }}
effect: {{ .effect | quote }}
{{- end }}
{{- if .tolerationSeconds }}
tolerationSeconds: {{ .tolerationSeconds }}
{{- end }}
{{- end }}
{{- end }}
volumes:
- name: saml-x509-volume
projected:
@@ -183,11 +90,3 @@ spec:
items:
- key: AUTH_SAML_X509_KEY
path: kubeshark.key
- name: snapshots-volume
{{- if .Values.tap.snapshots.storageClass }}
persistentVolumeClaim:
claimName: {{ include "kubeshark.name" . }}-snapshots-pvc
{{- else }}
emptyDir:
sizeLimit: {{ .Values.tap.snapshots.storageSize }}
{{- end }}

View File

@@ -3,10 +3,10 @@ apiVersion: v1
kind: Service
metadata:
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-hub
@@ -17,5 +17,5 @@ spec:
port: 80
targetPort: 8080
selector:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
type: ClusterIP

View File

@@ -2,10 +2,10 @@ apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: {{ include "kubeshark.name" . }}-front
@@ -14,63 +14,43 @@ spec:
replicas: 1 # Set the desired number of replicas
selector:
matchLabels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
{{- include "kubeshark.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
{{- include "kubeshark.labels" . | nindent 8 }}
spec:
containers:
- env:
- name: REACT_APP_DEFAULT_FILTER
value: '{{ not (eq .Values.tap.defaultFilter "") | ternary .Values.tap.defaultFilter " " }}'
- name: REACT_APP_AUTH_ENABLED
value: '{{- if or (and .Values.cloudLicenseEnabled (not (empty .Values.license))) (not .Values.internetConnectivity) -}}
{{ (and .Values.tap.auth.enabled (eq .Values.tap.auth.type "dex")) | ternary true false }}
{{- else -}}
{{ .Values.cloudLicenseEnabled | ternary "true" .Values.tap.auth.enabled }}
{{- end }}'
"false"
{{- else -}}
{{ .Values.cloudLicenseEnabled | ternary "true" .Values.tap.auth.enabled }}
{{- end }}'
- name: REACT_APP_AUTH_TYPE
value: '{{- if and .Values.cloudLicenseEnabled (not (eq .Values.tap.auth.type "dex")) -}}
default
{{- else -}}
{{ .Values.tap.auth.type }}
{{- end }}'
- name: REACT_APP_COMPLETE_STREAMING_ENABLED
value: '{{- if and (hasKey .Values.tap "dashboard") (hasKey .Values.tap.dashboard "completeStreamingEnabled") -}}
{{ eq .Values.tap.dashboard.completeStreamingEnabled true | ternary "true" "false" }}
{{- else -}}
true
{{- end }}'
- name: REACT_APP_STREAMING_TYPE
value: '{{ default "" (((.Values).tap).dashboard).streamingType }}'
value: '{{ not (eq .Values.tap.auth.type "") | ternary (.Values.cloudLicenseEnabled | ternary "oidc" .Values.tap.auth.type) " " }}'
- name: REACT_APP_AUTH_SAML_IDP_METADATA_URL
value: '{{ not (eq .Values.tap.auth.saml.idpMetadataUrl "") | ternary .Values.tap.auth.saml.idpMetadataUrl " " }}'
- name: REACT_APP_TIMEZONE
value: '{{ not (eq .Values.timezone "") | ternary .Values.timezone " " }}'
- name: REACT_APP_SCRIPTING_DISABLED
value: '{{- if .Values.tap.liveConfigMapChangesDisabled -}}
{{- if .Values.demoModeEnabled -}}
{{ .Values.demoModeEnabled | ternary false true }}
{{- else -}}
true
{{- end }}
{{- else -}}
false
{{- end }}'
value: '{{ .Values.tap.scriptingDisabled }}'
- name: REACT_APP_TARGETED_PODS_UPDATE_DISABLED
value: '{{ .Values.tap.liveConfigMapChangesDisabled }}'
- name: REACT_APP_PRESET_FILTERS_CHANGING_ENABLED
value: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "false" "true" }}'
value: '{{ .Values.tap.targetedPodsUpdateDisabled }}'
- name: REACT_APP_BPF_OVERRIDE_DISABLED
value: '{{ eq .Values.tap.packetCapture "af_packet" | ternary "false" "true" }}'
value: '{{ eq .Values.tap.packetCapture "ebpf" | ternary "true" "false" }}'
- name: REACT_APP_RECORDING_DISABLED
value: '{{ .Values.tap.liveConfigMapChangesDisabled }}'
value: '{{ .Values.tap.recordingDisabled }}'
- name: REACT_APP_STOP_TRAFFIC_CAPTURING_DISABLED
value: '{{- if and .Values.tap.liveConfigMapChangesDisabled .Values.tap.capture.stopped -}}
value: '{{- if and .Values.tap.stopTrafficCapturingDisabled .Values.tap.stopped -}}
false
{{- else -}}
{{ .Values.tap.liveConfigMapChangesDisabled | ternary "true" "false" }}
{{ .Values.tap.stopTrafficCapturingDisabled | ternary "true" "false" }}
{{- end -}}'
- name: 'REACT_APP_CLOUD_LICENSE_ENABLED'
value: '{{- if or (and .Values.cloudLicenseEnabled (not (empty .Values.license))) (not .Values.internetConnectivity) -}}
@@ -78,26 +58,12 @@ spec:
{{- else -}}
{{ .Values.cloudLicenseEnabled }}
{{- end }}'
- name: 'REACT_APP_AI_ASSISTANT_ENABLED'
value: '{{ .Values.aiAssistantEnabled | ternary "true" "false" }}'
- name: REACT_APP_SUPPORT_CHAT_ENABLED
value: '{{ and .Values.supportChatEnabled .Values.internetConnectivity | ternary "true" "false" }}'
- name: REACT_APP_BETA_ENABLED
value: '{{ default false .Values.betaEnabled | ternary "true" "false" }}'
- name: REACT_APP_DISSECTORS_UPDATING_ENABLED
value: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "false" "true" }}'
- name: REACT_APP_RAW_CAPTURE_ENABLED
value: '{{ .Values.tap.capture.raw.enabled | ternary "true" "false" }}'
- name: REACT_APP_SENTRY_ENABLED
value: '{{ (include "sentry.enabled" .) }}'
- name: REACT_APP_SENTRY_ENVIRONMENT
value: '{{ .Values.tap.sentry.environment }}'
{{- if .Values.tap.docker.overrideImage.front }}
image: '{{ .Values.tap.docker.overrideImage.front }}'
{{- else if .Values.tap.docker.overrideTag.front }}
{{- if .Values.tap.docker.overrideTag.front }}
image: '{{ .Values.tap.docker.registry }}/front:{{ .Values.tap.docker.overrideTag.front }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/front:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}'
image: '{{ .Values.tap.docker.registry }}/front:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (printf "v%s" .Chart.Version) }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: kubeshark-front
@@ -128,59 +94,9 @@ spec:
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
readOnly: true
{{- if gt (len .Values.tap.nodeSelectorTerms.front) 0}}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
{{- toYaml .Values.tap.nodeSelectorTerms.front | nindent 12 }}
{{- end }}
{{- if or .Values.tap.dns.nameservers .Values.tap.dns.searches .Values.tap.dns.options }}
dnsConfig:
{{- if .Values.tap.dns.nameservers }}
nameservers:
{{- range .Values.tap.dns.nameservers }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.searches }}
searches:
{{- range .Values.tap.dns.searches }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.options }}
options:
{{- range .Values.tap.dns.options }}
- name: {{ .name | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.tap.tolerations.front }}
tolerations:
{{- range .Values.tap.tolerations.front }}
- key: {{ .key | quote }}
operator: {{ .operator | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- if .effect }}
effect: {{ .effect | quote }}
{{- end }}
{{- if .tolerationSeconds }}
tolerationSeconds: {{ .tolerationSeconds }}
{{- end }}
{{- end }}
{{- end }}
volumes:
- name: nginx-config
configMap:
name: kubeshark-nginx-config-map
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: {{ include "kubeshark.serviceAccountName" . }}
{{- if .Values.tap.priorityClass }}
priorityClassName: {{ .Values.tap.priorityClass | quote }}
{{- end }}

View File

@@ -4,8 +4,8 @@ kind: Service
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-front
@@ -16,5 +16,5 @@ spec:
port: 80
targetPort: 8080
selector:
app.kubehq.com/app: front
app.kubeshark.co/app: front
type: ClusterIP

View File

@@ -26,14 +26,13 @@ kind: PersistentVolumeClaim
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-persistent-volume-claim
namespace: {{ .Release.Namespace }}
spec:
volumeMode: {{ .Values.tap.persistentStoragePvcVolumeMode }}
accessModes:
- ReadWriteMany
resources:

View File

@@ -1,22 +0,0 @@
---
{{- if .Values.tap.snapshots.storageClass }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: {{ include "kubeshark.name" . }}-snapshots-pvc
namespace: {{ .Release.Namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.tap.snapshots.storageSize }}
storageClassName: {{ .Values.tap.snapshots.storageClass }}
status: {}
{{- end }}

View File

@@ -3,11 +3,11 @@ apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
sidecar.istio.io/inject: "false"
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-worker-daemon-set
@@ -15,59 +15,33 @@ metadata:
spec:
selector:
matchLabels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
{{- include "kubeshark.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
{{- include "kubeshark.labels" . | nindent 8 }}
name: kubeshark-worker-daemon-set
namespace: kubeshark
spec:
{{- if or .Values.tap.mountBpf .Values.tap.persistentStorage}}
{{- if .Values.tap.kernelModule.enabled }}
initContainers:
{{- end }}
{{- if .Values.tap.mountBpf }}
- command:
- /bin/sh
- -c
- mkdir -p /sys/fs/bpf && mount | grep -q '/sys/fs/bpf' || mount -t bpf bpf /sys/fs/bpf
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: mount-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
mountPropagation: Bidirectional
{{- end }}
{{- if .Values.tap.persistentStorage }}
- command:
- /bin/sh
- -c
- mkdir -p /app/data/$NODE_NAME && rm -rf /app/data/$NODE_NAME/tracer_*
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: cleanup-data-dir
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- mountPath: /app/data
name: data
{{- end }}
- name: load-pf-ring
image: {{ .Values.tap.kernelModule.image }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
securityContext:
capabilities:
add:
{{- range .Values.tap.capabilities.kernelModule }}
{{ print "- " . }}
{{- end }}
drop:
- ALL
volumeMounts:
- name: lib-modules
mountPath: /lib/modules
{{- end }}
containers:
- command:
- ./worker
@@ -79,36 +53,27 @@ spec:
- '{{ .Values.tap.metrics.port }}'
- -packet-capture
- '{{ .Values.tap.packetCapture }}'
- -loglevel
- '{{ .Values.logLevel | default "warning" }}'
{{- if not .Values.tap.tls }}
- -disable-tracer
{{- end }}
- -unixsocket
{{- if .Values.tap.serviceMesh }}
- -servicemesh
{{- end }}
- -procfs
- /hostproc
{{- if .Values.tap.resourceGuard.enabled }}
- -enable-resource-guard
{{- if .Values.tap.kernelModule.enabled }}
- -kernel-module
{{- end }}
{{- if .Values.tap.watchdog.enabled }}
- -enable-watchdog
{{- if ne .Values.tap.packetCapture "ebpf" }}
- -disable-ebpf
{{- end }}
- -resolution-strategy
- '{{ .Values.tap.misc.resolutionStrategy }}'
- -staletimeout
- '{{ .Values.tap.misc.staleTimeoutSeconds }}'
- -storage-size
- '{{ .Values.tap.storageLimit }}'
- -capture-db-max-size
- '{{ .Values.tap.capture.dbMaxSize }}'
{{- if .Values.tap.docker.overrideImage.worker }}
image: '{{ .Values.tap.docker.overrideImage.worker }}'
{{- else if .Values.tap.docker.overrideTag.worker }}
{{- if .Values.tap.debug }}
- -debug
{{- end }}
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (printf "v%s" .Chart.Version) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: sniffer
@@ -130,87 +95,41 @@ spec:
- name: TCP_STREAM_CHANNEL_TIMEOUT_SHOW
value: '{{ .Values.tap.misc.tcpStreamChannelTimeoutShow }}'
- name: KUBESHARK_CLOUD_API_URL
value: 'https://api.kubehq.com'
value: 'https://api.kubeshark.co'
- name: PROFILING_ENABLED
value: '{{ .Values.tap.pprof.enabled }}'
- name: SENTRY_ENABLED
value: '{{ (include "sentry.enabled" .) }}'
- name: SENTRY_ENVIRONMENT
value: '{{ .Values.tap.sentry.environment }}'
value: '{{ .Values.tap.misc.profile }}'
resources:
limits:
{{ if ne (toString .Values.tap.resources.sniffer.limits.cpu) "0" }}
cpu: {{ .Values.tap.resources.sniffer.limits.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.sniffer.limits.memory) "0" }}
memory: {{ .Values.tap.resources.sniffer.limits.memory }}
{{ end }}
requests:
{{ if ne (toString .Values.tap.resources.sniffer.requests.cpu) "0" }}
cpu: {{ .Values.tap.resources.sniffer.requests.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.sniffer.requests.memory) "0" }}
memory: {{ .Values.tap.resources.sniffer.requests.memory }}
{{ end }}
securityContext:
privileged: {{ .Values.tap.securityContext.privileged }}
{{- if not .Values.tap.securityContext.privileged }}
{{- $aaProfile := .Values.tap.securityContext.appArmorProfile }}
{{- $selinuxOpts := .Values.tap.securityContext.seLinuxOptions }}
{{- if or (ne $aaProfile.type "") (ne $aaProfile.localhostProfile "") }}
appArmorProfile:
{{- if ne $aaProfile.type "" }}
type: {{ $aaProfile.type }}
{{- end }}
{{- if ne $aaProfile.localhostProfile "" }}
localhostProfile: {{ $aaProfile.localhostProfile }}
{{- end }}
{{- end }}
{{- if or (ne $selinuxOpts.level "") (ne $selinuxOpts.role "") (ne $selinuxOpts.type "") (ne $selinuxOpts.user "") }}
seLinuxOptions:
{{- if ne $selinuxOpts.level "" }}
level: {{ $selinuxOpts.level }}
{{- end }}
{{- if ne $selinuxOpts.role "" }}
role: {{ $selinuxOpts.role }}
{{- end }}
{{- if ne $selinuxOpts.type "" }}
type: {{ $selinuxOpts.type }}
{{- end }}
{{- if ne $selinuxOpts.user "" }}
user: {{ $selinuxOpts.user }}
{{- end }}
{{- end }}
capabilities:
add:
{{- range .Values.tap.securityContext.capabilities.networkCapture }}
{{- range .Values.tap.capabilities.networkCapture }}
{{ print "- " . }}
{{- end }}
{{- if .Values.tap.serviceMesh }}
{{- range .Values.tap.securityContext.capabilities.serviceMeshCapture }}
{{ print "- " . }}
{{- end }}
{{- end }}
{{- if .Values.tap.securityContext.capabilities.ebpfCapture }}
{{- range .Values.tap.securityContext.capabilities.ebpfCapture }}
{{- range .Values.tap.capabilities.serviceMeshCapture }}
{{ print "- " . }}
{{- end }}
{{- end }}
drop:
- ALL
{{- end }}
readinessProbe:
periodSeconds: {{ .Values.tap.probes.sniffer.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.sniffer.failureThreshold }}
successThreshold: {{ .Values.tap.probes.sniffer.successThreshold }}
initialDelaySeconds: {{ .Values.tap.probes.sniffer.initialDelaySeconds }}
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
tcpSocket:
port: {{ .Values.tap.proxy.worker.srvPort }}
livenessProbe:
periodSeconds: {{ .Values.tap.probes.sniffer.periodSeconds }}
failureThreshold: {{ .Values.tap.probes.sniffer.failureThreshold }}
successThreshold: {{ .Values.tap.probes.sniffer.successThreshold }}
initialDelaySeconds: {{ .Values.tap.probes.sniffer.initialDelaySeconds }}
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
tcpSocket:
port: {{ .Values.tap.proxy.worker.srvPort }}
volumeMounts:
@@ -220,27 +139,41 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
{{- if and (eq .Values.tap.kernelModule.enabled true) (eq .Values.tap.kernelModule.unloadOnDestroy true) }}
- name: unload-pf-ring
image: {{ .Values.tap.kernelModule.image }}
command: ["/bin/sh"]
args: ["-c", "trap 'rmmod pf_ring && sleep 3' SIGTERM; while true; do sleep 1; done"]
securityContext:
capabilities:
add:
{{- range .Values.tap.capabilities.kernelModule }}
{{ print "- " . }}
{{- end }}
drop:
- ALL
{{- end }}
{{- if .Values.tap.tls }}
- command:
- ./tracer
- -procfs
- /hostproc
{{- if .Values.tap.disableTlsLog }}
- -disable-tls-log
{{- if ne .Values.tap.packetCapture "ebpf" }}
- -disable-ebpf
{{- end }}
{{- if .Values.tap.pprof.enabled }}
{{- if .Values.tap.debug }}
- -debug
{{- end }}
{{- if .Values.tap.misc.profile }}
- -port
- '{{ add .Values.tap.proxy.worker.srvPort 1 }}'
{{- end }}
- -loglevel
- '{{ .Values.logLevel | default "warning" }}'
{{- if .Values.tap.docker.overrideTag.worker }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ .Values.tap.docker.overrideTag.worker }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
image: '{{ .Values.tap.docker.registry }}/worker:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (printf "v%s" .Chart.Version) }}{{ include "kubeshark.dockerTagDebugVersion" . }}'
{{- end }}
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
name: tracer
@@ -254,66 +187,25 @@ spec:
fieldRef:
fieldPath: metadata.namespace
- name: PROFILING_ENABLED
value: '{{ .Values.tap.pprof.enabled }}'
- name: SENTRY_ENABLED
value: '{{ (include "sentry.enabled" .) }}'
- name: SENTRY_ENVIRONMENT
value: '{{ .Values.tap.sentry.environment }}'
value: '{{ .Values.tap.misc.profile }}'
resources:
limits:
{{ if ne (toString .Values.tap.resources.tracer.limits.cpu) "0" }}
cpu: {{ .Values.tap.resources.tracer.limits.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.tracer.limits.memory) "0" }}
memory: {{ .Values.tap.resources.tracer.limits.memory }}
{{ end }}
requests:
{{ if ne (toString .Values.tap.resources.tracer.requests.cpu) "0" }}
cpu: {{ .Values.tap.resources.tracer.requests.cpu }}
{{ end }}
{{ if ne (toString .Values.tap.resources.tracer.requests.memory) "0" }}
memory: {{ .Values.tap.resources.tracer.requests.memory }}
{{ end }}
securityContext:
privileged: {{ .Values.tap.securityContext.privileged }}
{{- if not .Values.tap.securityContext.privileged }}
{{- $aaProfile := .Values.tap.securityContext.appArmorProfile }}
{{- $selinuxOpts := .Values.tap.securityContext.seLinuxOptions }}
{{- if or (ne $aaProfile.type "") (ne $aaProfile.localhostProfile "") }}
appArmorProfile:
{{- if ne $aaProfile.type "" }}
type: {{ $aaProfile.type }}
{{- end }}
{{- if ne $aaProfile.localhostProfile "" }}
localhostProfile: {{ $aaProfile.localhostProfile }}
{{- end }}
{{- end }}
{{- if or (ne $selinuxOpts.level "") (ne $selinuxOpts.role "") (ne $selinuxOpts.type "") (ne $selinuxOpts.user "") }}
seLinuxOptions:
{{- if ne $selinuxOpts.level "" }}
level: {{ $selinuxOpts.level }}
{{- end }}
{{- if ne $selinuxOpts.role "" }}
role: {{ $selinuxOpts.role }}
{{- end }}
{{- if ne $selinuxOpts.type "" }}
type: {{ $selinuxOpts.type }}
{{- end }}
{{- if ne $selinuxOpts.user "" }}
user: {{ $selinuxOpts.user }}
{{- end }}
{{- end }}
capabilities:
add:
{{- range .Values.tap.securityContext.capabilities.ebpfCapture }}
{{- range .Values.tap.capabilities.ebpfCapture }}
{{ print "- " . }}
{{- end }}
{{- range .Values.tap.securityContext.capabilities.networkCapture }}
{{- range .Values.tap.capabilities.networkCapture }}
{{ print "- " . }}
{{- end }}
drop:
- ALL
{{- end }}
volumeMounts:
- mountPath: /hostproc
name: proc
@@ -321,70 +213,30 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- mountPath: /etc/os-release
name: os-release
readOnly: true
- mountPath: /hostroot
mountPropagation: HostToContainer
name: root
readOnly: true
{{- end }}
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: {{ .Values.tap.hostNetwork }}
hostNetwork: true
serviceAccountName: {{ include "kubeshark.serviceAccountName" . }}
{{- if .Values.tap.priorityClass }}
priorityClassName: {{ .Values.tap.priorityClass | quote }}
{{- end }}
{{- if .Values.tap.tolerations.workers }}
terminationGracePeriodSeconds: 0
tolerations:
{{- range .Values.tap.tolerations.workers }}
- key: {{ .key | quote }}
operator: {{ .operator | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- if .effect }}
effect: {{ .effect | quote }}
{{- end }}
{{- if .tolerationSeconds }}
tolerationSeconds: {{ .tolerationSeconds }}
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Values.tap.nodeSelectorTerms.workers) 0}}
- effect: NoExecute
operator: Exists
{{- if not .Values.tap.ignoreTainted }}
- effect: NoSchedule
operator: Exists
{{- end }}
{{- if gt (len .Values.tap.nodeSelectorTerms) 0}}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
{{- toYaml .Values.tap.nodeSelectorTerms.workers | nindent 12 }}
{{- toYaml .Values.tap.nodeSelectorTerms | nindent 12 }}
{{- end }}
{{- if or .Values.tap.dns.nameservers .Values.tap.dns.searches .Values.tap.dns.options }}
dnsConfig:
{{- if .Values.tap.dns.nameservers }}
nameservers:
{{- range .Values.tap.dns.nameservers }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.searches }}
searches:
{{- range .Values.tap.dns.searches }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.options }}
options:
{{- range .Values.tap.dns.options }}
- name: {{ .name | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
volumes:
- hostPath:
path: /proc
@@ -398,12 +250,7 @@ spec:
- hostPath:
path: /etc/os-release
name: os-release
{{- if .Values.tap.tls }}
- hostPath:
path: /
name: root
- name: data
{{- end }}
{{- if .Values.tap.persistentStorage }}
persistentVolumeClaim:
claimName: kubeshark-persistent-volume-claim

View File

@@ -28,7 +28,7 @@ spec:
name: kubeshark-front
port:
number: 80
path: {{ default "/" (((.Values).tap).ingress).path }}
path: /
pathType: Prefix
{{- if .Values.tap.ingress.tls }}
tls:

View File

@@ -20,8 +20,8 @@ data:
client_header_buffer_size 32k;
large_client_header_buffers 8 64k;
location {{ default "" (((.Values.tap).routing).front).basePath }}/api {
rewrite ^{{ default "" (((.Values.tap).routing).front).basePath }}/api(.*)$ $1 break;
location /api {
rewrite ^/api(.*)$ $1 break;
proxy_pass http://kubeshark-hub;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
@@ -35,8 +35,8 @@ data:
proxy_pass_request_headers on;
}
location {{ default "" (((.Values.tap).routing).front).basePath }}/saml {
rewrite ^{{ default "" (((.Values.tap).routing).front).basePath }}/saml(.*)$ /saml$1 break;
location /saml {
rewrite ^/saml(.*)$ /saml$1 break;
proxy_pass http://kubeshark-hub;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
@@ -46,34 +46,6 @@ data:
proxy_pass_request_headers on;
}
{{- if .Values.tap.auth.dexConfig }}
location /dex {
rewrite ^{{ default "" (((.Values.tap).routing).front).basePath }}/dex(.*)$ /dex$1 break;
proxy_pass http://kubeshark-dex;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_connect_timeout 4s;
proxy_read_timeout 120s;
proxy_send_timeout 12s;
proxy_pass_request_headers on;
}
{{- end }}
{{- if (((.Values.tap).routing).front).basePath }}
location {{ .Values.tap.routing.front.basePath }} {
rewrite ^{{ .Values.tap.routing.front.basePath }}(.*)$ $1 break;
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
add_header Cache-Control no-cache;
}
{{- end }}
location / {
root /usr/share/nginx/html;
index index.html index.htm;

View File

@@ -1,67 +1,40 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ include "kubeshark.configmapName" . }}
name: kubeshark-config-map
namespace: {{ .Release.Namespace }}
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
data:
POD_REGEX: '{{ .Values.tap.regex }}'
NAMESPACES: '{{ gt (len .Values.tap.namespaces) 0 | ternary (join "," .Values.tap.namespaces) "" }}'
EXCLUDED_NAMESPACES: '{{ gt (len .Values.tap.excludedNamespaces) 0 | ternary (join "," .Values.tap.excludedNamespaces) "" }}'
BPF_OVERRIDE: '{{ .Values.tap.bpfOverride }}'
STOPPED: '{{ .Values.tap.capture.stopped | ternary "true" "false" }}'
STOPPED: '{{ .Values.tap.stopped | ternary "true" "false" }}'
SCRIPTING_SCRIPTS: '{}'
SCRIPTING_ACTIVE_SCRIPTS: '{{ gt (len .Values.scripting.active) 0 | ternary (join "," .Values.scripting.active) "" }}'
INGRESS_ENABLED: '{{ .Values.tap.ingress.enabled }}'
INGRESS_HOST: '{{ .Values.tap.ingress.host }}'
PROXY_FRONT_PORT: '{{ .Values.tap.proxy.front.port }}'
AUTH_ENABLED: '{{- if and .Values.cloudLicenseEnabled (not (empty .Values.license)) -}}
{{ and .Values.tap.auth.enabled (eq .Values.tap.auth.type "dex") | ternary true false }}
"false"
{{- else -}}
{{ .Values.cloudLicenseEnabled | ternary "true" (.Values.tap.auth.enabled | ternary "true" "") }}
{{- end }}'
AUTH_TYPE: '{{- if and .Values.cloudLicenseEnabled (not (eq .Values.tap.auth.type "dex")) -}}
default
{{- else -}}
{{ .Values.tap.auth.type }}
{{- end }}'
AUTH_TYPE: '{{ .Values.cloudLicenseEnabled | ternary "oidc" (.Values.tap.auth.type) }}'
AUTH_SAML_IDP_METADATA_URL: '{{ .Values.tap.auth.saml.idpMetadataUrl }}'
AUTH_SAML_ROLE_ATTRIBUTE: '{{ .Values.tap.auth.saml.roleAttribute }}'
AUTH_SAML_ROLES: '{{ .Values.tap.auth.saml.roles | toJson }}'
AUTH_OIDC_ISSUER: '{{ default "not set" (((.Values.tap).auth).dexOidc).issuer }}'
AUTH_OIDC_REFRESH_TOKEN_LIFETIME: '{{ default "3960h" (((.Values.tap).auth).dexOidc).refreshTokenLifetime }}'
AUTH_OIDC_STATE_PARAM_EXPIRY: '{{ default "10m" (((.Values.tap).auth).dexOidc).oauth2StateParamExpiry }}'
AUTH_OIDC_BYPASS_SSL_CA_CHECK: '{{- if and
(hasKey .Values.tap "auth")
(hasKey .Values.tap.auth "dexOidc")
(hasKey .Values.tap.auth.dexOidc "bypassSslCaCheck")
-}}
{{ eq .Values.tap.auth.dexOidc.bypassSslCaCheck true | ternary "true" "false" }}
{{- else -}}
false
{{- end }}'
TELEMETRY_DISABLED: '{{ not .Values.internetConnectivity | ternary "true" (not .Values.tap.telemetry.enabled | ternary "true" "false") }}'
SCRIPTING_DISABLED: '{{- if .Values.tap.liveConfigMapChangesDisabled -}}
{{- if .Values.demoModeEnabled -}}
{{ .Values.demoModeEnabled | ternary false true }}
{{- else -}}
true
{{- end }}
{{- else -}}
false
{{- end }}'
TARGETED_PODS_UPDATE_DISABLED: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "true" "" }}'
PRESET_FILTERS_CHANGING_ENABLED: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "false" "true" }}'
RECORDING_DISABLED: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "true" "" }}'
STOP_TRAFFIC_CAPTURING_DISABLED: '{{- if and .Values.tap.liveConfigMapChangesDisabled .Values.tap.capture.stopped -}}
TELEMETRY_DISABLED: '{{ not .Values.internetConnectivity | ternary "true" (not .Values.tap.telemetry.enabled | ternary "true" "") }}'
SCRIPTING_DISABLED: '{{ .Values.tap.scriptingDisabled | ternary "true" "" }}'
TARGETED_PODS_UPDATE_DISABLED: '{{ .Values.tap.targetedPodsUpdateDisabled | ternary "true" "" }}'
RECORDING_DISABLED: '{{ .Values.tap.recordingDisabled | ternary "true" "" }}'
STOP_TRAFFIC_CAPTURING_DISABLED: '{{- if and .Values.tap.stopTrafficCapturingDisabled .Values.tap.stopped -}}
false
{{- else -}}
{{ .Values.tap.liveConfigMapChangesDisabled | ternary "true" "false" }}
{{ .Values.tap.stopTrafficCapturingDisabled | ternary "true" "false" }}
{{- end }}'
GLOBAL_FILTER: {{ include "kubeshark.escapeDoubleQuotes" .Values.tap.globalFilter | quote }}
DEFAULT_FILTER: {{ include "kubeshark.escapeDoubleQuotes" .Values.tap.defaultFilter | quote }}
TRAFFIC_SAMPLE_RATE: '{{ .Values.tap.misc.trafficSampleRate }}'
JSON_TTL: '{{ .Values.tap.misc.jsonTTL }}'
PCAP_TTL: '{{ .Values.tap.misc.pcapTTL }}'
@@ -72,16 +45,6 @@ data:
{{- else -}}
{{ .Values.cloudLicenseEnabled }}
{{- end }}'
AI_ASSISTANT_ENABLED: '{{ .Values.aiAssistantEnabled | ternary "true" "false" }}'
DUPLICATE_TIMEFRAME: '{{ .Values.tap.misc.duplicateTimeframe }}'
ENABLED_DISSECTORS: '{{ gt (len .Values.tap.enabledDissectors) 0 | ternary (join "," .Values.tap.enabledDissectors) "" }}'
CUSTOM_MACROS: '{{ toJson .Values.tap.customMacros }}'
DISSECTORS_UPDATING_ENABLED: '{{ .Values.tap.liveConfigMapChangesDisabled | ternary "false" "true" }}'
DETECT_DUPLICATES: '{{ .Values.tap.misc.detectDuplicates | ternary "true" "false" }}'
PCAP_DUMP_ENABLE: '{{ .Values.pcapdump.enabled }}'
PCAP_TIME_INTERVAL: '{{ .Values.pcapdump.timeInterval }}'
PCAP_MAX_TIME: '{{ .Values.pcapdump.maxTime }}'
PCAP_MAX_SIZE: '{{ .Values.pcapdump.maxSize }}'
PORT_MAPPING: '{{ toJson .Values.tap.portMapping }}'
RAW_CAPTURE: '{{ .Values.tap.capture.raw.enabled | ternary "true" "false" }}'
RAW_CAPTURE_STORAGE_SIZE: '{{ .Values.tap.capture.raw.storageSize }}'

View File

@@ -1,16 +1,14 @@
kind: Secret
apiVersion: v1
metadata:
name: {{ include "kubeshark.secretName" . }}
name: kubeshark-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
stringData:
LICENSE: '{{ .Values.license }}'
SCRIPTING_ENV: '{{ .Values.scripting.env | toJson }}'
OIDC_CLIENT_ID: '{{ default "not set" (((.Values.tap).auth).dexOidc).clientId }}'
OIDC_CLIENT_SECRET: '{{ default "not set" (((.Values.tap).auth).dexOidc).clientSecret }}'
---
@@ -20,7 +18,7 @@ metadata:
name: kubeshark-saml-x509-crt-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
stringData:
AUTH_SAML_X509_CRT: |
@@ -34,7 +32,7 @@ metadata:
name: kubeshark-saml-x509-key-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
stringData:
AUTH_SAML_X509_KEY: |

View File

@@ -14,7 +14,7 @@ metadata:
namespace: {{ .Release.Namespace }}
spec:
selector:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
{{- include "kubeshark.labels" . | nindent 4 }}
ports:
- name: metrics

View File

@@ -1,23 +0,0 @@
---
kind: Service
apiVersion: v1
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9100'
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-hub-metrics
namespace: {{ .Release.Namespace }}
spec:
selector:
app.kubehq.com/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
ports:
- name: metrics
protocol: TCP
port: 9100
targetPort: 9100

View File

@@ -3,8 +3,8 @@ kind: NetworkPolicy
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-hub-network-policy
@@ -12,7 +12,7 @@ metadata:
spec:
podSelector:
matchLabels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
policyTypes:
- Ingress
- Egress
@@ -20,9 +20,6 @@ spec:
- ports:
- protocol: TCP
port: 8080
- ports:
- protocol: TCP
port: 9100
egress:
- {}
---
@@ -40,7 +37,7 @@ metadata:
spec:
podSelector:
matchLabels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
policyTypes:
- Ingress
- Egress
@@ -53,31 +50,6 @@ spec:
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
annotations:
{{- if .Values.tap.annotations }}
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-dex-network-policy
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app.kubehq.com/app: dex
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: 5556
egress:
- {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
{{- include "kubeshark.labels" . | nindent 4 }}
@@ -90,7 +62,7 @@ metadata:
spec:
podSelector:
matchLabels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
policyTypes:
- Ingress
- Egress

View File

@@ -1,27 +0,0 @@
{{ if .Values.tap.gitops.enabled -}}
apiVersion: batch/v1
kind: Job
metadata:
name: kubeshark-cleanup-job
annotations:
"helm.sh/hook": pre-delete
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
spec:
serviceAccountName: {{ include "kubeshark.serviceAccountName" . }}
{{- if .Values.tap.priorityClass }}
priorityClassName: {{ .Values.tap.priorityClass | quote }}
{{- end }}
restartPolicy: Never
containers:
- name: cleanup
{{- if .Values.tap.docker.overrideImage.hub }}
image: '{{ .Values.tap.docker.overrideImage.hub }}'
{{- else if .Values.tap.docker.overrideTag.hub }}
image: '{{ .Values.tap.docker.registry }}/hub:{{ .Values.tap.docker.overrideTag.hub }}'
{{ else }}
image: '{{ .Values.tap.docker.registry }}/hub:{{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (include "kubeshark.defaultVersion" .) }}'
{{- end }}
command: ["/app/cleanup"]
{{ end -}}

View File

@@ -1,112 +0,0 @@
{{- if .Values.tap.auth.dexConfig }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubehq.com/app: dex
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: {{ include "kubeshark.name" . }}-dex
namespace: {{ .Release.Namespace }}
spec:
replicas: 1 # Set the desired number of replicas
selector:
matchLabels:
app.kubehq.com/app: dex
{{- include "kubeshark.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
app.kubehq.com/app: dex
{{- include "kubeshark.labels" . | nindent 8 }}
spec:
containers:
- name: kubeshark-dex
image: 'dexidp/dex:v2.42.0-alpine'
ports:
- name: http
containerPort: 5556
protocol: TCP
- name: telemetry
containerPort: 5558
protocol: TCP
args:
- dex
- serve
- /etc/dex/dex-config.yaml
imagePullPolicy: {{ .Values.tap.docker.imagePullPolicy }}
volumeMounts:
- name: dex-secret-conf-volume
mountPath: /etc/dex/dex-config.yaml
subPath: dex-config.yaml
readOnly: true
livenessProbe:
httpGet:
path: /healthz/live
port: 5558
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 3
readinessProbe:
httpGet:
path: /healthz/ready
port: 5558
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 3
timeoutSeconds: 1
resources:
limits:
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
{{- if gt (len .Values.tap.nodeSelectorTerms.dex) 0}}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
{{- toYaml .Values.tap.nodeSelectorTerms.dex | nindent 12 }}
{{- end }}
{{- if or .Values.tap.dns.nameservers .Values.tap.dns.searches .Values.tap.dns.options }}
dnsConfig:
{{- if .Values.tap.dns.nameservers }}
nameservers:
{{- range .Values.tap.dns.nameservers }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.searches }}
searches:
{{- range .Values.tap.dns.searches }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .Values.tap.dns.options }}
options:
{{- range .Values.tap.dns.options }}
- name: {{ .name | quote }}
{{- if .value }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
volumes:
- name: dex-secret-conf-volume
secret:
secretName: kubeshark-dex-conf-secret
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: {{ include "kubeshark.serviceAccountName" . }}
{{- if .Values.tap.priorityClass }}
priorityClassName: {{ .Values.tap.priorityClass | quote }}
{{- end }}
{{- end }}

View File

@@ -1,25 +0,0 @@
{{- if .Values.tap.auth.dexConfig }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubehq.com/app: dex
{{- include "kubeshark.labels" . | nindent 4 }}
{{- if .Values.tap.annotations }}
annotations:
{{- toYaml .Values.tap.annotations | nindent 4 }}
{{- end }}
name: kubeshark-dex
namespace: {{ .Release.Namespace }}
spec:
ports:
- name: kubeshark-dex
port: 80
targetPort: 5556
selector:
app.kubehq.com/app: dex
type: ClusterIP
{{- end }}

View File

@@ -1,14 +0,0 @@
{{- if .Values.tap.auth.dexConfig }}
kind: Secret
apiVersion: v1
metadata:
name: kubeshark-dex-conf-secret
namespace: {{ .Release.Namespace }}
labels:
app.kubehq.com/app: hub
{{- include "kubeshark.labels" . | nindent 4 }}
data:
dex-config.yaml: {{ .Values.tap.auth.dexConfig | toYaml | b64enc | quote }}
{{- end }}

View File

@@ -2,39 +2,29 @@ Thank you for installing {{ title .Chart.Name }}.
Registry: {{ .Values.tap.docker.registry }}
Tag: {{ not (eq .Values.tap.docker.tag "") | ternary .Values.tap.docker.tag (printf "v%s" .Chart.Version) }}
{{- if .Values.tap.docker.overrideTag.worker }}
Overridden worker tag: {{ .Values.tap.docker.overrideTag.worker }}
{{- end }}
{{ end }}
{{- if .Values.tap.docker.overrideTag.hub }}
Overridden hub tag: {{ .Values.tap.docker.overrideTag.hub }}
{{- end }}
{{ end }}
{{- if .Values.tap.docker.overrideTag.front }}
Overridden front tag: {{ .Values.tap.docker.overrideTag.front }}
{{- end }}
{{- if .Values.tap.docker.overrideImage.worker }}
Overridden worker image: {{ .Values.tap.docker.overrideImage.worker }}
{{- end }}
{{- if .Values.tap.docker.overrideImage.hub }}
Overridden hub image: {{ .Values.tap.docker.overrideImage.hub }}
{{- end }}
{{- if .Values.tap.docker.overrideImage.front }}
Overridden front image: {{ .Values.tap.docker.overrideImage.front }}
{{- end }}
{{ end }}
Your deployment has been successful. The release is named `{{ .Release.Name }}` and it has been deployed in the `{{ .Release.Namespace }}` namespace.
Notices:
{{- if .Values.supportChatEnabled}}
- Support chat using Intercom is enabled. It can be disabled using `--set supportChatEnabled=false`
{{- end }}
{{- if eq .Values.license ""}}
- No license key was detected. You can either log-in/sign-up through the dashboard, or download the license key from https://console.kubehq.com/ and add it as 'license: <license>' in helm values or as `--set license=<license>` or as `LICENSE` via mounted secret (`tap.secrets`).
{{- end }}
{{- if .Values.tap.telemetry.enabled }}
Notice: Telemetry is enabled. Kubeshark will collect anonymous usage statistics.
{{ end }}
{{ if .Values.tap.ingress.enabled }}
{{- if .Values.tap.ingress.enabled }}
You can now access the application through the following URL:
http{{ if .Values.tap.ingress.tls }}s{{ end }}://{{ .Values.tap.ingress.host }}{{ default "" (((.Values.tap).routing).front).basePath }}/
http{{ if .Values.tap.ingress.tls }}s{{ end }}://{{ .Values.tap.ingress.host }}
{{- else }}
To access the application, follow these steps:
@@ -42,9 +32,8 @@ To access the application, follow these steps:
1. Perform port forwarding with the following commands:
kubectl port-forward -n {{ .Release.Namespace }} service/kubeshark-front 8899:80
you could also run: `kubeshark proxy` (which simply manages the port-forward connection)
2. Once port forwarding is done, you can access the application by visiting the following URL in your web browser:
http://127.0.0.1:8899{{ default "" (((.Values.tap).routing).front).basePath }}/
http://0.0.0.0:8899
{{- end }}
{{ end }}

View File

@@ -49,18 +49,6 @@ Create the name of the service account to use
{{- printf "%s-service-account" .Release.Name }}
{{- end }}
{{/*
Set configmap and secret names based on gitops.enabled
*/}}
{{- define "kubeshark.configmapName" -}}
kubeshark-config-map{{ if .Values.tap.gitops.enabled }}-default{{ end }}
{{- end -}}
{{- define "kubeshark.secretName" -}}
kubeshark-secret{{ if .Values.tap.gitops.enabled }}-default{{ end }}
{{- end -}}
{{/*
Escape double quotes in a string
*/}}
@@ -72,41 +60,5 @@ Escape double quotes in a string
Define debug docker tag suffix
*/}}
{{- define "kubeshark.dockerTagDebugVersion" -}}
{{- .Values.tap.pprof.enabled | ternary "-debug" "" }}
{{- .Values.tap.misc.profile | ternary "-debug" "" }}
{{- end -}}
{{/*
Create docker tag default version
*/}}
{{- define "kubeshark.defaultVersion" -}}
{{- $defaultVersion := (printf "v%s" .Chart.Version) -}}
{{- if .Values.tap.docker.tagLocked }}
{{- $defaultVersion = regexReplaceAll "^([^.]+\\.[^.]+).*" $defaultVersion "$1" -}}
{{- end }}
{{- $defaultVersion }}
{{- end -}}
{{/*
Set sentry based on internet connectivity and telemetry
*/}}
{{- define "sentry.enabled" -}}
{{- $sentryEnabledVal := .Values.tap.sentry.enabled -}}
{{- if not .Values.internetConnectivity -}}
{{- $sentryEnabledVal = false -}}
{{- else if not .Values.tap.telemetry.enabled -}}
{{- $sentryEnabledVal = false -}}
{{- end -}}
{{- $sentryEnabledVal -}}
{{- end -}}
{{/*
Dex IdP: retrieve a secret for static client with a specific ID
*/}}
{{- define "getDexKubesharkStaticClientSecret" -}}
{{- $clientId := .clientId -}}
{{- range .clients }}
{{- if eq .id $clientId }}
{{- .secret }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -2,20 +2,15 @@ tap:
docker:
registry: docker.io/kubeshark
tag: ""
tagLocked: true
imagePullPolicy: Always
imagePullSecrets: []
overrideImage:
worker: ""
hub: ""
front: ""
overrideTag:
worker: ""
hub: ""
front: ""
proxy:
worker:
srvPort: 48999
srvPort: 30001
hub:
srvPort: 8898
front:
@@ -25,106 +20,51 @@ tap:
namespaces: []
excludedNamespaces: []
bpfOverride: ""
capture:
stopped: false
stopAfter: 5m
raw:
enabled: true
storageSize: 1Gi
dbMaxSize: 500Mi
delayedDissection:
image: kubeshark/worker:master
cpu: "1"
memory: 2Gi
snapshots:
storageClass: ""
storageSize: 20Gi
stopped: true
release:
repo: https://helm.kubehq.com
repo: https://helm.kubeshark.co
name: kubeshark
namespace: default
persistentStorage: false
persistentStorageStatic: false
persistentStoragePvcVolumeMode: FileSystem
efsFileSytemIdAndPath: ""
secrets: []
storageLimit: 10Gi
storageLimit: 500Mi
storageClass: standard
dryRun: false
dns:
nameservers: []
searches: []
options: []
resources:
hub:
limits:
cpu: "0"
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
sniffer:
limits:
cpu: "0"
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
tracer:
limits:
cpu: "0"
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
probes:
hub:
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
sniffer:
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
serviceMesh: true
tls: true
disableTlsLog: true
packetCapture: best
ignoreTainted: false
labels: {}
annotations: {}
nodeSelectorTerms:
hub:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
workers:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
front:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
dex:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
tolerations:
hub: []
workers:
- operator: Exists
effect: NoExecute
front: []
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
auth:
enabled: false
type: saml
@@ -138,10 +78,6 @@ tap:
filter: ""
canDownloadPCAP: true
canUseScripting: true
scriptingPermissions:
canSave: true
canActivate: true
canDelete: true
canUpdateTargetedPods: true
canStopTrafficCapturing: true
showAdminConsoleLink: true
@@ -149,31 +85,36 @@ tap:
enabled: false
className: ""
host: ks.svc.cluster.local
path: /
tls: []
annotations: {}
priorityClass: ""
routing:
front:
basePath: ""
ipv6: true
debug: false
dashboard:
streamingType: connect-rpc
completeStreamingEnabled: true
kernelModule:
enabled: false
image: kubeshark/pf-ring-module:all
unloadOnDestroy: false
telemetry:
enabled: true
resourceGuard:
enabled: false
watchdog:
enabled: false
gitops:
enabled: false
sentry:
enabled: false
environment: production
defaultFilter: ""
liveConfigMapChangesDisabled: false
scriptingDisabled: false
targetedPodsUpdateDisabled: false
recordingDisabled: false
stopTrafficCapturingDisabled: false
capabilities:
networkCapture:
- NET_RAW
- NET_ADMIN
serviceMeshCapture:
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
kernelModule:
- SYS_MODULE
ebpfCapture:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
globalFilter: ""
enabledDissectors:
- amqp
@@ -182,101 +123,35 @@ tap:
- icmp
- kafka
- redis
- sctp
- syscall
- ws
- ldap
- radius
- diameter
- udp-flow
- tcp-flow
portMapping:
http:
- 80
- 443
- 8080
amqp:
- 5671
- 5672
kafka:
- 9092
redis:
- 6379
ldap:
- 389
diameter:
- 3868
customMacros:
https: tls and (http or http2)
metrics:
port: 49100
pprof:
enabled: false
port: 8000
view: flamegraph
misc:
jsonTTL: 5m
pcapTTL: "0"
pcapErrorTTL: "0"
pcapTTL: 10s
pcapErrorTTL: 60s
trafficSampleRate: 100
tcpStreamChannelTimeoutMs: 10000
tcpStreamChannelTimeoutShow: false
resolutionStrategy: auto
profile: false
duplicateTimeframe: 200ms
detectDuplicates: false
staleTimeoutSeconds: 30
securityContext:
privileged: true
appArmorProfile:
type: ""
localhostProfile: ""
seLinuxOptions:
level: ""
role: ""
type: ""
user: ""
capabilities:
networkCapture:
- NET_RAW
- NET_ADMIN
serviceMeshCapture:
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
ebpfCapture:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
mountBpf: true
hostNetwork: true
logs:
file: ""
grep: ""
pcapdump:
enabled: false
timeInterval: 1m
maxTime: 1h
maxSize: 500MB
time: time
debug: false
dest: ""
kube:
configPath: ""
context: ""
dumpLogs: false
headless: false
license: FN7QGAIBA5GGSY3FNZZWKAP7QAAACAYBARCGC5DBAEFAAAIBKIA77AQAAEAVGAP7QIAAAAAK76AQKAIC76CAAAAA7YAUX74AAH7566ZCMVWWC2LMEI5CE43VOBYG64TUIBVXKYTFNBYS42LPEIWCE5LTMVZESZBCHIRFKMZVPFTFMZT2KVQTGSLZNVLW2MRZON3E23CONNJFCQ2UEIWCEYLDMNSXG42UN5VWK3RCHIRCELBCMVSGS5DJN5XCEORCIVHFIRKSKBJESU2FEIWCE3TPMRSXGIR2GEYDALBCOBXWI4ZCHIYCYITFNZSCEORRG43TCMBYHAYDIMZQGAYCYITJNZUXI2LBNRBWC4DBMNUXI6JCHIYCYITDMFYGCY3JOR4SEORQFQRGC4DQL5UWIIR2EJIDEUDZMZ2E62LQOAZEKY2YLBJHS2LWJZ3WYSTLKVGUQ3JCPUATCATX7NHAP7U5DNNY5QYMLW22ZNBELDV24OYIWGD2J3BD5J27C7RS7XIYSSK2OMNLTBXDURVXYJ22ULZACMICQPHKXFSOOHBEBJABJBCHGJSZCEVY2C7US3FXWDPCWROGVSMCLIGBKLM4L6EPMGBZRA7JG7426LWLKAA=
license: ""
cloudLicenseEnabled: true
aiAssistantEnabled: true
demoModeEnabled: false
supportChatEnabled: false
betaEnabled: false
supportChatEnabled: true
internetConnectivity: true
scripting:
env: {}
source: ""
sources: []
watchScripts: true
active: []
console: true
timezone: ""
logLevel: warning

View File

@@ -3,6 +3,7 @@ package connect
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@@ -11,6 +12,7 @@ import (
"time"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/misc"
"github.com/kubeshark/kubeshark/utils"
"github.com/rs/zerolog/log"
@@ -119,6 +121,140 @@ func (connector *Connector) PostLicense(license string) {
}
}
type postScriptRequest struct {
Title string `json:"title"`
Code string `json:"code"`
}
func (connector *Connector) PostScript(script *misc.Script) (index int64, err error) {
postScriptUrl := fmt.Sprintf("%s/scripts", connector.url)
payload := postScriptRequest{
Title: script.Title,
Code: script.Code,
}
var scriptMarshalled []byte
if scriptMarshalled, err = json.Marshal(payload); err != nil {
log.Error().Err(err).Msg("Failed to marshal the script:")
} else {
ok := false
for !ok {
var resp *http.Response
if resp, err = utils.Post(postScriptUrl, "application/json", bytes.NewBuffer(scriptMarshalled), connector.client, config.Config.License); err != nil || resp.StatusCode != http.StatusOK {
if _, ok := err.(*url.Error); ok {
break
}
log.Warn().Err(err).Msg("Failed creating script Hub:")
} else {
var j map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&j)
if err != nil {
return
}
val, ok := j["index"]
if !ok {
err = errors.New("Response does not contain `key` field!")
return
}
index = int64(val.(float64))
log.Debug().Int("index", int(index)).Interface("script", script).Msg("Created script on Hub:")
return
}
time.Sleep(DefaultSleep)
}
}
return
}
func (connector *Connector) PutScript(script *misc.Script, index int64) (err error) {
putScriptUrl := fmt.Sprintf("%s/scripts/%d", connector.url, index)
var scriptMarshalled []byte
if scriptMarshalled, err = json.Marshal(script); err != nil {
log.Error().Err(err).Msg("Failed to marshal the script:")
} else {
ok := false
for !ok {
client := &http.Client{}
var req *http.Request
req, err = http.NewRequest(http.MethodPut, putScriptUrl, bytes.NewBuffer(scriptMarshalled))
if err != nil {
log.Error().Err(err).Send()
return
}
utils.AddIgnoreCaptureHeader(req)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("License-Key", config.Config.License)
var resp *http.Response
resp, err = client.Do(req)
if err != nil {
log.Error().Err(err).Send()
return
}
if resp.StatusCode != http.StatusOK {
if _, ok := err.(*url.Error); ok {
break
}
log.Warn().Err(err).Msg("Failed updating script on Hub:")
} else {
log.Debug().Int("index", int(index)).Interface("script", script).Msg("Updated script on Hub:")
return
}
time.Sleep(DefaultSleep)
}
}
return
}
func (connector *Connector) DeleteScript(index int64) (err error) {
deleteScriptUrl := fmt.Sprintf("%s/scripts/%d", connector.url, index)
ok := false
for !ok {
client := &http.Client{}
var req *http.Request
req, err = http.NewRequest(http.MethodDelete, deleteScriptUrl, nil)
if err != nil {
log.Error().Err(err).Send()
return
}
utils.AddIgnoreCaptureHeader(req)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("License-Key", config.Config.License)
var resp *http.Response
resp, err = client.Do(req)
if err != nil {
log.Error().Err(err).Send()
return
}
if resp.StatusCode != http.StatusOK {
if _, ok := err.(*url.Error); ok {
break
}
log.Warn().Err(err).Msg("Failed deleting script on Hub:")
} else {
log.Debug().Int("index", int(index)).Msg("Deleted script on Hub:")
return
}
time.Sleep(DefaultSleep)
}
return
}
func (connector *Connector) PostPcapsMerge(out *os.File) {
postEnvUrl := fmt.Sprintf("%s/pcaps/merge", connector.url)

View File

@@ -2,12 +2,8 @@ package kubernetes
import (
"context"
"encoding/json"
"slices"
"strings"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/misc"
"github.com/rs/zerolog/log"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,12 +23,6 @@ const (
CONFIG_AUTH_ENABLED = "AUTH_ENABLED"
CONFIG_AUTH_TYPE = "AUTH_TYPE"
CONFIG_AUTH_SAML_IDP_METADATA_URL = "AUTH_SAML_IDP_METADATA_URL"
CONFIG_SCRIPTING_SCRIPTS = "SCRIPTING_SCRIPTS"
CONFIG_SCRIPTING_ACTIVE_SCRIPTS = "SCRIPTING_ACTIVE_SCRIPTS"
CONFIG_PCAP_DUMP_ENABLE = "PCAP_DUMP_ENABLE"
CONFIG_TIME_INTERVAL = "TIME_INTERVAL"
CONFIG_MAX_TIME = "MAX_TIME"
CONFIG_MAX_SIZE = "MAX_SIZE"
)
func SetSecret(provider *Provider, key string, value string) (updated bool, err error) {
@@ -58,17 +48,6 @@ func SetSecret(provider *Provider, key string, value string) (updated bool, err
return
}
func GetConfig(provider *Provider, key string) (value string, err error) {
var configMap *v1.ConfigMap
configMap, err = provider.clientSet.CoreV1().ConfigMaps(config.Config.Tap.Release.Namespace).Get(context.TODO(), SELF_RESOURCES_PREFIX+SUFFIX_CONFIG_MAP, metav1.GetOptions{})
if err != nil {
return
}
value = configMap.Data[key]
return
}
func SetConfig(provider *Provider, key string, value string) (updated bool, err error) {
var configMap *v1.ConfigMap
configMap, err = provider.clientSet.CoreV1().ConfigMaps(config.Config.Tap.Release.Namespace).Get(context.TODO(), SELF_RESOURCES_PREFIX+SUFFIX_CONFIG_MAP, metav1.GetOptions{})
@@ -84,56 +63,10 @@ func SetConfig(provider *Provider, key string, value string) (updated bool, err
_, err = provider.clientSet.CoreV1().ConfigMaps(config.Config.Tap.Release.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
if err == nil {
if updated {
log.Info().
Str("config", key).
Str("value", func() string {
if len(value) > 10 {
return value[:10]
}
return value
}()).
Int("length", len(value)).
Msg("Updated. Printing only 10 first characters of value:")
log.Info().Str("config", key).Str("value", value).Msg("Updated:")
}
} else {
log.Error().Str("config", key).Err(err).Send()
}
return
}
func ConfigGetScripts(provider *Provider) (scripts map[int64]misc.ConfigMapScript, err error) {
var data string
data, err = GetConfig(provider, CONFIG_SCRIPTING_SCRIPTS)
if err != nil {
return
}
err = json.Unmarshal([]byte(data), &scripts)
return
}
func IsActiveScript(provider *Provider, title string) bool {
configActiveScripts, err := GetConfig(provider, CONFIG_SCRIPTING_ACTIVE_SCRIPTS)
if err != nil {
return false
}
return strings.Contains(configActiveScripts, title)
}
func DeleteActiveScriptByTitle(provider *Provider, title string) (err error) {
configActiveScripts, err := GetConfig(provider, CONFIG_SCRIPTING_ACTIVE_SCRIPTS)
if err != nil {
return err
}
activeScripts := strings.Split(configActiveScripts, ",")
idx := slices.Index(activeScripts, title)
if idx != -1 {
activeScripts = slices.Delete(activeScripts, idx, idx+1)
_, err = SetConfig(provider, CONFIG_SCRIPTING_ACTIVE_SCRIPTS, strings.Join(activeScripts, ","))
if err != nil {
return err
}
}
return nil
}

View File

@@ -8,5 +8,4 @@ const (
HubServiceName = HubPodName
K8sAllNamespaces = ""
MinKubernetesServerVersion = "1.16.0"
AppLabelKey = "app.kubehq.com/app"
)

View File

@@ -247,10 +247,6 @@ func (provider *Provider) GetNamespaces() (namespaces []string) {
return
}
func (provider *Provider) GetClientSet() *kubernetes.Clientset {
return provider.clientSet
}
func getClientSet(config *rest.Config) (*kubernetes.Clientset, error) {
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {

View File

@@ -106,7 +106,7 @@ func getRerouteHttpHandlerSelfStatic(proxyHandler http.Handler, selfNamespace st
}
func NewPortForward(kubernetesProvider *Provider, namespace string, podRegex *regexp.Regexp, srcPort uint16, dstPort uint16, ctx context.Context) (*portforward.PortForwarder, error) {
pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, namespace, map[string]string{AppLabelKey: "front"})
pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, namespace, map[string]string{"app.kubeshark.co/app": "front"})
if err != nil {
return nil, err
} else if len(pods) == 0 {
@@ -138,7 +138,6 @@ func NewPortForward(kubernetesProvider *Provider, namespace string, podRegex *re
go func() {
if err = forwarder.ForwardPorts(); err != nil {
log.Error().Err(err).Msg("While Kubernetes port-forwarding!")
log.Info().Str("command", fmt.Sprintf("kubectl port-forward -n %s service/kubeshark-front 8899:80", config.Config.Tap.Release.Namespace)).Msg("Please try running:")
return
}
}()

View File

@@ -1,20 +1,21 @@
---
# Source: kubeshark/templates/17-network-policies.yaml
# Source: kubeshark/templates/16-network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
policyTypes:
- Ingress
- Egress
@@ -22,21 +23,18 @@ spec:
- ports:
- protocol: TCP
port: 8080
- ports:
- protocol: TCP
port: 9100
egress:
- {}
---
# Source: kubeshark/templates/17-network-policies.yaml
# Source: kubeshark/templates/16-network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front-network-policy
@@ -44,7 +42,7 @@ metadata:
spec:
podSelector:
matchLabels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
policyTypes:
- Ingress
- Egress
@@ -55,42 +53,15 @@ spec:
egress:
- {}
---
# Source: kubeshark/templates/17-network-policies.yaml
# Source: kubeshark/templates/16-network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-dex-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app.kubehq.com/app: dex
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: 5556
egress:
- {}
---
# Source: kubeshark/templates/17-network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-worker-network-policy
@@ -98,14 +69,14 @@ metadata:
spec:
podSelector:
matchLabels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: 48999
port: 30001
- protocol: TCP
port: 49100
egress:
@@ -116,11 +87,12 @@ apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-service-account
namespace: default
---
@@ -131,17 +103,15 @@ metadata:
name: kubeshark-secret
namespace: default
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
stringData:
LICENSE: 'FN7QGAIBA5GGSY3FNZZWKAP7QAAACAYBARCGC5DBAEFAAAIBKIA77AQAAEAVGAP7QIAAAAAK76AQKAIC76CAAAAA7YAUX74AAH7566ZCMVWWC2LMEI5CE43VOBYG64TUIBVXKYTFNBYS42LPEIWCE5LTMVZESZBCHIRFKMZVPFTFMZT2KVQTGSLZNVLW2MRZON3E23CONNJFCQ2UEIWCEYLDMNSXG42UN5VWK3RCHIRCELBCMVSGS5DJN5XCEORCIVHFIRKSKBJESU2FEIWCE3TPMRSXGIR2GEYDALBCOBXWI4ZCHIYCYITFNZSCEORRG43TCMBYHAYDIMZQGAYCYITJNZUXI2LBNRBWC4DBMNUXI6JCHIYCYITDMFYGCY3JOR4SEORQFQRGC4DQL5UWIIR2EJIDEUDZMZ2E62LQOAZEKY2YLBJHS2LWJZ3WYSTLKVGUQ3JCPUATCATX7NHAP7U5DNNY5QYMLW22ZNBELDV24OYIWGD2J3BD5J27C7RS7XIYSSK2OMNLTBXDURVXYJ22ULZACMICQPHKXFSOOHBEBJABJBCHGJSZCEVY2C7US3FXWDPCWROGVSMCLIGBKLM4L6EPMGBZRA7JG7426LWLKAA='
LICENSE: ''
SCRIPTING_ENV: '{}'
OIDC_CLIENT_ID: 'not set'
OIDC_CLIENT_SECRET: 'not set'
---
# Source: kubeshark/templates/13-secret.yaml
kind: Secret
@@ -150,11 +120,11 @@ metadata:
name: kubeshark-saml-x509-crt-secret
namespace: default
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_CRT: |
@@ -166,11 +136,11 @@ metadata:
name: kubeshark-saml-x509-key-secret
namespace: default
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_KEY: |
@@ -182,10 +152,10 @@ metadata:
name: kubeshark-nginx-config-map
namespace: default
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
data:
default.conf: |
@@ -245,70 +215,53 @@ metadata:
name: kubeshark-config-map
namespace: default
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
data:
POD_REGEX: '.*'
NAMESPACES: ''
EXCLUDED_NAMESPACES: ''
BPF_OVERRIDE: ''
STOPPED: 'false'
STOPPED: 'true'
SCRIPTING_SCRIPTS: '{}'
SCRIPTING_ACTIVE_SCRIPTS: ''
INGRESS_ENABLED: 'false'
INGRESS_HOST: 'ks.svc.cluster.local'
PROXY_FRONT_PORT: '8899'
AUTH_ENABLED: 'false'
AUTH_TYPE: 'default'
AUTH_ENABLED: 'true'
AUTH_TYPE: 'oidc'
AUTH_SAML_IDP_METADATA_URL: ''
AUTH_SAML_ROLE_ATTRIBUTE: 'role'
AUTH_SAML_ROLES: '{"admin":{"canDownloadPCAP":true,"canStopTrafficCapturing":true,"canUpdateTargetedPods":true,"canUseScripting":true,"filter":"","scriptingPermissions":{"canActivate":true,"canDelete":true,"canSave":true},"showAdminConsoleLink":true}}'
AUTH_OIDC_ISSUER: 'not set'
AUTH_OIDC_REFRESH_TOKEN_LIFETIME: '3960h'
AUTH_OIDC_STATE_PARAM_EXPIRY: '10m'
AUTH_OIDC_BYPASS_SSL_CA_CHECK: 'false'
TELEMETRY_DISABLED: 'false'
SCRIPTING_DISABLED: 'false'
AUTH_SAML_ROLES: '{"admin":{"canDownloadPCAP":true,"canStopTrafficCapturing":true,"canUpdateTargetedPods":true,"canUseScripting":true,"filter":"","showAdminConsoleLink":true}}'
TELEMETRY_DISABLED: ''
SCRIPTING_DISABLED: ''
TARGETED_PODS_UPDATE_DISABLED: ''
PRESET_FILTERS_CHANGING_ENABLED: 'true'
RECORDING_DISABLED: ''
STOP_TRAFFIC_CAPTURING_DISABLED: 'false'
GLOBAL_FILTER: ""
DEFAULT_FILTER: ""
TRAFFIC_SAMPLE_RATE: '100'
JSON_TTL: '5m'
PCAP_TTL: '0'
PCAP_ERROR_TTL: '0'
PCAP_TTL: '10s'
PCAP_ERROR_TTL: '60s'
TIMEZONE: ' '
CLOUD_LICENSE_ENABLED: 'false'
AI_ASSISTANT_ENABLED: 'true'
CLOUD_LICENSE_ENABLED: 'true'
DUPLICATE_TIMEFRAME: '200ms'
ENABLED_DISSECTORS: 'amqp,dns,http,icmp,kafka,redis,ws,ldap,radius,diameter,udp-flow,tcp-flow'
CUSTOM_MACROS: '{"https":"tls and (http or http2)"}'
DISSECTORS_UPDATING_ENABLED: 'true'
DETECT_DUPLICATES: 'false'
PCAP_DUMP_ENABLE: 'false'
PCAP_TIME_INTERVAL: '1m'
PCAP_MAX_TIME: '1h'
PCAP_MAX_SIZE: '500MB'
PORT_MAPPING: '{"amqp":[5671,5672],"diameter":[3868],"http":[80,443,8080],"kafka":[9092],"ldap":[389],"redis":[6379]}'
RAW_CAPTURE: 'true'
RAW_CAPTURE_STORAGE_SIZE: '1Gi'
ENABLED_DISSECTORS: 'amqp,dns,http,icmp,kafka,redis,sctp,syscall,ws'
---
# Source: kubeshark/templates/02-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-cluster-role-default
namespace: default
rules:
@@ -332,30 +285,20 @@ rules:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- get
- list
- watch
- create
- update
- delete
resourceNames:
- kube-system
---
# Source: kubeshark/templates/03-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-cluster-role-binding-default
namespace: default
roleRef:
@@ -372,10 +315,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role
@@ -387,45 +330,24 @@ rules:
resourceNames:
- kubeshark-secret
- kubeshark-config-map
- kubeshark-secret-default
- kubeshark-config-map-default
resources:
- secrets
- configmaps
verbs:
- create
- get
- watch
- list
- update
- patch
- delete
- apiGroups:
- ""
- v1
resources:
- secrets
- configmaps
- pods/log
verbs:
- create
- get
- apiGroups:
- batch
resources:
- jobs
verbs:
- "*"
---
# Source: kubeshark/templates/03-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role-binding
@@ -444,12 +366,13 @@ apiVersion: v1
kind: Service
metadata:
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub
namespace: default
spec:
@@ -458,7 +381,7 @@ spec:
port: 80
targetPort: 8080
selector:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
type: ClusterIP
---
# Source: kubeshark/templates/07-front-service.yaml
@@ -466,11 +389,12 @@ apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front
namespace: default
spec:
@@ -479,7 +403,7 @@ spec:
port: 80
targetPort: 8080
selector:
app.kubehq.com/app: front
app.kubeshark.co/app: front
type: ClusterIP
---
# Source: kubeshark/templates/15-worker-service-metrics.yaml
@@ -487,10 +411,10 @@ kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
@@ -499,11 +423,11 @@ metadata:
namespace: default
spec:
selector:
app.kubehq.com/app: worker
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: worker
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
@@ -511,106 +435,58 @@ spec:
port: 49100
targetPort: 49100
---
# Source: kubeshark/templates/16-hub-service-metrics.yaml
kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-52.11.7
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9100'
name: kubeshark-hub-metrics
namespace: default
spec:
selector:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
protocol: TCP
port: 9100
targetPort: 9100
---
# Source: kubeshark/templates/09-worker-daemon-set.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
sidecar.istio.io/inject: "false"
helm.sh/chart: kubeshark-52.11.7
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-worker-daemon-set
namespace: default
spec:
selector:
matchLabels:
app.kubehq.com/app: worker
app.kubeshark.co/app: worker
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
template:
metadata:
labels:
app.kubehq.com/app: worker
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: worker
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
name: kubeshark-worker-daemon-set
namespace: kubeshark
spec:
initContainers:
- command:
- /bin/sh
- -c
- mkdir -p /sys/fs/bpf && mount | grep -q '/sys/fs/bpf' || mount -t bpf bpf /sys/fs/bpf
image: 'docker.io/kubeshark/worker:v52.11'
imagePullPolicy: Always
name: mount-bpf
securityContext:
privileged: true
volumeMounts:
- mountPath: /sys
name: sys
mountPropagation: Bidirectional
containers:
- command:
- ./worker
- -i
- any
- -port
- '48999'
- '30001'
- -metrics-port
- '49100'
- -packet-capture
- 'best'
- -loglevel
- 'warning'
- -unixsocket
- -servicemesh
- -procfs
- /hostproc
- -disable-ebpf
- -resolution-strategy
- 'auto'
- -staletimeout
- '30'
- -storage-size
- '10Gi'
- -capture-db-max-size
- '500Mi'
image: 'docker.io/kubeshark/worker:v52.11'
image: 'docker.io/kubeshark/worker:v52.3.75'
imagePullPolicy: Always
name: sniffer
ports:
@@ -631,42 +507,40 @@ spec:
- name: TCP_STREAM_CHANNEL_TIMEOUT_SHOW
value: 'false'
- name: KUBESHARK_CLOUD_API_URL
value: 'https://api.kubehq.com'
value: 'https://api.kubeshark.co'
- name: PROFILING_ENABLED
value: 'false'
- name: SENTRY_ENABLED
value: 'false'
- name: SENTRY_ENVIRONMENT
value: 'production'
resources:
limits:
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
securityContext:
privileged: true
capabilities:
add:
- NET_RAW
- NET_ADMIN
- SYS_ADMIN
- SYS_PTRACE
- DAC_OVERRIDE
drop:
- ALL
readinessProbe:
periodSeconds: 5
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
tcpSocket:
port: 48999
port: 30001
livenessProbe:
periodSeconds: 5
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
tcpSocket:
port: 48999
port: 30001
volumeMounts:
- mountPath: /hostproc
name: proc
@@ -674,17 +548,14 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- command:
- ./tracer
- -procfs
- /hostproc
- -disable-tls-log
- -loglevel
- 'warning'
image: 'docker.io/kubeshark/worker:v52.11'
- -disable-ebpf
image: 'docker.io/kubeshark/worker:v52.3.75'
imagePullPolicy: Always
name: tracer
env:
@@ -698,25 +569,24 @@ spec:
fieldPath: metadata.namespace
- name: PROFILING_ENABLED
value: 'false'
- name: SENTRY_ENABLED
value: 'false'
- name: SENTRY_ENVIRONMENT
value: 'production'
resources:
limits:
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
- SYS_PTRACE
- SYS_RESOURCE
- IPC_LOCK
- NET_RAW
- NET_ADMIN
drop:
- ALL
volumeMounts:
- mountPath: /hostproc
name: proc
@@ -724,23 +594,20 @@ spec:
- mountPath: /sys
name: sys
readOnly: true
mountPropagation: HostToContainer
- mountPath: /app/data
name: data
- mountPath: /etc/os-release
name: os-release
readOnly: true
- mountPath: /hostroot
mountPropagation: HostToContainer
name: root
readOnly: true
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
serviceAccountName: kubeshark-service-account
terminationGracePeriodSeconds: 0
tolerations:
- key:
operator: "Exists"
effect: "NoExecute"
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
@@ -763,63 +630,49 @@ spec:
- hostPath:
path: /etc/os-release
name: os-release
- hostPath:
path: /
name: root
- name: data
emptyDir:
sizeLimit: 10Gi
sizeLimit: 500Mi
---
# Source: kubeshark/templates/04-hub-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-hub
namespace: default
spec:
replicas: 1 # Set the desired number of replicas
selector:
matchLabels:
app.kubehq.com/app: hub
app.kubeshark.co/app: hub
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
template:
metadata:
labels:
app.kubehq.com/app: hub
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: hub
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
spec:
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: kubeshark-service-account
containers:
- name: hub
- name: kubeshark-hub
command:
- ./hub
- -port
- "8080"
- -loglevel
- 'warning'
- -capture-stop-after
- "5m"
- -snapshot-size-limit
- '20Gi'
- -dissector-image
- 'kubeshark/worker:master'
- -dissector-cpu
- '1'
- -dissector-memory
- '2Gi'
env:
- name: POD_NAME
valueFrom:
@@ -829,58 +682,35 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SENTRY_ENABLED
value: 'false'
- name: SENTRY_ENVIRONMENT
value: 'production'
- name: KUBESHARK_CLOUD_API_URL
value: 'https://api.kubehq.com'
- name: PROFILING_ENABLED
value: 'false'
image: 'docker.io/kubeshark/hub:v52.11'
value: 'https://api.kubeshark.co'
image: 'docker.io/kubeshark/hub:v52.3.75'
imagePullPolicy: Always
readinessProbe:
periodSeconds: 5
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
initialDelaySeconds: 3
tcpSocket:
port: 8080
livenessProbe:
periodSeconds: 5
periodSeconds: 1
failureThreshold: 3
successThreshold: 1
initialDelaySeconds: 5
initialDelaySeconds: 3
tcpSocket:
port: 8080
resources:
limits:
memory: 5Gi
cpu: 750m
memory: 1Gi
requests:
cpu: 50m
memory: 50Mi
volumeMounts:
- name: saml-x509-volume
mountPath: "/etc/saml/x509"
readOnly: true
- name: snapshots-volume
mountPath: "/app/data/snapshots"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
volumes:
- name: saml-x509-volume
projected:
@@ -895,50 +725,46 @@ spec:
items:
- key: AUTH_SAML_X509_KEY
path: kubeshark.key
- name: snapshots-volume
emptyDir:
sizeLimit: 20Gi
---
# Source: kubeshark/templates/06-front-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubehq.com/app: front
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: front
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front
namespace: default
spec:
replicas: 1 # Set the desired number of replicas
selector:
matchLabels:
app.kubehq.com/app: front
app.kubeshark.co/app: front
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
template:
metadata:
labels:
app.kubehq.com/app: front
helm.sh/chart: kubeshark-52.11.7
app.kubeshark.co/app: front
helm.sh/chart: kubeshark-52.3.75
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "52.11.7"
app.kubernetes.io/version: "52.3.75"
app.kubernetes.io/managed-by: Helm
spec:
containers:
- env:
- name: REACT_APP_DEFAULT_FILTER
value: ' '
- name: REACT_APP_AUTH_ENABLED
value: 'false'
- name: REACT_APP_AUTH_TYPE
value: 'default'
- name: REACT_APP_COMPLETE_STREAMING_ENABLED
value: 'true'
- name: REACT_APP_STREAMING_TYPE
value: 'connect-rpc'
- name: REACT_APP_AUTH_TYPE
value: 'oidc'
- name: REACT_APP_AUTH_SAML_IDP_METADATA_URL
value: ' '
- name: REACT_APP_TIMEZONE
@@ -947,31 +773,17 @@ spec:
value: 'false'
- name: REACT_APP_TARGETED_PODS_UPDATE_DISABLED
value: 'false'
- name: REACT_APP_PRESET_FILTERS_CHANGING_ENABLED
value: 'true'
- name: REACT_APP_BPF_OVERRIDE_DISABLED
value: 'true'
value: 'false'
- name: REACT_APP_RECORDING_DISABLED
value: 'false'
- name: REACT_APP_STOP_TRAFFIC_CAPTURING_DISABLED
value: 'false'
- name: 'REACT_APP_CLOUD_LICENSE_ENABLED'
value: '"false"'
- name: 'REACT_APP_AI_ASSISTANT_ENABLED'
value: 'true'
- name: REACT_APP_SUPPORT_CHAT_ENABLED
value: 'false'
- name: REACT_APP_BETA_ENABLED
value: 'false'
- name: REACT_APP_DISSECTORS_UPDATING_ENABLED
value: 'true'
- name: REACT_APP_RAW_CAPTURE_ENABLED
value: 'true'
- name: REACT_APP_SENTRY_ENABLED
value: 'false'
- name: REACT_APP_SENTRY_ENVIRONMENT
value: 'production'
image: 'docker.io/kubeshark/front:v52.11'
image: 'docker.io/kubeshark/front:v52.3.75'
imagePullPolicy: Always
name: kubeshark-front
livenessProbe:
@@ -1001,15 +813,6 @@ spec:
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
readOnly: true
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
volumes:
- name: nginx-config
configMap:

View File

@@ -5,7 +5,7 @@ metadata:
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: info@kubehq.com
email: info@kubeshark.co
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:

View File

@@ -10,8 +10,8 @@ var (
Software = "Kubeshark"
Program = "kubeshark"
Description = "The API Traffic Analyzer for Kubernetes"
Website = "https://www.kubehq.com"
Email = "support@kubehq.io"
Website = "https://kubeshark.co"
Email = "info@kubeshark.co"
Ver = "0.0.0"
Branch = "master"
GitCommitHash = "" // this var is overridden using ldflags in makefile when building

View File

@@ -10,24 +10,9 @@ import (
)
type Script struct {
Path string `json:"path"`
Title string `json:"title"`
Code string `json:"code"`
Active bool `json:"active"`
}
type ConfigMapScript struct {
Title string `json:"title"`
Code string `json:"code"`
Active bool `json:"active"`
}
func (s *Script) ConfigMap() ConfigMapScript {
return ConfigMapScript{
Title: s.Title,
Code: s.Code,
Active: s.Active,
}
Path string `json:"path"`
Title string `json:"title"`
Code string `json:"code"`
}
func ReadScriptFile(path string) (script *Script, err error) {
@@ -61,10 +46,9 @@ func ReadScriptFile(path string) (script *Script, err error) {
}
script = &Script{
Path: path,
Title: title,
Code: code,
Active: false,
Path: path,
Title: title,
Code: code,
}
return

View File

@@ -16,7 +16,7 @@ const (
// Get - When err is nil, resp always contains a non-nil resp.Body.
// Caller should close resp.Body when done reading from it.
func Get(url string, client *http.Client) (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
req, err := http.NewRequest(http.MethodPost, url, nil)
if err != nil {
return nil, err
}