Kubesense

Configuration

Synthetic Monitoring works with the defaults from Deployment. This page lists the settings you can change: the Helm values of the KubeSense chart, extra synthetics-api settings, and the settings of agents you run in your own locations.

Settings that users change in the web app (monitor defaults, variables, tag rules) are described in Settings.


Helm Values

All values sit under the top-level synthetics: block of the kubesense (or kubesense-server) chart. Apply changes with helm upgrade and the same values files.

General

ValueDefaultDescription
synthetics.enabledfalseDeploys Synthetic Monitoring and shows the Synthetics pages
synthetics.editionbasicThe installation's edition
synthetics.existingSecret""A Secret you manage, with SYNTHETICS_API_TOKEN, SYNTHETICS_AGENT_TOKEN and SYNTHETICS_SECRET_KEYS. Nothing is generated when it is set
synthetics.secret.apiTokengeneratedToken the KubeSense API presents to synthetics-api
synthetics.secret.agentTokengeneratedToken agents register with
synthetics.secret.secretKeysgeneratedKey ring that encrypts stored secrets (see Secrets key)

synthetics-api

ValueDefaultDescription
synthetics.api.replicaCount1API replicas. Replicas elect a leader for scheduling and alerting, so more than one adds availability
synthetics.api.image.tagrelease versionImage tag of synthetics/api
synthetics.api.port8080Service port
synthetics.api.alertingModeplatformplatform: monitor alerts go through KubeSense alert rules and notification channels. Keep it on platform
synthetics.api.dashboardUrlhttps://<global.dashboardHostName>Base URL that alert notifications link to
synthetics.api.agentHelmRepohttps://helm.kubesense.aiHelm repository used in the install commands shown for a location
synthetics.api.mysql.hostbundled MySQLhost, port, database (synthetics) and username of the control-plane database. Empty uses the bundled MySQL or global.externalMySQL
synthetics.api.clickhouse.hostbundled ClickHousehost, port and username of the ClickHouse that holds run results (in kube_synthetics). Empty uses the bundled ClickHouse or the external one. database (synthetics) names the results database of releases before this one, copied once after the upgrade
synthetics.api.remoteWriteUrlbundled metrics storeRemote-write URL for the kubesense_synthetics_* series
synthetics.api.configFile{}Extra settings, see synthetics-api settings
synthetics.api.env{}Extra environment variables
synthetics.api.resources250m / 1 CPU, 256 / 512 MiBRequests and limits
synthetics.api.nodeSelector, tolerations, affinity, podAnnotationsemptyPod placement and annotations

Database passwords come from the release's existing secrets; you do not set them here.

In-cluster location and agents

ValueDefaultDescription
synthetics.location.idin-clusterLocation the in-cluster agents register into. Created on first start if it does not exist
synthetics.location.nameIn-clusterDisplay name of that location
synthetics.location.regionprivateRegion label of that location
synthetics.agent.enabledtrueDeploys the in-cluster agents
synthetics.agent.replicaCount2Agents in the location. The agents share the location's monitors, so two agents on different nodes keep checks running when one goes down, and more replicas add capacity
synthetics.agent.workers100Checks one agent runs at the same time
synthetics.agent.persistence.enabledfalseA volume per agent for queued results (kept while synthetics-api is unreachable, and across restarts) and its registration. Changing it later needs the StatefulSet recreated: kubectl delete statefulset kubesense-synthetics-agent --cascade=orphan, then helm upgrade
synthetics.agent.persistence.size / storageClass1Gi / defaultVolume size and storage class
synthetics.agent.labels{}Agent labels, used to target agents from a monitor
synthetics.agent.resources100m / 500m CPU, 128 / 256 MiBRequests and limits
synthetics.agent.env, nodeSelector, tolerations, affinity, podAnnotationsemptyExtra environment and pod placement

The in-cluster agents have no access to the Kubernetes API. To run Kubernetes resource checks, install a separate agent with the synthetics-agent chart and k8sChecks=true (see Agents in your own locations).

Browser agents

ValueDefaultDescription
synthetics.browserAgent.enabledfalseDeploys agents with headless Chromium for browser tests
synthetics.browserAgent.replicaCount1Browser agents
synthetics.browserAgent.concurrency2Browser tests one agent runs at the same time. Each needs about 800m CPU and 1 GiB
synthetics.browserAgent.tmpSizeLimit1GiIn-memory /tmp for the browser profiles
synthetics.browserAgent.persistence.*disabledAs for synthetics.agent.persistence
synthetics.browserAgent.resources1.7 / 2.5 CPU, 2.25 / 3 GiBRequests and limits. Raise them together with concurrency

Agent ingress

