Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
10d701b
feat: add perses as optional standalone dashboarding component
MichaelSp Jun 24, 2026
44248e7
Merge branch 'main' into feat/add-perses
MichaelSp Jun 26, 2026
e0ad6c5
chore: update perses image version to v0.53.1 🐳
MichaelSp Jun 26, 2026
7456649
Merge branch 'main' into feat/add-perses
MichaelSp Jun 29, 2026
364a1cf
feat: add Perses dashboarding component to observability stack 🐳
MichaelSp Jun 29, 2026
0cb7a85
Merge branch 'main' into feat/add-perses
MichaelSp Jun 29, 2026
ae0c38d
fix: patch perses gateway listener hostname and cert in observability…
MichaelSp Jun 30, 2026
eebb1d5
fix(e2e): increase prometheus metric wait timeout to 10 minutes
MichaelSp Jun 30, 2026
0fde218
feat: integrate Perses into ObservabilityStack RGD with enabled flag
MichaelSp Jul 1, 2026
f848734
Merge branch 'main' into feat/add-perses
MichaelSp Jul 1, 2026
e8cf497
fix(e2e): rename observability-stack RGD file to sort after dependencies
MichaelSp Jul 1, 2026
9e6ebe1
Revert "fix(e2e): rename observability-stack RGD file to sort after d…
MichaelSp Jul 1, 2026
e8f50c6
fix(perses): use sentinel ConfigMap to expose kustomization readiness…
MichaelSp Jul 1, 2026
982b25d
fix(perses): use static status.ready to work around kro includeWhen l…
MichaelSp Jul 1, 2026
3f5b00a
fix(perses): drop ready-state propagation, add explanatory note
MichaelSp Jul 1, 2026
9907879
Merge branch 'main' into feat/add-perses
MichaelSp Aug 18, 2026
75f2c6e
Merge branch 'main' into feat/add-perses
MichaelSp Aug 18, 2026
eebff5d
Merge branch 'main' into feat/add-perses
MichaelSp Aug 19, 2026
5e6d675
Merge branch 'main' into feat/add-perses
MichaelSp Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 90 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ spec:
namespace: open-telemetry-operator-system
openTelemetryCollector:
namespace: open-telemetry-collector-system
clusterName: platform
prometheusOperator:
namespace: prometheus-operator-system
prometheus:
Expand Down Expand Up @@ -406,7 +407,95 @@ kubectl get prometheus.monitoring.coreos.com prometheus -n prometheus-system -o

The Prometheus dashboard also shows the connected Alertmanager count under **Status → Runtime & Build Info**.

#### 9. Log Collection and Cross-Cluster Ingestion
#### 9. Perses Dashboards

[Perses](https://perses.dev) is an optional dashboarding component that provides a Kubernetes-native dashboard UI on top of Prometheus and Victoria Logs. It is disabled by default.

**Enable Perses:**

```bash
kubectl patch observabilitystack stack -n obs-stack \
--type=merge -p '{"spec":{"perses":{"enabled":true}}}'
```

Or add `perses.enabled: true` to your `ObservabilityStack` spec:

```yaml
spec:
# ... other fields ...
perses:
enabled: true
```

Wait for the stack to become ready:

```bash
kubectl wait observabilitystack stack -n obs-stack \
--for=jsonpath='{.status.ready}'=true \
--timeout=300s
```

**Access the UI:**

Perses is exposed through the Observability Gateway. Get the hostname:

```bash
kubectl get httproute perses -n perses-system -o jsonpath='{.spec.hostnames[0]}'
```

The URL follows the pattern:

```
https://dashboards.<gateway-namespace>.<base-domain>:<port>
```

For local development via port-forward:

```bash
kubectl port-forward -n perses-system svc/perses 8080:8080
```

Then open: `http://localhost:8080`

**Pre-provisioned resources:**

The following are provisioned automatically at startup:

| Resource | Name | Details |
| --- | --- | --- |
| `GlobalDatasource` | `prometheus` | Default datasource, proxied to `prometheus-operated.prometheus-system.svc:9090` |
| `GlobalDatasource` | `victoria-logs` | Proxied to `victoria-logs.victoria-logs-system.svc:9428` |

**Configuration options** (all have defaults, only override what you need):

```yaml
spec:
forProvider:
namespace: perses-system # target namespace
prometheusRef:
namespace: prometheus-system
serviceName: prometheus-operated
port: 9090
victoriaLogsRef:
namespace: victoria-logs-system
serviceName: victoria-logs
port: 9428
resources:
requests:
memory: "128Mi"
cpu: "50m"
limits:
memory: "512Mi"
cpu: "500m"
```

An sample dashboard is included in the [`kustomizations/perses/provisioning/sample-dashboard.yaml`](kustomizations/perses/provisioning/sample-dashboard.yaml) file. You can apply it to the Perses instance:

```bash
kubectl apply -f kustomizations/perses/provisioning/sample-dashboard.yaml -n perses-system
```

#### 10. Log Collection and Cross-Cluster Ingestion

Pod logs (stdout/stderr from all containers on every node) are automatically collected by an OpenTelemetry Collector DaemonSet running in `open-telemetry-collector-system`. It reads from `/var/log/pods` on each node and ships logs to Victoria Logs via OTLP HTTP.

Expand Down
16 changes: 16 additions & 0 deletions component-constructor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,19 @@ components:
type: ociImage
imageReference: "docker.io/victoriametrics/victoria-logs:${VICTORIA_LOGS_IMAGE_VERSION}"

# perses
- name: perses-kustomization
version: ${OBSERVABILITY_STACK_VERSION}
type: kustomization
access:
type: ociArtifact
imageReference: "${KUSTOMIZATIONS_LOCATION_PREFIX}/perses:${OBSERVABILITY_STACK_VERSION}"

- name: perses-image
version: ${PERSES_IMAGE_VERSION}
type: ociImage
input:
type: ociImage
path: "docker.io/persesdev/perses:${PERSES_IMAGE_VERSION}"
repository: images/perses

3 changes: 3 additions & 0 deletions component-settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ ALERTMANAGER_IMAGE_VERSION: "v0.33.1"
# victoria logs
VICTORIA_LOGS_IMAGE_VERSION: "v1.6.0-victorialogs"

# perses
PERSES_IMAGE_VERSION: "v0.53.1"


# E2E Test dependencies
# Not used for deployment
Expand Down
3 changes: 2 additions & 1 deletion hack/build-component.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def push_kustomizations(repo_root: Path, version: str) -> None:
("prometheus", "prometheus"),
("metrics", "metrics"),
("victoria-logs", "victoria-logs"),
("observability-gateway", "observability-gateway")
("observability-gateway", "observability-gateway"),
("perses", "perses"),
]

