Compare commits

...

5 Commits

Author SHA1 Message Date
Volodymyr Stoiko
f476c89610 cloud-storage-docs 2026-03-03 20:00:25 +00:00
Volodymyr Stoiko
81dcb8778f Merge branch 'master' into cloud-storage 2026-03-02 20:10:53 +02:00
Volodymyr Stoiko
1031c08c0a fixes 2026-03-02 20:08:18 +02:00
Volodymyr Stoiko
ba9da99e34 Add readme updates for cloud storage 2026-03-02 20:05:08 +02:00
Volodymyr Stoiko
5be6cd757a add testing values for helm chart 2026-02-25 13:03:32 +00:00
6 changed files with 268 additions and 11 deletions

View File

@@ -308,11 +308,22 @@ type RawCaptureConfig struct {
StorageSize string `yaml:"storageSize" json:"storageSize" default:"1Gi"`
}
type SnapshotsConfig struct {
type SnapshotsLocalConfig struct {
StorageClass string `yaml:"storageClass" json:"storageClass" default:""`
StorageSize string `yaml:"storageSize" json:"storageSize" default:"20Gi"`
}
type SnapshotsCloudConfig struct {
Provider string `yaml:"provider" json:"provider" default:""`
ConfigMaps []string `yaml:"configMaps" json:"configMaps" default:"[]"`
Secrets []string `yaml:"secrets" json:"secrets" default:"[]"`
}
type SnapshotsConfig struct {
Local SnapshotsLocalConfig `yaml:"local" json:"local"`
Cloud SnapshotsCloudConfig `yaml:"cloud" json:"cloud"`
}
type DelayedDissectionConfig struct {
CPU string `yaml:"cpu" json:"cpu" default:"1"`
Memory string `yaml:"memory" json:"memory" default:"4Gi"`

View File

@@ -143,8 +143,11 @@ Example for overriding image names:
| `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.snapshots.local.storageClass` | Storage class for local snapshots volume. When empty, uses `emptyDir`. When set, creates a PVC with this storage class | `""` |
| `tap.snapshots.local.storageSize` | Storage size for local snapshots volume (supports K8s quantity format: `1Gi`, `500Mi`, etc.) | `20Gi` |
| `tap.snapshots.cloud.provider` | Cloud storage provider for snapshots: `s3` or `azblob`. Empty string disables cloud storage. See [Cloud Storage docs](docs/snapshots_cloud_storage.md). | `""` |
| `tap.snapshots.cloud.configMaps` | Names of ConfigMaps containing cloud storage environment variables. See [Cloud Storage docs](docs/snapshots_cloud_storage.md). | `[]` |
| `tap.snapshots.cloud.secrets` | Names of Secrets containing cloud storage credentials. See [Cloud Storage docs](docs/snapshots_cloud_storage.md). | `[]` |
| `tap.release.repo` | URL of the Helm chart repository | `https://helm.kubeshark.com` |
| `tap.release.name` | Helm release name | `kubeshark` |
| `tap.release.namespace` | Helm release namespace | `default` |

View File

@@ -0,0 +1,226 @@
# Cloud Storage for Snapshots
Kubeshark can upload and download snapshots to cloud object storage, enabling cross-cluster sharing, backup/restore, and long-term retention.
Supported providers: **Amazon S3** (`s3`) and **Azure Blob Storage** (`azblob`).
## Helm Values
```yaml
tap:
snapshots:
cloud:
provider: "" # "s3" or "azblob" (empty = disabled)
configMaps: [] # names of pre-existing ConfigMaps with cloud config env vars
secrets: [] # names of pre-existing Secrets with cloud credentials
```
- `provider` selects which cloud backend to use. Leave empty to disable cloud storage.
- `configMaps` and `secrets` are lists of names of existing ConfigMap/Secret resources. They are mounted as `envFrom` on the hub pod, injecting all their keys as environment variables.
---
## Amazon S3
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `SNAPSHOT_AWS_BUCKET` | Yes | S3 bucket name |
| `SNAPSHOT_AWS_REGION` | No | AWS region (uses SDK default if empty) |
| `SNAPSHOT_AWS_ACCESS_KEY` | No | Static access key ID (empty = use default credential chain) |
| `SNAPSHOT_AWS_SECRET_KEY` | No | Static secret access key |
| `SNAPSHOT_AWS_ROLE_ARN` | No | IAM role ARN to assume via STS (for cross-account access) |
| `SNAPSHOT_AWS_EXTERNAL_ID` | No | External ID for the STS AssumeRole call |
| `SNAPSHOT_CLOUD_PREFIX` | No | Key prefix in the bucket (e.g. `snapshots/`) |
### Authentication Methods
Credentials are resolved in this order:
1. **Static credentials** -- If `SNAPSHOT_AWS_ACCESS_KEY` is set, static credentials are used directly.
2. **STS AssumeRole** -- If `SNAPSHOT_AWS_ROLE_ARN` is also set, the static (or default) credentials are used to assume the given IAM role. This is useful for cross-account S3 access.
3. **AWS default credential chain** -- When no static credentials are provided, the SDK default chain is used:
- **IRSA** (EKS service account token) -- recommended for production on EKS
- EC2 instance profile
- Standard AWS environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, etc.)
- Shared credentials file (`~/.aws/credentials`)
The provider validates bucket access on startup via `HeadBucket`. If the bucket is inaccessible, the hub will fail to start.
### Example: IRSA (recommended for EKS)
Create a ConfigMap with bucket configuration:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubeshark-s3-config
data:
SNAPSHOT_AWS_BUCKET: my-kubeshark-snapshots
SNAPSHOT_AWS_REGION: us-east-1
```
Set Helm values:
```yaml
tap:
snapshots:
cloud:
provider: "s3"
configMaps:
- kubeshark-s3-config
```
The hub pod's service account must be annotated for IRSA with an IAM role that has S3 access to the bucket.
### Example: Static Credentials
Create a Secret with credentials:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: kubeshark-s3-creds
type: Opaque
stringData:
SNAPSHOT_AWS_ACCESS_KEY: AKIA...
SNAPSHOT_AWS_SECRET_KEY: wJal...
```
Create a ConfigMap with bucket configuration:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubeshark-s3-config
data:
SNAPSHOT_AWS_BUCKET: my-kubeshark-snapshots
SNAPSHOT_AWS_REGION: us-east-1
```
Set Helm values:
```yaml
tap:
snapshots:
cloud:
provider: "s3"
configMaps:
- kubeshark-s3-config
secrets:
- kubeshark-s3-creds
```
### Example: Cross-Account Access via AssumeRole
Add the role ARN to your ConfigMap:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubeshark-s3-config
data:
SNAPSHOT_AWS_BUCKET: other-account-bucket
SNAPSHOT_AWS_REGION: eu-west-1
SNAPSHOT_AWS_ROLE_ARN: arn:aws:iam::123456789012:role/KubesharkCrossAccountRole
SNAPSHOT_AWS_EXTERNAL_ID: my-external-id # optional, if required by the trust policy
```
The hub will first authenticate using its own credentials (IRSA, static, or default chain), then assume the specified role to access the bucket.
---
## Azure Blob Storage
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `SNAPSHOT_AZBLOB_STORAGE_ACCOUNT` | Yes | Azure storage account name |
| `SNAPSHOT_AZBLOB_CONTAINER` | Yes | Blob container name |
| `SNAPSHOT_AZBLOB_STORAGE_KEY` | No | Storage account access key (empty = use DefaultAzureCredential) |
| `SNAPSHOT_CLOUD_PREFIX` | No | Key prefix in the container (e.g. `snapshots/`) |
### Authentication Methods
Credentials are resolved in this order:
1. **Shared Key** -- If `SNAPSHOT_AZBLOB_STORAGE_KEY` is set, the storage account key is used directly.
2. **DefaultAzureCredential** -- When no storage key is provided, the Azure SDK default credential chain is used:
- **Workload Identity** (AKS pod identity) -- recommended for production on AKS
- Managed Identity (system or user-assigned)
- Azure CLI credentials
- Environment variables (`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`)
The provider validates container access on startup via `GetProperties`. If the container is inaccessible, the hub will fail to start.
### Example: Workload Identity (recommended for AKS)
Create a ConfigMap with storage configuration:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubeshark-azblob-config
data:
SNAPSHOT_AZBLOB_STORAGE_ACCOUNT: mykubesharksa
SNAPSHOT_AZBLOB_CONTAINER: snapshots
```
Set Helm values:
```yaml
tap:
snapshots:
cloud:
provider: "azblob"
configMaps:
- kubeshark-azblob-config
```
The hub pod's service account must be configured for AKS Workload Identity with a managed identity that has the **Storage Blob Data Contributor** role on the container.
### Example: Storage Account Key
Create a Secret with the storage key:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: kubeshark-azblob-creds
type: Opaque
stringData:
SNAPSHOT_AZBLOB_STORAGE_KEY: "base64-encoded-storage-key..."
```
Create a ConfigMap with storage configuration:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: kubeshark-azblob-config
data:
SNAPSHOT_AZBLOB_STORAGE_ACCOUNT: mykubesharksa
SNAPSHOT_AZBLOB_CONTAINER: snapshots
```
Set Helm values:
```yaml
tap:
snapshots:
cloud:
provider: "azblob"
configMaps:
- kubeshark-azblob-config
secrets:
- kubeshark-azblob-creds
```

View File

@@ -61,12 +61,24 @@ spec:
{{- end }}
- -cloud-api-url
- '{{ .Values.cloudApiUrl }}'
{{- if .Values.tap.secrets }}
{{- if .Values.tap.snapshots.cloud.provider }}
- -cloud-storage-provider
- '{{ .Values.tap.snapshots.cloud.provider }}'
{{- end }}
{{- if or .Values.tap.secrets .Values.tap.snapshots.cloud.configMaps .Values.tap.snapshots.cloud.secrets }}
envFrom:
{{- range .Values.tap.secrets }}
- secretRef:
name: {{ . }}
{{- end }}
{{- range .Values.tap.snapshots.cloud.configMaps }}
- configMapRef:
name: {{ . }}
{{- end }}
{{- range .Values.tap.snapshots.cloud.secrets }}
- secretRef:
name: {{ . }}
{{- end }}
{{- end }}
env:
- name: POD_NAME
@@ -188,10 +200,10 @@ spec:
- key: AUTH_SAML_X509_KEY
path: kubeshark.key
- name: snapshots-volume
{{- if .Values.tap.snapshots.storageClass }}
{{- if .Values.tap.snapshots.local.storageClass }}
persistentVolumeClaim:
claimName: {{ include "kubeshark.name" . }}-snapshots-pvc
{{- else }}
emptyDir:
sizeLimit: {{ .Values.tap.snapshots.storageSize }}
sizeLimit: {{ .Values.tap.snapshots.local.storageSize }}
{{- end }}

View File

@@ -1,5 +1,5 @@
---
{{- if .Values.tap.snapshots.storageClass }}
{{- if .Values.tap.snapshots.local.storageClass }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
@@ -16,7 +16,7 @@ spec:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.tap.snapshots.storageSize }}
storageClassName: {{ .Values.tap.snapshots.storageClass }}
storage: {{ .Values.tap.snapshots.local.storageSize }}
storageClassName: {{ .Values.tap.snapshots.local.storageClass }}
status: {}
{{- end }}

View File

@@ -38,8 +38,13 @@ tap:
cpu: "1"
memory: 4Gi
snapshots:
storageClass: ""
storageSize: 20Gi
local:
storageClass: ""
storageSize: 20Gi
cloud:
provider: "" # cloud storage provider: "s3" (empty = disabled)
configMaps: [] # names of ConfigMaps with cloud storage env vars
secrets: [] # names of Secrets with cloud storage credentials
release:
repo: https://helm.kubeshark.com
name: kubeshark