Kubesense

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:

AttributePurpose
kubesense.clusterThe domain the host belongs to. Hosts are grouped and selected by domain.
kubesense.env_typeMust 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-contrib

Config 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-contrib

Note: 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

ColumnDescription
NameHost name
CPUCPU usage against the host's cores
MemoryMemory usage against the host's total memory
DomainDomain the host reports to (kubesense.cluster)
OSOS 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
KernelKernel release on Linux, build number on Windows
ArchCPU architecture, e.g. amd64, arm64
CloudCloud provider and region, e.g. Azure · eastus2
Instance TypeAWS / GCP instance type, or Azure VM size
ProcessesNumber 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.

FilterShowsCollector attribute
oslinux, windows, …os.type
os_versionUbuntu 22.04.3 LTS, Windows Server 2022 Datacenter 21H2, …parsed from os.description
kernelLinux kernel release, or Windows build numberparsed from os.description
archamd64, arm64, …host.arch
cpu_modelIntel(R) Xeon(R) Platinum 8370C, …host.cpu.model.name
cloud_provideraws, azure, gcpcloud.provider
cloud_platformaws_ec2, azure.vm, gcp_compute_enginecloud.platform
cloud_regionus-east-1, eastus2, …cloud.region
cloud_availability_zoneus-east-1a, …cloud.availability_zone
cloud_account_idCloud account / subscription IDcloud.account.id
instance_typeAWS / GCP instance type, e.g. m5.largehost.type
azure_vm_sizeAzure VM size, e.g. Standard_D4ds_v5azure.vm.size
resource_groupAzure resource groupazure.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.