Configuration
June 16, 2026 · View on GitHub
This guide details the configuration options for the Karpenter Provider for Linode, covering environment variables, operating modes, and the LinodeNodeClass Custom Resource.
Environment Variables
| Variable | Description | Required? | Default |
|---|---|---|---|
LINODE_TOKEN | Your Linode API Personal Access Token. | Yes | - |
CLUSTER_NAME | The name of your LKE cluster. Used to discover the cluster ID in lke mode. | Yes (in lke mode) | - |
LINODE_REGION | The Linode region code. See available regions. | No | us-east |
CLUSTER_ENDPOINT | The external Kubernetes cluster endpoint. Discovered automatically if not provided. | No | - |
KARPENTER_MODE | Operating mode: lke or instance. See Modes below. | No | lke |
LINODE_CLIENT_TIMEOUT | Timeout in seconds for Linode API client requests. | No | - |
VM_MEMORY_OVERHEAD_PERCENT | Additional memory overhead to simplify calculation (0.075 = 7.5%). | No | 0.075 |
DISABLE_DRY_RUN | Set to true to disable dry-run validation for LinodeNodeClasses. | No | false |
These environment variables are injected into the controller pod via a Kubernetes Secret. By default, the Helm chart creates a secret called karpl-credentials from the apiToken, apiURL, apiVersion, and region values.
Note: Using an external secret (GitOps)
For GitOps workflows where credentials should not be stored in Helm values, you can set
credentialsSecretRefto point to a pre-existing Secret instead. When set, the chart skips creating its own secret and uses the referenced one. This is useful when secrets are managed externally via ExternalSecrets, SealedSecrets, Vault, or similar tools.The externally managed secret must contain the following keys:
LINODE_TOKEN,LINODE_URL,LINODE_API_VERSION, and optionallyCLUSTER_REGION.helm upgrade --install karpenter charts/karpenter \ --set settings.clusterName=my-cluster \ --set credentialsSecretRef=my-linode-credentials
Modes
The provider can operate in two distinct modes, controlled by the KARPENTER_MODE environment variable.
LKE Mode (lke)
- Default Mode.
- Provisions nodes by creating LKE Node Pools with a count of 1.
- The nodes are automatically joined to your LKE cluster.
- Pros: Simplest setup, managed by LKE.
- Cons: Limited customization (cannot use custom images or advanced networking/storage options usually available to raw Linodes).
Instance Mode (instance)
- Provisions nodes by creating raw Linode Instances.
- Status: ⚠️ In Development. Not Fully Functional
- This mode represents the roadmap for full instance control but is not currently functional for creating working cluster nodes.
- It currently lacks bootstrapping and cluster joining logic (such as User Data injection). Instances will start but will not join the Kubernetes cluster.
- Pros: Full control over the instance configuration (SSH keys, placement groups, etc.).
- Note:
VPCIDand custom disk configurations are defined in the API but not yet fully implemented in the provider logic.
LinodeNodeClass Spec
The LinodeNodeClass allows you to configure specific settings for the nodes managed by Karpenter. Support for specific fields depends on the Mode you are running.
Field Reference
| Field | Type | Supported Modes | Description |
|---|---|---|---|
tags | []string | All | List of tags to apply to instances. In LKE mode, Karpenter-managed pools keep only core provider tags. |
firewallID | int | All | The ID of the Cloud Firewall to attach. |
lkeK8sVersion | string | LKE | Specific Kubernetes version for LKE Enterprise worker nodes. Upgrade the cluster control plane to this version first; otherwise reconciliation fails and replacement NodeClaims will not come up on the requested version. For Enterprise clusters, the update strategy automatically defaults to on_recycle. |
image | string | Instance | The Image ID to deploy (default: linode/ubuntu22.04). |
authorizedKeys | []string | Instance | SSH Public Keys to add to the root user. |
authorizedUsers | []string | Instance | List of Linode usernames whose SSH keys will be added. |
backupsEnabled | bool | Instance | Enable backups service for the instance. |
diskEncryption | enum | Instance | enabled or disabled. |
swapSize | int | Instance | Size of the swap disk in MiB. |
placementGroup | object | Instance | Place instance in a specific Placement Group (see below). |
Taints and Standard Labels
It is important to distinguish between Karpenter configuration and Linode-specific configuration:
- Taints: Taints are defined in the Karpenter
NodePoolresource (spec.template.spec.taints), not in theLinodeNodeClass.- LKE Mode: Taints are passed to the LKE Node Pool configuration and applied to nodes by LKE.
- Kubernetes Labels: Standard scheduling labels are defined in the Karpenter
NodePool(spec.template.metadata.labels). Karpenter ensures these are applied to the Node object. - LKE Labels: LKE Node Pool labels are derived from the labels resolved onto the NodeClaim (originating from NodePool template metadata labels).
Example: LKE Mode
apiVersion: karpenter.k8s.linode/v1alpha1
kind: LinodeNodeClass
metadata:
name: default
spec:
tags:
- "karpenter-node"
- "env:production"
firewallID: 12345
Example: Instance Mode
apiVersion: karpenter.k8s.linode/v1alpha1
kind: LinodeNodeClass
metadata:
name: custom-instance
spec:
tags:
- "custom-workload"
image: "linode/ubuntu22.04"
authorizedUsers:
- "my-user"
backupsEnabled: true
swapSize: 512
diskEncryption: "enabled"
Selecting nodes
With nodeSelector you can ask for a node that matches selected key-value pairs.
This can include well-known labels or custom labels you create yourself.
You can use affinity to define more complicated constraints, see Node Affinity for the complete specification.
Labels
Well-known labels may be specified as NodePool requirements or pod scheduling constraints. You can also define your own custom labels by specifying requirements or labels on your NodePool and select them using nodeAffinity or nodeSelectors on your Pods.
Well-Known Labels
| Label | Example | Description |
|---|---|---|
| topology.kubernetes.io/region | us-east | Regions are defined by your cloud provider (linode) |
| node.kubernetes.io/instance-type | g6-dedicated-16 | Instance types are defined by your cloud provider (linode) |
| kubernetes.io/os | linux | Operating systems are defined by GOOS values on the instance |
| kubernetes.io/arch | amd64 | Architectures are defined by GOARCH values on the instance |
| karpenter.k8s.linode/instance-generation | 6 | [Linode Specific] Instance type generation number |
| karpenter.k8s.linode/instance-cpu | 32 | [Linode Specific] Number of CPUs on the instance |
| karpenter.k8s.linode/instance-memory | 32768 | [Linode Specific] Number of megabytes of memory on the instance |
| karpenter.k8s.linode/instance-disk | 655360 | [Linode Specific] Number of megabytes of storage on the instance |
| karpenter.k8s.linode/instance-gpu-name | gtx6000 | [Linode Specific] Name of the GPU on the instance, if available |
| karpenter.k8s.linode/instance-gpu-count | 1 | [Linode Specific] Number of GPUs on the instance |
| karpenter.k8s.linode/instance-transfer | 16000 | [Linode Specific] Number of gigabytes for network transfer |
| karpenter.k8s.linode/instance-network-out | 10000 | [Linode Specific] Number of megabits per second for network outbound bandwidth |
| karpenter.k8s.linode/instance-accelerated-devices-count | 1 | [Linode Specific] Number of accelerated devices on the instance |
| karpenter.k8s.linode/instance-class | dedicated | [Linode Specific] Instance class types include nanode, standard, dedicated, highmem, and gpu |
User-Defined Labels
Karpenter is aware of several well-known labels, deriving them from instance type details. If you specify a nodeSelector or a required nodeAffinity using a label that is not well-known to Karpenter, it will not launch nodes with these labels and pods will remain pending. For Karpenter to become aware that it can schedule for these labels, you must specify the label in the NodePool requirements with the Exists operator:
requirements:
- key: user.defined.label/type
operator: Exists
Node selectors
Here is an example of a nodeSelector for selecting nodes:
nodeSelector:
topology.kubernetes.io/region: us-east
karpenter.sh/capacity-type: dedicated
This example features a well-known label (topology.kubernetes.io/region) and a label that is well known to Karpenter (karpenter.sh/capacity-type).
If you want to create a custom label, you should do that at the NodePool level. Then the pod can declare that custom label.
See nodeSelector in the Kubernetes documentation for details.