Host Monitoring
Monitor Linux and Windows virtual machines with the OpenTelemetry Collector — CPU, memory, disk and processes, plus OS, kernel, architecture and cloud details you can filter by.
KubeSense monitors virtual machines and bare-metal hosts outside Kubernetes through the OpenTelemetry Collector (otelcol-contrib) running on each host. The collector reports host metrics to KubeSense, and the hosts appear under Infrastructure → VM.
For each host you get:
- Usage — CPU, memory and disk, with charts over time
- Processes — the processes running on the host
- System details — OS, OS version, kernel (the build number on Windows), architecture and CPU model
- Cloud details — provider, region, availability zone, account, instance type and, on Azure, VM size and resource group
Every system and cloud detail is also a filter, so you can narrow the host list to, for example, all Windows Server 2022 hosts in eastus2, or every host still on a particular kernel.
How it works
The collector's hostmetrics receiver scrapes the host's CPU, memory, disk, filesystem and network. Its resourcedetection processor works out what the host is (OS, architecture, cloud instance) and attaches that to every metric as resource attributes. KubeSense receives the metrics over Prometheus remote write, where resource_to_telemetry_conversion turns those attributes into labels, and builds the host list, its filters and the host details from them.
Two resource attributes place the host in KubeSense:
| Attribute | Purpose |
|---|---|
kubesense.cluster | The domain the host belongs to. Hosts are grouped and selected by domain. |
kubesense.env_type | Must be legacy for VM hosts. |
Setup
Step 1: Create a domain
In Settings → Domain, create a domain with environment type Legacy (the type for VM hosts). Its name must match the kubesense.cluster value you set in the collector config below. The VM explorer only lists hosts from the domains you select, so a host whose domain does not exist will not appear.
Step 2: Install the OpenTelemetry Collector
Install the contrib distribution of the collector (otelcol-contrib), version 0.120.0 or later, from the OpenTelemetry Collector releases. On Linux use the .deb or .rpm package; on Windows use the .msi, which installs the otelcol-contrib service. Either way the collector runs as a service.
Step 3: Configure the collector
Replace the collector's config file with the one for your OS, then set:
<KUBESENSE_ENDPOINT>— your KubeSense ingest address<DOMAIN>— the domain name from Step 1
Config file: /etc/otelcol-contrib/config.yaml
receivers:
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
memory:
disk:
filesystem:
network:
load:
paging:
processes:
process:
mute_process_all_errors: true
processors:
memory_limiter:
check_interval: 1s
limit_mib: 400
spike_limit_mib: 100
# Places the host in KubeSense.
resource/kubesense:
attributes:
- key: kubesense.cluster
value: "<DOMAIN>"
action: upsert
- key: kubesense.env_type
value: legacy
action: upsert
# Works out what the host is. Runs after resource/kubesense with
# override: false, so it only fills in what is not already set.
resourcedetection:
# Keep the detector for your cloud (ec2, azure or gcp); drop the others.
detectors: [env, ec2, azure, gcp, system]
timeout: 5s
override: false
system:
hostname_sources: [os]
# Off by default — enable them for the OS version, kernel,
# architecture and CPU model in KubeSense.
resource_attributes:
os.description:
enabled: true
host.arch:
enabled: true
host.cpu.model.name:
enabled: true
host.cpu.vendor.id:
enabled: true
batch:
timeout: 10s
exporters:
prometheusremotewrite/kubesense:
endpoint: http://<KUBESENSE_ENDPOINT>:30060/api/v1/write
timeout: 30s
send_metadata: true
# Turns the resource attributes above into labels KubeSense filters by.
resource_to_telemetry_conversion:
enabled: true
retry_on_failure:
enabled: true
service:
pipelines:
metrics:
receivers: [hostmetrics]
processors: [memory_limiter, resource/kubesense, resourcedetection, batch]
exporters: [prometheusremotewrite/kubesense]Validate the file, then restart the service:
sudo otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
sudo systemctl restart otelcol-contribConfig file: C:\Program Files\OpenTelemetry Collector\config.yaml
receivers:
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
memory:
disk:
filesystem:
exclude_mount_points:
mount_points: ['A:\*', 'B:\*']
match_type: regexp
network:
paging:
process:
mute_process_all_errors: true
processors:
memory_limiter:
check_interval: 1s
limit_mib: 400
spike_limit_mib: 100
# Places the host in KubeSense.
resource/kubesense:
attributes:
- key: kubesense.cluster
value: "<DOMAIN>"
action: upsert
- key: kubesense.env_type
value: legacy
action: upsert
# Works out what the host is. Runs after resource/kubesense with
# override: false, so it only fills in what is not already set.
resourcedetection:
# Keep the detector for your cloud (ec2, azure or gcp); drop the others.
detectors: [env, ec2, azure, gcp, system]
timeout: 5s
override: false
system:
hostname_sources: [os]
# Off by default — enable them for the OS version, build number,
# architecture and CPU model in KubeSense.
resource_attributes:
os.description:
enabled: true
host.arch:
enabled: true
host.cpu.model.name:
enabled: true
host.cpu.vendor.id:
enabled: true
batch:
timeout: 10s
exporters:
prometheusremotewrite/kubesense:
endpoint: http://<KUBESENSE_ENDPOINT>:30060/api/v1/write
timeout: 30s
send_metadata: true
# Turns the resource attributes above into labels KubeSense filters by.
resource_to_telemetry_conversion:
enabled: true
retry_on_failure:
enabled: true
service:
pipelines:
metrics:
receivers: [hostmetrics]
processors: [memory_limiter, resource/kubesense, resourcedetection, batch]
exporters: [prometheusremotewrite/kubesense]From an elevated PowerShell, validate the file, then restart the service:
& "C:\Program Files\OpenTelemetry Collector\otelcol-contrib.exe" validate --config "C:\Program Files\OpenTelemetry Collector\config.yaml"
Restart-Service otelcol-contribNote: Save the file as UTF-8 without a byte-order mark. Notepad on older Windows versions adds one, and the collector then fails to parse the first key.
Already running a collector?: If your hosts already run an OpenTelemetry Collector that sends metrics to KubeSense, you only need to add the system.resource_attributes block to its existing resourcedetection processor, and make sure its Prometheus remote write exporter has resource_to_telemetry_conversion enabled. Nothing else changes.
Step 4: Verify
Open Infrastructure → VM, select your domain, and the host should appear within a minute. Open it to check that the System and Cloud panels show its details.
Host details
Host list
| Column | Description |
|---|---|
| Name | Host name |
| CPU | CPU usage against the host's cores |
| Memory | Memory usage against the host's total memory |
| Domain | Domain the host reports to (kubesense.cluster) |
| OS | OS version, e.g. Ubuntu 24.04.5 LTS (Noble Numbat) or Windows Server 2022 Datacenter 21H2; the OS type when the version is not reported |
| Kernel | Kernel release on Linux, build number on Windows |
| Arch | CPU architecture, e.g. amd64, arm64 |
| Cloud | Cloud provider and region, e.g. Azure · eastus2 |
| Instance Type | AWS / GCP instance type, or Azure VM size |
| Processes | Number of running processes |
Filters
Each of these appears as a section in the filter sidebar, with the number of hosts for each value, and can be typed in the search bar as field:value. A section is only shown when at least one host reports that field.
| Filter | Shows | Collector attribute |
|---|---|---|
os | linux, windows, … | os.type |
os_version | Ubuntu 22.04.3 LTS, Windows Server 2022 Datacenter 21H2, … | parsed from os.description |
kernel | Linux kernel release, or Windows build number | parsed from os.description |
arch | amd64, arm64, … | host.arch |
cpu_model | Intel(R) Xeon(R) Platinum 8370C, … | host.cpu.model.name |
cloud_provider | aws, azure, gcp | cloud.provider |
cloud_platform | aws_ec2, azure.vm, gcp_compute_engine | cloud.platform |
cloud_region | us-east-1, eastus2, … | cloud.region |
cloud_availability_zone | us-east-1a, … | cloud.availability_zone |
cloud_account_id | Cloud account / subscription ID | cloud.account.id |
instance_type | AWS / GCP instance type, e.g. m5.large | host.type |
azure_vm_size | Azure VM size, e.g. Standard_D4ds_v5 | azure.vm.size |
resource_group | Azure resource group | azure.resourcegroup.name |
Host drawer
Opening a host shows its CPU, memory, disk and process charts, followed by two panels:
- System — OS, OS version, kernel version (Build on Windows), architecture, CPU model and host ID
- Cloud — provider, platform, region, availability zone, account, instance type or VM size, resource group and image ID
Troubleshooting
The host does not appear. Check that a domain with the same name as kubesense.cluster exists with environment type Legacy and is selected, and that kubesense.env_type is legacy. Then check that the host can reach <KUBESENSE_ENDPOINT> on port 30060: the collector retries silently when it cannot, which looks the same as no data.
OS version, kernel, architecture or CPU model are empty. The system.resource_attributes block is missing or not enabled. These attributes are off by default in the collector.
Cloud fields are empty. The cloud detector cannot reach the instance metadata service. On AWS, if IMDSv2 is enforced, the metadata hop limit must allow the collector to reach it. Also check that the detector for your cloud (ec2, azure or gcp) is in detectors.
A Windows 11 host. Windows 11 still reports itself as "Windows 10" to software that reads its version. KubeSense shows it as Windows 11, based on the build number (22000 or later).
The architecture looks wrong on Windows on ARM. host.arch reports the architecture of the collector binary. An x64 collector running under emulation on an ARM machine reports amd64.