Docs
Kubernetes

Getting Started

Public Preview

The Kubernetes integration is currently in public preview and is not yet generally available. Contact support@netboxlabs.com to join the preview.

This guide walks you through setting up the Kubernetes Integration for NetBox.


Prerequisites

Before you begin, ensure you have the following:

  • NetBox Cloud or NetBox Enterprise with NetBox Assurance
  • Orb Agent Pro credentials (required to download the integration agent image)
  • A Kubernetes cluster running upstream (vanilla) Kubernetes. OpenShift and other distributions are not supported in this release
  • kubectl access to the cluster with permission to create a service account, a cluster role, and a cluster role binding
  • Host system with Docker support
  • Network connectivity between your host and both your NetBox instance and the cluster's API server

Decide two settings before the first run

NODE_OBJECT_TYPE (whether nodes become devices or virtual machines) and SITE_NAME (which site node devices are placed in) are hard to change after the first run. Read Choosing a node object type and site before you configure the agent.

Host Requirements

System

  • Operating System: Linux, macOS, or Windows with Docker support
  • Memory: Minimum 2 GB RAM (4 GB recommended)
  • Storage: 1 GB free disk space
  • Docker: Version 20.10 or later

Network

  • Outbound gRPC/gRPCS access to Diode on your NetBox instance (typically port 443 for gRPCS)
  • Outbound HTTPS access to the cluster's API server, on the port in its URL (commonly 6443)
  • DNS resolution for both NetBox and the API server hostname, if you use one
  • Firewall rules configured to allow the above connections from your agent host

If the agent host reaches the API server through a proxy, pass HTTPS_PROXY (and NO_PROXY if needed) to the agent container. There is no proxy setting in the agent configuration.


Kubernetes Setup

Create a service account and token