# Get git information
Expand Down
29 changes: 29 additions & 0 deletions kustomizations/observability-gateway/gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ spec:
certificateRefs:
- kind: Secret
name: otlp-logs-cert
- name: perses
port: 8443
protocol: HTTPS
hostname: "<perses-dnsname>"
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: perses-cert
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
Expand Down Expand Up @@ -92,3 +104,20 @@ spec:
- kind: "Secret"
group: ""
name: "observability-client-ca-cert"
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: perses-mtls
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: observability-gateway
sectionName: perses
tls:
clientValidation:
caCertificateRefs:
- kind: "Secret"
group: ""
name: "observability-client-ca-cert"
1 change: 1 addition & 0 deletions kustomizations/observability-gateway/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ resources:
- prometheus-certificates.yaml
- victoria-logs-certificates.yaml
- otlp-logs-certificates.yaml
- perses-certificates.yaml
- client-certificates.yaml
10 changes: 10 additions & 0 deletions kustomizations/observability-gateway/perses-certificates.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: perses-gateway-cert
spec:
secretName: perses-cert
issuerRef:
name: gateway-selfsigned-issuer
kind: Issuer
dnsNames: []
46 changes: 46 additions & 0 deletions kustomizations/perses/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: perses-config
data:
config.yaml: |
database:
file:
folder: /tmp/perses
plugin:
path: /tmp/perses-plugins
provisioning:
folders:
- /etc/perses/provisioning
- /etc/perses/dashboards
---
apiVersion: v1
kind: ConfigMap
metadata:
name: perses-provisioning
data:
datasources.yaml: |
kind: GlobalDatasource
metadata:
name: prometheus
spec:
default: true
plugin:
kind: PrometheusDatasource
spec:
proxy:
kind: HTTPProxy
spec:
url: "http://prometheus-operated.prometheus-system.svc:9090"
victoria-logs-datasource.yaml: |
kind: GlobalDatasource
metadata:
name: victoria-logs
spec:
plugin:
kind: VictoriaLogsDatasource
spec:
proxy:
kind: HTTPProxy
spec:
url: "http://victoria-logs.victoria-logs-system.svc:9428"
50 changes: 50 additions & 0 deletions kustomizations/perses/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: perses
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: perses
template:
metadata:
labels:
app.kubernetes.io/name: perses
spec:
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 1000
containers:
- name: perses
args:
- --config=/etc/perses/config.yaml
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: config
mountPath: /etc/perses/config.yaml
subPath: config.yaml
- name: provisioning
mountPath: /etc/perses/provisioning
- name: dashboards
mountPath: /etc/perses/dashboards
resources:
requests:
memory: 128Mi
cpu: 50m
limits:
memory: 512Mi
cpu: 500m
volumes:
- name: config
configMap:
name: perses-config
- name: provisioning
configMap:
name: perses-provisioning
- name: dashboards
configMap:
name: perses-dashboards
18 changes: 18 additions & 0 deletions kustomizations/perses/httproute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: perses
spec:
parentRefs:
- name: observability-gateway
namespace: observability-gateway-system
sectionName: perses
hostnames: []
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: perses
port: 8080
7 changes: 7 additions & 0 deletions kustomizations/perses/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- configmap.yaml
- httproute.yaml
Loading
Loading