Agents outside the cluster reach synthetics-api through this Ingress. It routes only the agent endpoints (/api/v1/probes/* and /healthz); users always go through the KubeSense API.

ValueDefaultDescription
synthetics.agentIngress.enabledfalseCreates the Ingress. When enabled, the install commands shown for a location point new agents at it
synthetics.agentIngress.classNameglobal.ingress.classNameIngress class
synthetics.agentIngress.hostglobal.dashboardHostNameHost name. Empty serves the agent paths beside the dashboard
synthetics.agentIngress.annotations{}Ingress annotations
synthetics.agentIngress.tls.enabledglobal.ingress.tls.enabledTLS
synthetics.agentIngress.tls.secretNameglobal.ingress.tls.secretNameTLS Secret. Required with a host of its own
synthetics:
  agentIngress:
    enabled: true
    host: synthetics-agents.example.com
    tls:
      enabled: true
      secretName: synthetics-agents-tls

synthetics-api Settings

Settings the chart does not expose go in synthetics.api.configFile (Kubernetes) or in synthetics-api.yaml (VM). Keys are snake_case; durations use s, m and h (720h is 30 days). An unknown key or a value of the wrong type stops synthetics-api at startup, and its log says which key.

synthetics:
  api:
    configFile:
      min_interval: 30s
      incident_retention: 4320h   # 180 days
      alert_event_retention: 720h  # 30 days
# common/config/synthetics/synthetics-api.yaml
listen_port: 8080
# ... mysql, clickhouse and remote_write as in Deployment
min_interval: 30s
incident_retention: 4320h   # 180 days
alert_event_retention: 720h  # 30 days
KeyDefaultDescription
min_interval10sShortest interval a monitor may run at (10s to 7d)
max_monitors0Most monitors that can be stored (0 = no limit)
max_locations_per_monitor0Most locations one monitor may pick (0 = no limit)
max_concurrent_on_demand20On-demand runs (Run now, Test) at the same time; more are refused until one finishes. Scheduled runs are never limited
max_multistep_steps10Most steps in a multistep API test (at most 25)
incident_retention8760h (365 days)How long resolved outages are kept
alert_event_retention2160h (90 days)How long alert events are kept
batch_retention720h (30 days)How long CI batches and their runs are kept
monitor_version_retention2160h (90 days)How long saved monitor versions are kept; the newest 20 of each monitor always are
remote_write.labels[service, env, team]Monitor tags copied onto the kubesense_synthetics_* series as label_<key>, at most 5. Use them to filter dashboards and alerts by tag
min_agent_version""Agents older than this version are marked outdated on the Locations page
drain_timeout10sOn shutdown, how long running checks get to finish
evaluation_workers8Parallel result evaluation. Raise only for very large numbers of monitors
probe_offline_after45sAn agent silent this long is marked offline and its monitors move to the location's other agents. See Handover
nodata_sweep15sHow often offline agents and monitors without results are looked for

Run history in ClickHouse is kept for 30 days, uptime for 365 days, failure snapshots for 7 days and browser screenshots for 14 days. Change them under Settings → Data Retention (group Synthetics). The retention settings above (outages, alert events, CI batches, monitor versions) are synthetics-api's own clean-up of its MySQL database, once a day; they are set here, not on that page.


Agents in Your Own Locations

Agents in another cluster or on a VM are installed with the command a location shows (see Locations & Agents). The command sets the API address, location and token; add the settings below to it as needed.

Values of the synthetics-agent chart (--set or a values file):

ValueDefaultDescription
replicaCount1Agents in this installation. The agents of a location share its monitors; run two for availability
imagePullSecrets[]Pull access to the KubeSense registry, e.g. [{name: registry-credentials}]
agent.apiEndpointset by the commandsynthetics-api address (the agent ingress)
agent.locationset by the commandLocation id the agent registers into
agent.name / agent.regionpod name / privateDisplay name and region label
agent.labels{}Agent labels, used to target agents from a monitor
agent.detectCloudtrueReads the cloud provider and region from the instance metadata, which places the agent on the map
agent.workers100Checks one agent runs at the same time
agent.syncInterval / agent.heartbeatInterval30s / 15sHow often the agent fetches its checks / reports that it is alive. See Handover
agent.spoolDir / agent.spoolMaxmemory / 10000Where results wait while synthetics-api is unreachable, and how many
agent.proxy.bypass[]Hosts reached without the proxy (NO_PROXY syntax). The proxy URL itself goes in secrets.proxyUrl
agent.dns.useHost / agent.dns.serverstrue / []Use the node's resolver, with servers (ip[:port]) as fallback; useHost: false uses only servers
agent.egress.allowedDomains / blockedDomains[]Only these domains may be checked / never these (blocked wins)
agent.egress.allowedIpRanges / blockedIpRanges[]IP ranges re-allowed / never reached
agent.enableIpv6truefalse = IPv4 only
agent.maxBodySize5242880Response body bytes read for assertions (at most 50 MiB)
agent.customCA.secretName / configMapName""Extra root CAs (*.pem, *.crt, *.cer keys) trusted by HTTP, WebSocket, gRPC, TCP-TLS, DNS-over-TLS/HTTPS and SSL checks
secrets.token / secrets.existingSecretset by the commandRegistration token, or a Secret holding SYNTHETICS_AGENT_TOKEN
secrets.proxyUrl""Proxy for HTTP, WebSocket and gRPC checks, e.g. http://user:pass@proxy.corp:3128
enableICMPfalseAdds CAP_NET_RAW, needed for ICMP ping checks
networkPath.rawSocketfalseRouter identification and UDP/ICMP paths in network path checks (adds CAP_NET_RAW, runs as root with every other capability dropped)
k8sChecksfalseKubernetes resource checks: adds a read-only ClusterRole
k8sCustomResources[]Custom resources Kubernetes checks may read, e.g. [{apiGroup: cert-manager.io, resources: [certificates]}]
browser.enabledfalseBrowser agent (headless Chromium) instead of the standard agent
browser.concurrency2Browser tests at the same time (about 800m CPU and 1 GiB each)
resources / browser.resources100m / 500m CPU, 128 / 256 MiBRequests and limits
configFile{}Any other agent setting, as snake_case keys

Agent flags. Each also works as a snake_case key of a config file passed with -config.

FlagDefaultDescription
-api—synthetics-api address (the agent ingress or reverse proxy)
-location—Location id the agent registers into
-token / SYNTHETICS_AGENT_TOKEN—Registration token. Prefer the environment variable
-token-file—Keeps the agent's registration in a file so a restart is back at once. Put it on a volume
-id / -name / -region / -labels k=v,k=vgeneratedIdentity and labels
-workers100Checks at the same time
-sync / -heartbeat30s / 15sCheck fetch / alive report interval
-spool-dir / -spool-maxmemory / 10000Where results wait while synthetics-api is unreachable, and how many
-proxy-url / -proxy-bypass—Proxy for HTTP, WebSocket and gRPC checks / hosts reached without it
-dns-server / -dns-use-host— / trueResolvers for check targets
-allowed-domains / -blocked-domains—Domain rules (blocked wins)
-allowed-ip-ranges / -blocked-ip-ranges—IP range rules
-enable-ipv6truefalse = IPv4 only
-max-body-size5 MiBResponse body bytes read for assertions
-ca-dir—Directory of extra root CAs
-browser / -browser-concurrency / -chrome-no-sandboxoff / 2 / offBrowser agent (use the synthetics/browser-agent image)
-drain-timeout10sOn shutdown, how long running checks get to finish
-metrics-addr:9090/healthz and Prometheus /metrics

ICMP ping checks need the NET_RAW capability (--cap-add NET_RAW with Docker).


Handover

When an agent goes offline, its monitors move to the other agents of its location (see Availability). An agent that stops is offline at once, and its monitors move within one check sync, about 30 seconds. An agent that dies is noticed only by its silence: its monitors move within probe_offline_after + nodata_sweep + the agents' check sync, about 30–90 seconds with the defaults. Lower settings shorten the gap at the cost of more requests to synthetics-api:

SettingWhereDefaultLower means
probe_offline_aftersynthetics.handover.offlineAfter (Kubernetes) or synthetics-api settings45sA dead agent is offline sooner. Agents automatically heartbeat at least every third of it, so lowering it never marks live agents offline
nodata_sweepsynthetics.handover.sweep (Kubernetes) or synthetics-api settings15sOffline agents are found sooner
Check syncsynthetics.handover.sync (in-cluster agents), agent.syncInterval (synthetics-agent chart) or -sync (Docker / binary)30sMonitors move sooner after any handover

For example, probe_offline_after: 15s, nodata_sweep: 5s and agents at a 10s check sync bring the handover after a crash to about 15–30 seconds.

synthetics:
  handover:
    offlineAfter: 15s
    sweep: 5s
    sync: 10s   # in-cluster agents; set agent.syncInterval on agents of other locations

For no gap at all, turn on Run every monitor on every agent for the location.


Secrets Key

SYNTHETICS_SECRET_KEYS encrypts secure variables and monitor credentials at rest. Its format is kid:base64key[,kid:base64key] with 32-byte keys (openssl rand -base64 32). The first key encrypts; every key in the list decrypts.

To rotate the key:

  1. Put a new key first and keep the old one after it, e.g. k2:<new>,k1:<old>, and restart synthetics-api. New secrets are encrypted with k2; old ones still decrypt with k1.

  2. Re-encrypt the stored secrets once. Run the synthetics-api binary with -rotate-secrets and the same database settings and key list as the running service:

    # The pod already has the passwords and keys in its environment;
    # copy the --mysql-* arguments from: kubectl -n kubesense get deploy kubesense-synthetics-api -o yaml
    kubectl -n kubesense exec deploy/kubesense-synthetics-api -- \
      /usr/local/bin/synthetics-api --mysql-host=<host> --mysql-username=<user> -rotate-secrets
    docker compose run --rm synthetics-api -config /etc/synthetics/synthetics-api.yaml -rotate-secrets

    It logs how many secrets it re-encrypted and exits with code 1 if one could not be decrypted.

  3. Remove the old key from the list and restart synthetics-api.

Losing every key in use makes the stored secrets unreadable: re-enter them in the monitors and variables that use them.