Skip to main content
Cilium CNI can be installed on Talos Linux using several methods, ranging from a fully declarative GitOps-friendly approach to a quick one-command install for development clusters. The right method depends on whether you’re using Omni, what your production requirements are, and how much you want the installation to persist across reboots. Each method supports both the default kube-proxy mode and kube-proxy-free operation, covered by tabs in each section.
MethodRecommended forNotes
Omni manifest syncOmni usersRecommended path for Omni clusters
HelmAll other Talos clustersFour variants — inline, apply, hosted, CLI; choose based on your workflow
Cilium CLIDevelopment / testingQuickest path, least declarative

Prerequisites

Talos Linux has specific requirements that apply regardless of which installation method you choose:
  • IPAM mode must be set to kubernetes
  • Talos already provides cgroupv2 and bpffs mounts — do not let Cilium attempt to mount these
  • Talos does not allow Kubernetes workloads to load kernel modules, so the SYS_MODULE capability must be dropped from Cilium’s default capability set
  • This guide assumes KubePrism is enabled and configured on port 7445

Machine configuration prerequisites

In addition to the above prerequisites, the Cilium CLI and Helm methods all require that you first configure your machine with CNI set to none. Set this before bootstrapping. To do that:
1. Create a patch file that sets the CNI to none:
cat <<EOF > patch.yaml
cluster:
  network:
    cni:
      name: none
EOF
2. Generate the machine config with the patch applied:
talosctl gen config \
    my-cluster https://mycluster.local:6443 \
    --config-patch @patch.yaml
After applying the machine config with CNI set to none and bootstrapping, Talos will appear to hang at phase 18/19 with the message retrying error: node not ready. This is expected, nodes are only marked ready once a CNI is running. You have approximately 10 minutes to apply Cilium before the node reboots to retry.

Method 1: Omni manifest sync

If you are using Omni, the recommended approach is to deploy Cilium using the manifest sync feature in a cluster template. Omni will wait until the Kubernetes API is available and the cluster is healthy before applying the Cilium manifests. Step 1. Create a values.yaml file with the Cilium Helm values by running:
cat <<EOF > values.yaml
ipam:
  mode: kubernetes
kubeProxyReplacement: false
securityContext:
  capabilities:
    ciliumAgent:
      - CHOWN
      - KILL
      - NET_ADMIN
      - NET_RAW
      - IPC_LOCK
      - SYS_ADMIN
      - SYS_RESOURCE
      - DAC_OVERRIDE
      - FOWNER
      - SETGID
      - SETUID
    cleanCiliumState:
      - NET_ADMIN
      - SYS_ADMIN
      - SYS_RESOURCE
cgroup:
  autoMount:
    enabled: false
  hostRoot: /sys/fs/cgroup
EOF
Step 2. Render the Cilium manifests using Helm:
helm repo add cilium https://helm.cilium.io/
helm repo update
helm template \
    cilium \
    cilium/cilium \
    --version 1.18.0 \
    --namespace kube-system \
    --values values.yaml > cilium.yaml
Step 3. Reference the rendered manifest in your Omni cluster template using the file field:
When deploying without kube-proxy, set proxy.disabled: true in the patches block:
Step 4. Apply the cluster template:
omnictl cluster template sync --file cluster-template.yaml
See Sync Kubernetes Manifests for more on manifest sync modes and status monitoring.

Method 2: Helm

Helm is the recommended approach for Talos clusters not managed by Omni. There are four variants depending on how you want to manage and apply the Cilium manifest. Choose the one that fits your workflow:
  • CLI install: Installs Cilium directly with helm install without generating a manifest file. Simplest Helm path but least declarative.
  • Inline manifest: Embeds the manifest directly in the machine configuration; applied automatically on bootstrap and reapplied on control plane reboots. Recommended for production.
  • Manifest apply: Generates the manifest with helm template and applies it manually with kubectl. Useful for one-off installs or when you want to inspect the manifest first.
  • Hosted manifest: Generates the manifest, hosts it at a URL, and patches the machine config to fetch it automatically during bootstrap. Requires secure internal hosting.
Install Cilium directly using helm install during the bootstrap window.
helm repo add cilium https://helm.cilium.io/
helm repo update

helm install \
    cilium \
    cilium/cilium \
    --version 1.18.0 \
    --namespace kube-system \
    --set ipam.mode=kubernetes \
    --set kubeProxyReplacement=false \
    --set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \
    --set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \
    --set cgroup.autoMount.enabled=false \
    --set cgroup.hostRoot=/sys/fs/cgroup
After Cilium is installed successfully, the bootstrap process will continue and complete.

Method 3: Cilium CLI

Install the Cilium CLI following the upstream instructions, then run:
cilium install \
    --set ipam.mode=kubernetes \
    --set kubeProxyReplacement=false \
    --set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \
    --set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \
    --set cgroup.autoMount.enabled=false \
    --set cgroup.hostRoot=/sys/fs/cgroup

Known issues

The following are known issues when running Cilium on Talos Linux. Each entry includes a workaround where one exists.
  • GCP internal load balancers: There are known issues when using Talos and Cilium on Google Cloud Platform with internal load balancers. See GCP ILB support / support scope local routes to be configured for details.
  • CoreDNS not working with forwardKubeDNSToHost and bpf.masquerade: When using Talos forwardKubeDNSToHost=true (enabled by default) together with Cilium bpf.masquerade=true, CoreDNS may not work correctly. Setting forwardKubeDNSToHost=false resolves the issue. See the discussion here for more context.
  • cilium connectivity test fails with PodSecurity errors: After installing Cilium, cilium connectivity test may hang or fail with an error like:
    Error creating: pods "client-69748f45d8-9b9jg" is forbidden: violates PodSecurity "baseline:latest":
    non-default capabilities (container "client" must not include "NET_RAW" in securityContext.capabilities.add)
    
    This is expected. Work around it by adding the pod-security.kubernetes.io/enforce=privileged label on the namespace level.

Additional resources

Talos has full kernel module support for eBPF. See Cilium System Requirements, Talos Kernel Config AMD64, and Talos Kernel Config ARM64.