Skip to content

Commit c2dc818

Browse files
djwfyijohannesfreyseanschneeweiss
authored
docs: add fleet observability phase 1 guide (#2371)
docs(observability): add fleet observability guides Add the new gateway-based fleet observability doc set: install and Argo CD deployment, metrics access keys, edge collector configuration, querying via PromQL and the bundled Grafana, platform labels, and troubleshooting. Point the monitoring overview at these guides first, keeping the older OpenTelemetry remote_write pages as a simpler or more advanced alternative. Promote the feature out of monitoring/fleet into its own Observability category to fix nav confusion with the older OpenTelemetry page, and correct several implementation-accuracy gaps found by comparing the docs against loft-enterprise: the connector label key, gateway TLS being mandatory rather than optional, the access-key secret's actual fields, and which datasource lifecycle pieces are already implemented versus future work. Also loosens the docs style rule against platform UI screenshots for cases like dashboard views that are hard to describe in prose. Closes ENGPLAT-471 Co-authored-by: Johannes Frey <johannes.frey@loft.sh> Co-authored-by: Sean Schneeweiss <sean.schneeweiss@vcluster.com>
1 parent 4ef9a3b commit c2dc818

21 files changed

Lines changed: 1887 additions & 70 deletions

.github/styles/config/vocabularies/Loft/accept.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ SSH
8181
SSHKey[s]?
8282
StatefulSet
8383
TSNet
84+
TLS
85+
mTLS
86+
PromQL
8487
URL
8588
vCluster
8689
vcluster.yaml
@@ -89,4 +92,4 @@ rpm.vcluster.com
8992
[vVirtual] [cC]luster
9093
Velero
9194
VolumeAttachment
92-
(?i)yaml
95+
(?i)yaml

.vale.ini

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,17 @@ Vale.Terms = NO
7676
BasedOnStyles = Loft, Google, Vale
7777
Vale.Terms = NO
7878

79+
# `metrics-backend-mtls` is a literal Kubernetes Secret name (must stay
80+
# lowercase per RFC 1123), and "Deploy Grafana" is correct sentence case with
81+
# a proper noun that Google.Headings doesn't recognize as one. Neither needs
82+
# to change, so scope both rules off for this page instead of the vocab (which
83+
# would create new false positives on the "grafana" anchors and reverse-proxy
84+
# path used throughout the fleet monitoring pages).
85+
[**/observability/deploy-with-argocd.mdx]
86+
BasedOnStyles = Loft, Google, Vale
87+
Vale.Terms = NO
88+
Google.Headings = NO
89+
7990
# Auto-generated by scripts/generate-platform-cli-index.js from
8091
# vcluster/cli/vcluster_platform*.md. The regenerate-instructions comment
8192
# references that file path in plain text, and command descriptions are

CLAUDE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,10 @@ When writing docs for new features:
178178
### Examples format
179179

180180
- vcluster.yaml: description + code block
181-
- Platform: description + step-by-step (no UI screenshots - they go stale)
181+
- Platform: description + step-by-step. Minimize UI screenshots since the UI
182+
changes often and screenshots go stale, but they're okay where warranted
183+
(for example, illustrating a dashboard or layout that's hard to describe in
184+
prose).
182185

183186
### Checklist
184187

platform/maintenance/monitoring/central-hostpath-mapper.mdx

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Central HostPath Mapper
33
sidebar_label: Central HostPath Mapper
4-
sidebar_position: 6
4+
sidebar_position: 7
55
sidebar_class_name: free
66
---
77

@@ -17,9 +17,9 @@ import FeatureTable from '@site/src/components/FeatureTable';
1717

1818
You can install a common logging solution such as Fluentd or the ELK stack on the Control Plane Cluster and use it within the tenant cluster. However, in some scenarios, installing these tools directly on the tenant cluster is preferred.
1919

20-
These logging solutions access pod and container logs by mounting node host paths and using specific filename formats to associate logs with the correct pods. This approach doesnt work in a vCluster because the vCluster rewrites pod names to a vCluster-specific format when syncing them to the Control Plane Cluster.
20+
These logging solutions access pod and container logs by mounting node host paths and using specific filename formats to associate logs with the correct pods. This approach doesn't work in a tenant cluster because vCluster rewrites pod names to a vCluster-specific format when syncing them to the Control Plane Cluster.
2121

22-
The HostPath Mapper collects logs from tenant clusters. It works by matching virtual pod and container names to their physical names on the host and does this through symbolic links.
22+
The HostPath Mapper collects logs from tenant clusters. It works by matching virtual pod and container names to their physical names on the host through symbolic links.
2323

2424
To enable HostPath Mapper for a tenant cluster, install a DaemonSet in the same namespace. This setup works well for small environments with few nodes and tenant clusters.
2525

@@ -32,7 +32,7 @@ To use this feature, install the Central HostPath Mapper on the Control Plane Cl
3232
:::
3333

3434
:::warning Templates
35-
This feature is only configurable from the UI for tenant clusters created without a template. When using a custom template that has the feature enabled, the UI does not display the configuration in **Advanced Options** as described below. In this case, configure the feature using the CLI or by modifying the manifests.
35+
This feature is only configurable from the UI for tenant clusters created without a template. When using a custom template that has the feature enabled, the UI doesn't display the configuration in **Advanced Options** as described below. In this case, configure the feature using the CLI or by modifying the manifests.
3636
:::
3737

3838
<Tabs
@@ -45,28 +45,28 @@ This feature is only configurable from the UI for tenant clusters created withou
4545
<TabItem value="creation">
4646
<Flow id="enable-central-hpm-virtualcluster-creation">
4747
<Step>
48-
From the project drop-down menu, select the project you'd like to create
49-
the tenant cluster in.
48+
From the project drop-down menu, click the project where you want to
49+
create the tenant cluster.
5050
</Step>
5151
<Step>
52-
Click the <Button>New Tenant Cluster</Button> button above the list of tenant clusters
52+
Click the <Button>New Tenant Cluster</Button> button above the list of tenant clusters.
5353
</Step>
5454
<Step>
55-
<b>[Optional]</b> select the cluster in which to create the tenant
55+
<b>[Optional]</b> Click the cluster where you want to create the tenant
5656
cluster.
5757
</Step>
5858
<Step>
5959
Leave the <Label>Select a template</Label> section blank and click the <Button>Configure</Button> to continue.
6060
</Step>
6161
<Step>
6262
Click the <Label>Advanced Options</Label> configuration tab and expand
63-
the 'Host Path Mapper' section.
63+
the **Host Path Mapper** section.
6464
</Step>
6565
<Step>
66-
Toggle the slider <Label>Enable</Label>. This will add the
67-
'loft.sh/hpm-enabled' annotation to the template metadata which will be
68-
automatically synced to the tenant cluster on creation. Secondly, it
69-
will add `enabled: true` & `central: true` under the '[controlPlane.hostPathMapper](/docs/vcluster/configure/vcluster-yaml/control-plane/components/host-path-mapper)' field in the vcluster.yaml.
66+
Toggle the slider <Label>Enable</Label>. This adds the
67+
`loft.sh/hpm-enabled` annotation to the template metadata, which syncs
68+
automatically to the tenant cluster on creation. It also sets
69+
`enabled: true` and `central: true` under the [controlPlane.hostPathMapper](/docs/vcluster/configure/vcluster-yaml/control-plane/components/host-path-mapper) field in the vcluster.yaml.
7070
</Step>
7171
<Step>
7272
Finish configuring anything else on your tenant cluster,
@@ -78,21 +78,22 @@ This feature is only configurable from the UI for tenant clusters created withou
7878
<TabItem value="existing">
7979
<Flow id="enable-central-hpm-virtualcluster-existing">
8080
<Step>
81-
Select the project that contains the tenant cluster you want to enable Central HostPath Mapper on from the project drop-down menu.
81+
From the project drop-down menu, click the project that contains the
82+
tenant cluster where you want to enable Central HostPath Mapper.
8283
</Step>
8384
<Step>
84-
Hover over the tenant cluster you would like to enable Central HostPath Mapper on to see an <Label>Edit</Label> button displayed.
85+
Hover over the tenant cluster where you want to enable Central HostPath Mapper to reveal the <Label>Edit</Label> button.
8586
Click <Label>Edit</Label>.
8687
</Step>
8788
<Step>
8889
Click the <Label>Advanced Options</Label> configuration tab and expand
8990
the **Host Path Mapper** section.
9091
</Step>
9192
<Step>
92-
Toggle the slider <Label>Enable</Label>. This will add the
93-
'loft.sh/hpm-enabled' annotation to the template metadata which will be
94-
automatically synced to the tenant cluster on creation. Secondly, it
95-
will add `enabled: true` & `central: true` under the '[controlPlane.hostPathMapper](/docs/vcluster/configure/vcluster-yaml/control-plane/components/host-path-mapper)' field in the vcluster.yaml.
93+
Toggle the slider <Label>Enable</Label>. This adds the
94+
`loft.sh/hpm-enabled` annotation to the template metadata, which syncs
95+
automatically to the tenant cluster on creation. It also sets
96+
`enabled: true` and `central: true` under the [controlPlane.hostPathMapper](/docs/vcluster/configure/vcluster-yaml/control-plane/components/host-path-mapper) field in the vcluster.yaml.
9697
</Step>
9798
<Step>
9899
Finish configuring anything else on your tenant cluster,

platform/maintenance/monitoring/fleet-monitoring-otel.mdx

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Fleet monitoring with OpenTelemetry"
33
sidebar_label: "Fleet monitoring with OpenTelemetry"
4-
sidebar_position: 3
4+
sidebar_position: 4
55
description: "Monitor tenant clusters across shared and private nodes using OpenTelemetry Collectors with automatic label enrichment and Prometheus remote write."
66
---
77

@@ -160,7 +160,7 @@ node. The `groupbyattrs` processor splits the batch into per-pod resource scopes
160160
(by `namespace`, `pod`, `node`) so each pod is matched correctly.
161161

162162
The `k8sattributes` processor resolves vCluster identity from Platform-managed
163-
namespace labels (`loft.sh/project`, `loft.sh/vcluster-instance-name`, and others) and
163+
namespace labels (`loft.sh/project`, `loft.sh/vcluster-instance-name`, and so on) and
164164
pod labels/annotations set by the vCluster syncer
165165
(`vcluster.loft.sh/namespace`, `vcluster.loft.sh/name`).
166166

@@ -170,7 +170,7 @@ which also prevents duplicate series with any existing Prometheus scrapes.
170170

171171
### Private nodes
172172

173-
The private-nodes collector runs inside each vCluster as a DaemonSet with one
173+
The private-nodes collector runs inside each tenant cluster as a DaemonSet with one
174174
pod per node. Each pod scrapes only its local node's kubelet `/metrics`,
175175
cAdvisor `/metrics/cadvisor`, and API server `/metrics` endpoints.
176176

@@ -188,14 +188,14 @@ prometheus receiver (kubelet, cAdvisor, API server)
188188
pod vcluster_virtual_pod)
189189
```
190190

191-
Since the collector runs inside the vCluster, it can't access host-cluster
192-
namespace labels. Instead, the Platform injects `{{ .Values.loft.* }}` template
191+
Since the collector runs inside the tenant cluster, it can't access Control
192+
Plane Cluster namespace labels. Instead, the Platform injects `{{ .Values.loft.* }}` template
193193
variables at deploy time, which are set as `external_labels` on the
194-
`prometheusremotewrite` exporter. These are static per-vCluster values applied
194+
`prometheusremotewrite` exporter. These are static per-tenant-cluster values applied
195195
to all exported metrics.
196196

197197
The `metric_relabel_configs` copy `namespace` to `vcluster_virtual_namespace`
198-
and `pod` to `vcluster_virtual_pod`. Inside a private-nodes vCluster, the
198+
and `pod` to `vcluster_virtual_pod`. Inside a private-nodes tenant cluster, the
199199
`namespace` and `pod` labels already represent virtual names, so this copy
200200
ensures dashboard compatibility with the shared-nodes collector.
201201

@@ -219,7 +219,7 @@ All metrics from both apps carry a consistent set of identity labels:
219219
`vcluster_virtual_namespace` and `vcluster_virtual_pod` are missing on some
220220
metrics. These are vCluster system pods (syncer, CoreDNS) that don't have the
221221
syncer labels and annotations because they aren't user workloads synced from
222-
inside the vCluster.
222+
inside the tenant cluster.
223223
:::
224224

225225
## Prerequisites
@@ -248,7 +248,7 @@ server:
248248

249249
- kubelet scraping disabled in any existing kube-prometheus-stack to avoid
250250
duplicate cAdvisor series (`kubelet.enabled: false`).
251-
- Platform namespace labels present (added automatically by the vCluster Platform).
251+
- Platform namespace labels present (added automatically by vCluster Platform).
252252

253253
### Private nodes prerequisites
254254

@@ -593,7 +593,7 @@ spec:
593593
- **`serviceMonitorSelector: app: vcluster`**: Without filtering, the Target
594594
Allocator discovers all ServiceMonitors in the cluster, overwhelming
595595
collectors with memory pressure.
596-
- **`operator.targetallocator.mtls: true`**: Each vCluster exposes its API
596+
- **`operator.targetallocator.mtls: true`**: Each tenant cluster exposes its API
597597
server metrics over mTLS. Without this feature gate, the Target Allocator
598598
redacts TLS private keys when passing scrape configs to collectors.
599599
- **`otel/opentelemetry-collector-contrib` image**: The default image doesn't
@@ -622,7 +622,7 @@ kubectl apply -f otel-collector-shared-nodes-app.yaml
622622
Navigate to the <NavStep>Apps</NavStep> tab.
623623
</Step>
624624
<Step>
625-
Click <Button>Install App</Button> and select the
625+
Click <Button>Install App</Button> and click the
626626
**OTEL Collector - Shared Nodes** app.
627627
</Step>
628628
<Step>
@@ -645,7 +645,7 @@ Repeat these steps for each Control Plane Cluster.
645645
## Deploy the private nodes collector
646646
<!-- vale on -->
647647

648-
Deploy one private-nodes collector into each private-nodes vCluster. All
648+
Deploy one private-nodes collector into each private-nodes tenant cluster. All
649649
vCluster identity labels are injected automatically by the Platform using
650650
`{{ .Values.loft.* }}`.
651651

@@ -889,7 +889,7 @@ spec:
889889
ensures one collector per node, scraping only the local kubelet and cAdvisor
890890
using `${env:K8S_NODE_NAME}` filtering. No Target Allocator is needed.
891891
- **`external_labels` instead of `k8sattributes` for identity**: The collector
892-
runs inside the vCluster, so it can't access Control Plane Cluster namespace labels.
892+
runs inside the tenant cluster, so it can't access Control Plane Cluster namespace labels.
893893
The Platform injects `{{ .Values.loft.* }}` template variables at deploy time.
894894
- **`resource_to_telemetry_conversion: false`**: Setting this to `true` causes
895895
duplicate labels that break Grafana dashboards.
@@ -916,7 +916,7 @@ kubectl apply -f otel-collector-private-nodes-app.yaml
916916
Go to the <NavStep>Projects</NavStep> section using the menu on the left.
917917
</Step>
918918
<Step>
919-
Select the project containing your private-nodes tenant cluster.
919+
Click the project containing your private-nodes tenant cluster.
920920
</Step>
921921
<Step>
922922
Click on the tenant cluster, then navigate to the <NavStep>Config</NavStep>
@@ -1215,7 +1215,8 @@ with the event rate.
12151215

12161216
:::note
12171217
This section assumes Grafana is already deployed. For setup instructions, see
1218-
[Aggregating Metrics Deploy Grafana](./aggregating-metrics.mdx#deploy-grafana).
1218+
the [Deploy Grafana](./aggregating-metrics.mdx#deploy-grafana) section in
1219+
Aggregating Metrics.
12191220
:::
12201221

12211222
Two Grafana dashboards are provided for visualizing metrics collected by the
@@ -1234,14 +1235,12 @@ time, so all panels use straightforward PromQL queries without joins.
12341235
### vCluster projects dashboard
12351236
<!-- vale on -->
12361237

1237-
A platform admin overview of vCluster projects across shared and private node
1238-
tenant clusters. Use this dashboard to monitor resource consumption and API health at
1239-
the project level.
1238+
A platform admin overview of vCluster projects across Shared Nodes and Private
1239+
Nodes tenant clusters. Use this dashboard to monitor resource consumption and
1240+
API health at the project level.
12401241

12411242
**Dashboard JSON file:** [Download dashboard JSON](/media/dashboards/vcluster-projects.json)
12421243

1243-
1244-
12451244
**Template variables:**
12461245

12471246
| Variable | Description |
@@ -1255,8 +1254,8 @@ the project level.
12551254
<!-- vale off -->
12561255
| Section | Panels |
12571256
|---------|--------|
1258-
| Project summary | Total Projects, Total vClusters, Total Pods, Total CPU (cores), Total Memory, Max Error Rate (stat panels) |
1259-
| Resource usage by project | CPU by Project (cores), Memory by Project, Pods by Project, vClusters by Project (bar charts) |
1257+
| Project summary | Total Projects, Total tenant clusters, Total Pods, Total CPU (cores), Total Memory, Max Error Rate (stat panels) |
1258+
| Resource usage by project | CPU by Project (cores), Memory by Project, Pods by Project, Tenant clusters by Project (bar charts) |
12601259
| API health by project | API Request Rate, API Error Rate (5xx), API P95 Latency (time series) |
12611260
| Resource trends | CPU Usage Trend (stacked), Memory Usage Trend (stacked) (time series) |
12621261
<!-- vale on -->

0 commit comments

Comments
 (0)