The integration reads the cluster with a service account that can only get and list nodes, namespaces, services, and service CIDRs. It cannot read pods or secrets.

  1. Create a manifest named nbl-kubernetes-rbac.yaml with the following content:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nbl-kubernetes
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nbl-kubernetes
rules:
  - apiGroups: [""]
    resources: ["nodes", "namespaces", "services"]
    verbs: ["get", "list"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["servicecidrs"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nbl-kubernetes
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nbl-kubernetes
subjects:
  - kind: ServiceAccount
    name: nbl-kubernetes
    namespace: default
  1. Apply it to the cluster:
kubectl apply -f nbl-kubernetes-rbac.yaml
  1. Create a token for the service account. Choose the option that suits how you will run the agent.

For testing, create a short-lived token:

kubectl create token nbl-kubernetes --duration=1h

A token created this way expires after the duration you request, and the API server may limit the maximum duration. When it expires, the integration can no longer read the cluster.

For a scheduled agent, create a long-lived token stored in a Secret. Create a manifest named nbl-kubernetes-token.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: nbl-kubernetes-token
  namespace: default
  annotations:
    kubernetes.io/service-account.name: nbl-kubernetes
type: kubernetes.io/service-account-token

Apply it, then read the token that Kubernetes generates in the Secret:

kubectl apply -f nbl-kubernetes-token.yaml
kubectl get secret nbl-kubernetes-token -n default -o jsonpath='{.data.token}' | base64 -d

Long-lived tokens do not expire

A token stored in a Secret stays valid until you delete the Secret. Make sure this meets your security policy, and store the token securely. To revoke it, delete the Secret. See Manually create an API token for a ServiceAccount in the Kubernetes documentation.

Copy the token. You will use it as K8S_TOKEN.

If your security policy does not allow the services or servicecidrs permission, you can leave either out. The sync still runs, without LoadBalancer service addresses or service prefixes respectively. See Authentication and Permissions for what each permission provides.

Get the API server URL and CA certificate

  1. Get the API server URL for your current kubectl context. You will use it as K8S_API_URL:
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
  1. Save the cluster's CA certificate to a file in the directory you will run the agent from:
kubectl config view --raw --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \
  | base64 -d > cluster-ca.pem

The API server's certificate is normally signed by this CA, which the agent host does not trust by default. The agent needs it to verify the connection. If your kubeconfig points to a CA file (certificate-authority) instead of embedding the certificate, copy that file to cluster-ca.pem.


NetBox Setup

Generate Diode Client Credentials

  1. Log in to your NetBox instance.
  2. Navigate to Diode → Client Credentials.
  3. Click + Add a Credential.
  4. Enter a descriptive name (for example, "Kubernetes Integration").
  5. Click Create.

Add a Diode client credential

  1. Important: Copy and securely store the Client ID and Client Secret - you will need them in the agent configuration.

Copy the client ID and secret

  1. Navigate to Diode → Settings.
  2. Copy the Diode target value - you will use this in the agent configuration file.

Copy the Diode target


Agent Setup and Configuration

You can sync several clusters, each with its own policy. Give each cluster a different CLUSTER_NAME.

Step 1: Authenticate to the NetBox Labs Image Registry

From your host machine, authenticate to the NetBox Labs registry using the CUSTOMER-IDENTIFIER and token provided by the NetBox Labs team:

docker login quay.io -u netboxlabs+<CUSTOMER-ID> -p <TOKEN>

Example session:

% docker login quay.io -u netboxlabs+org-abc123def456 -p <token>
Login Succeeded

Then pull the agent image:

docker pull quay.io/netboxlabs/orb-agent-pro:develop

Step 2: Configure the Agent

  1. Create the configuration file in the same directory as cluster-ca.pem (you can name the file anything you like):
touch agent.yaml
  1. Edit the configuration file and add the following. Replace grpcs://your-instance.netboxcloud.com/diode with the value from Diode → Settings → Diode target in the NetBox UI:
orb:
  config_manager:
    active: local
  backends:
    worker:
    common:
      diode:
        target: grpcs://your-instance.netboxcloud.com/diode # Get this value from Diode > Settings > Diode target
        client_id: ${DIODE_CLIENT_ID}
        client_secret: ${DIODE_CLIENT_SECRET}
        agent_name: kubernetes_01  # Use a meaningful name to identify this agent
  policies:
    worker:
      kubernetes_worker:
        config:
          package: nbl_kubernetes
          schedule: "0 2 * * *" # Daily at 2:00 AM. Set your desired schedule (see examples below)
          K8S_API_URL: ${K8S_API_URL}
          K8S_TOKEN: ${K8S_TOKEN}
          K8S_CA_CERT: ${K8S_CA_CERT}  # Path to the cluster's CA certificate inside the container
          CLUSTER_NAME: prod-east      # Name of the cluster in NetBox. Use a different name for each cluster
          NODE_OBJECT_TYPE: device     # "device" or "virtual_machine". Decide before the first run (see below)
          SITE_NAME: Kubernetes        # Site for node devices. Required when NODE_OBJECT_TYPE is device
          BOOTSTRAP: True  # Set to True for initial setup, False for regular operation
          # SKIP_SSL: false  # Optional: set to true to skip TLS verification, and remove K8S_CA_CERT (default: false)
        scope:
          # node_labels: "hardware=baremetal"  # Optional: Kubernetes label selector to limit which nodes are synced (default: all nodes)

Set NODE_OBJECT_TYPE and SITE_NAME deliberately

  • NODE_OBJECT_TYPE - use device for bare-metal nodes and virtual_machine for nodes that are virtual machines. Changing it later leaves every record written under the previous type in NetBox.
  • SITE_NAME - in device mode, if this site already holds devices with the same names as your nodes, the integration updates those devices instead of creating new ones. It is not used in virtual_machine mode.

See Choosing a node object type and site.

Environment variables

Every ${VARIABLE} in the configuration must be set in the agent container's environment. An unset variable is passed to the integration as the literal text, such as ${K8S_CA_CERT}, and the run fails. If you set SKIP_SSL: true instead of using a CA certificate, remove the K8S_CA_CERT line.

K8S_CA_CERT can be a path to the CA file inside the container, or the PEM-encoded certificate itself.

Schedule Examples

The schedule field uses cron syntax. Common examples:

  • "*/30 * * * *" - Every 30 minutes
  • "0 * * * *" - Every hour
  • "0 */6 * * *" - Every 6 hours
  • "0 2 * * *" - Daily at 02:00

Scope Configuration

The scope section limits which nodes are synced. Configure it under a scope key in the policy, separate from config.

  • node_labels - a Kubernetes label selector, written as a single string. Only nodes matching the selector are synced. It uses the same syntax as kubectl get nodes -l, and comma-separated conditions must all match. Omit it to sync all nodes.

Example:

scope:
  node_labels: "hardware=baremetal,kubernetes.io/arch=arm64"

A selector that matches no nodes fails the run, and the error lists the label keys present on the cluster's nodes. Test your selector first with kubectl get nodes -l "<selector>". See scope Parameters for details.

Bootstrap Mode (First-Time Setup)

Bootstrap mode creates the static content in NetBox that the integration requires before the first full sync. Run it once on initial setup, then disable it for all subsequent runs. In bootstrap mode the integration makes no Kubernetes API calls, so the token and API server URL are not required.

What bootstrap mode creates:

  • Tags: kubernetes, discovered
  • Custom fields: nbl_matching_id, k8s_system_uuid, k8s_provider_id, k8s_namespace, k8s_service_name
  • The Kubernetes cluster type and cluster group
  • In device mode only: the Kubernetes manufacturer and the Kubernetes Node device type

NODE_OBJECT_TYPE must still be set in bootstrap mode.

Configuration:

config:
  BOOTSTRAP: true  # Set to true for initial setup, false for regular operation

First-time run process:

  1. Set BOOTSTRAP: true in your configuration.
  2. Run the agent and monitor the output for executed successfully.
  3. Stop the agent by pressing Ctrl+C once you see executed successfully.
  4. Apply the deviations in NetBox Assurance (see Apply Deviations below).
  5. Set BOOTSTRAP: false for all future runs.

Optional - Dry Run Mode

The agent can run in dry run mode, which writes discovered data to a JSON file instead of sending it to NetBox. This is useful for checking what the integration will create before the first real sync, or for sharing data with the NetBox Labs support team.

Add the following to the diode section of your configuration:

      diode:
        dry_run: true
        dry_run_output_dir: /opt/orb/  # Output file is written to this directory

Step 3: Run the Agent

Run the agent to synchronize the cluster into NetBox. The current directory, containing agent.yaml and cluster-ca.pem, is mounted into the container at /opt/orb/, so the CA certificate path inside the container is /opt/orb/cluster-ca.pem.

Method 1: Set Environment Variables Manually

  1. Export Diode credentials:
export DIODE_CLIENT_ID="your-client-id"
export DIODE_CLIENT_SECRET="your-client-secret"
  1. Export Kubernetes connection details:
export K8S_API_URL="https://10.0.0.1:6443"
export K8S_TOKEN="your-service-account-token"
export K8S_CA_CERT="/opt/orb/cluster-ca.pem"
  1. Run the agent:
docker run \
  -v $PWD:/opt/orb/ \
  -e DIODE_CLIENT_SECRET \
  -e DIODE_CLIENT_ID \
  -e K8S_API_URL \
  -e K8S_TOKEN \
  -e K8S_CA_CERT \
  quay.io/netboxlabs/orb-agent-pro:develop \
  run -c /opt/orb/agent.yaml
  1. Create a .env file:
touch .env
  1. Edit the .env file and add the following:
## NetBox Diode credentials (from NetBox Setup)
DIODE_CLIENT_ID=your-client-id
DIODE_CLIENT_SECRET=your-client-secret

## Kubernetes connection
K8S_API_URL=https://10.0.0.1:6443
K8S_TOKEN=your-service-account-token
K8S_CA_CERT=/opt/orb/cluster-ca.pem

Important

Replace the placeholder values with your actual credentials:

  1. Run the agent:
docker run \
  -v $PWD:/opt/orb/ \
  --env-file .env \
  quay.io/netboxlabs/orb-agent-pro:develop \
  run -c /opt/orb/agent.yaml

Security Best Practice

Add .env to your .gitignore file to avoid committing credentials to version control:

echo ".env" >> .gitignore

Expected Output

After starting the agent, you will see log output as the integration reads the cluster and sends data to NetBox:

{"time":"2026-10-06T15:15:01.123456789Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.kubernetes_diode:No node label filtering configured — ingesting all nodes"}
{"time":"2026-10-06T15:15:01.234567890Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.kubernetes_diode:Starting Kubernetes sync for cluster 'prod-east' at https://10.0.0.1:6443 in device mode"}
{"time":"2026-10-06T15:15:01.345678901Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.client:Verifying the API server against the CA bundle at /opt/orb/cluster-ca.pem"}
{"time":"2026-10-06T15:15:01.456789012Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.cluster:Created cluster 'prod-east' in group 'Kubernetes' (matching id 3f0c9a52-7d1e-4b8a-9c6f-2a1e5d8b4c07)"}
{"time":"2026-10-06T15:15:01.567890123Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.client:Fetched 3 nodes"}
{"time":"2026-10-06T15:15:01.678901234Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.device_roles:Built 2 device roles"}
{"time":"2026-10-06T15:15:01.789012345Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.nodes:Built 3 nodes as device entities"}
{"time":"2026-10-06T15:15:01.890123456Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.interfaces:Built 3 node interfaces named 'kubernetes'"}
{"time":"2026-10-06T15:15:01.901234567Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.ip_addresses:Built 3 node addresses"}
{"time":"2026-10-06T15:15:02.012345678Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.vrfs:Created VRF 'prod-east' (rd=k8s:9e49cfecc54d38c87)"}
{"time":"2026-10-06T15:15:02.123456789Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.client:Fetched 1 ServiceCIDR objects"}
{"time":"2026-10-06T15:15:02.234567890Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.prefixes:Built 4 prefixes"}
{"time":"2026-10-06T15:15:02.345678901Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.client:Fetched 12 services"}
{"time":"2026-10-06T15:15:02.456789012Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.builders.service_addresses:Built 1 external service addresses from 1 LoadBalancer services"}
{"time":"2026-10-06T15:15:02.567890123Z","level":"INFO","msg":"worker stderr","log":"INFO:nbl_kubernetes.kubernetes_diode:Returning 27 total entities"}
{"time":"2026-10-06T15:15:03.678901234Z","level":"INFO","msg":"worker stderr","log":"INFO:worker.policy.runner:Policy kubernetes_worker: Successful ingestion"}
{"time":"2026-10-06T15:15:03.789012345Z","level":"INFO","msg":"worker stderr","log":"INFO:apscheduler.executors.default:Job \"PolicyRunner.run\" executed successfully"}

Monitoring and Testing

Success indicator: Look for Successful ingestion in the output to confirm data was sent to NetBox via Diode.

Warnings to check: The integration logs a warning, and continues, when it cannot read services or service CIDRs, when LoadBalancer services report a hostname instead of an IP address, and when a node has no usable system UUID. See FAQ & Troubleshooting.

Testing: Run the agent once and press Ctrl+C to stop it after seeing executed successfully. This lets you verify configuration before setting up continuous scheduled operation.

Continuous operation: The agent runs according to your cron schedule until the container is stopped.

View and Apply Discovered Data in NetBox Assurance

After the agent runs, work with the discovered Kubernetes data in NetBox Assurance.

NetBox Assurance identifies deviations between data already in NetBox and the actual operational state discovered by the integration.

Understanding Deviations

Deviations are the delta between what is currently in NetBox and what the integration discovered from the cluster. On the initial run, all discovered objects may appear as deviations if they did not previously exist in NetBox. After the initial sync and deviation application, subsequent runs produce deviations only for changed or new objects.

Accessing NetBox Assurance

  1. Navigate to your NetBox instance UI.
  2. Click on Assurance in the main navigation menu.

Explore Deviation Types

  1. Click on Deviation Types to view the categories of deviations discovered.

Assurance deviation types

  1. Click the Name of a deviation type to view deviations of that type.

Discovered new device

  1. Click the Name of an individual deviation to view its details.

View Active Deviations

  1. Click on Active Deviations to view all deviations that have not yet been applied or ignored.

Active deviations

  1. Click the Name of a deviation to view its details.

Apply Deviations

  1. Select the deviations you want to apply. For large result sets, set Per Page to 500 first.

Set per page to 500

  1. Select the first deviation, hold SHIFT, select the last one, then click Apply Selected.

Apply selected deviations

  1. Click Apply X Deviations to write the data to NetBox.

Confirm applying deviations

Apply Deviations to a Branch

Instead of writing deviations to the Main NetBox database branch, select another branch from the drop-down menu to apply deviations to that branch first.

Assurance Docs

For detailed information on working with NetBox Assurance, see the documentation.

View the Kubernetes Data in NetBox

After running the integration and applying discovered data, you can navigate the cluster in NetBox:

  1. Navigate to Virtualization → Clusters and open your cluster to see its nodes.
  2. Navigate to Devices (in device mode) or Virtualization → Virtual Machines (in virtual_machine mode) to see each node with its role, status, and the k8s_system_uuid and k8s_provider_id custom fields.
  3. Open a node's interfaces to see the kubernetes interface and the node's IP addresses.
  4. Navigate to IPAM → VRFs and open the cluster's VRF to see its pod and service prefixes.
  5. Navigate to IPAM → IP Addresses and filter by the k8s_service_name custom field to see LoadBalancer service addresses.

Additional Resources

Support

Email support@netboxlabs.com for support.

On this page