Talos Linux
Talos Linux v1.13.6 runs the single Kubernetes control-plane and workload
node. The installation was prepared as one complete machine configuration:
the custom NVIDIA image, kernel modules, control-plane scheduling, and disk
layout were all present before the first apply.
Build the installation image
The AMD64 bare-metal image was created with Talos Image Factory using this schematic:
6698d6f136c5bb37ca8bb8482c9084305084da0a5ead1f4dcae760796f8ab3a2
It contains only the two NVIDIA extensions required by this machine:
customization:
systemExtensions:
officialExtensions:
- siderolabs/nvidia-container-toolkit-production
- siderolabs/nvidia-open-gpu-kernel-modules-production
All other Image Factory settings used their defaults. The same schematic and
Talos version must be used by machine.install.image; booting a custom ISO but
installing the default image would omit the extensions from the installed
system.
Install the CLI
The workstation uses mise to manage talosctl:
mise use -g talosctl@latest
talosctl version --client
The CLI resolved to v1.13.6 for this installation. Keeping the client and
target Talos versions aligned avoids version-skew warnings while applying the
machine configuration.
Inspect the installation disks
Boot the Image Factory ISO and wait for Talos maintenance mode. Export the node address and inspect the available disks over the insecure maintenance API:
export CONTROL_PLANE_IP=192.168.0.50
talosctl get disks \
--insecure \
--nodes "$CONTROL_PLANE_IP"
The machine exposes two relevant devices:
| Device | Size | Transport | Purpose |
|---|---|---|---|
nvme0n1 |
256 GB | NVMe | Talos system and workload storage |
sda |
62 GB | USB | Bootable installation media |
The NVMe serial observed during installation was 2401VC2S03904597. Always
inspect the live disks instead of assuming device names before a destructive
installation.
Generate the cluster configuration
export CLUSTER_NAME=homelab
export DISK_NAME=nvme0n1
talosctl gen config \
"$CLUSTER_NAME" \
"https://${CONTROL_PLANE_IP}:6443" \
--install-disk "/dev/${DISK_NAME}"
The command creates:
controlplane.yaml
talosconfig
worker.yaml
All three files contain cluster configuration, but talosconfig is
particularly important for recovery: Kubernetes credentials do not grant
administrative access to the Talos API. Keep the generated files outside Git
and back them up securely.
Configure the control plane
Edit the generated controlplane.yaml once before applying it. The complete
change can be reviewed with:
git diff -- controlplane.yaml
This is the diff that was applied during the installation:
diff --git a/controlplane.yaml b/controlplane.yaml
index afbc1d3..7a935dc 100644
--- a/controlplane.yaml
+++ b/controlplane.yaml
@@ -75,8 +75,8 @@ machine:
# Used to provide instructions for installations.
install:
disk: /dev/nvme0n1 # The disk used for installations.
- image: ghcr.io/siderolabs/installer:v1.13.6 # Allows for supplying the image used to perform the installation.
- wipe: false # Indicates if the installation disk should be wiped at installation time.
+ image: factory.talos.dev/metal-installer/6698d6f136c5bb37ca8bb8482c9084305084da0a5ead1f4dcae760796f8ab3a2:v1.13.6 # Allows for supplying the image used to perform the installation.
+ wipe: true # Indicates if the installation disk should be wiped at installation time.
grubUseUKICmdline: true # Indicates if legacy GRUB bootloader should use kernel cmdline from the UKI instead of building it on the host.
# # Look up disk using disk attributes like model, size, serial and others.
@@ -178,10 +178,14 @@ machine:
# machine: worker-1
# # Configures the kernel.
- # kernel:
+ kernel:
# # Kernel modules to load.
- # modules:
+ modules:
# - name: btrfs # Module name.
+ - name: nvidia
+ - name: nvidia_uvm
+ - name: nvidia_drm
+ - name: nvidia_modeset
# # Configures the seccomp profiles for the machine.
# seccompProfiles:
@@ -381,7 +385,7 @@ cluster:
# certLifetime: 1h0m0s # Admin kubeconfig certificate lifetime (default is 1 year).
# # Allows running workload on control-plane nodes.
- # allowSchedulingOnControlPlanes: true
+ allowSchedulingOnControlPlanes: true
---
apiVersion: v1alpha1
kind: HostnameConfig
@@ -390,3 +394,27 @@ auto: stable # A method to automatically generate a hostname for the machine.
# # A static hostname to set for the machine.
# hostname: controlplane1
# hostname: controlplane1.example.org
+---
+apiVersion: v1alpha1
+kind: VolumeConfig
+name: EPHEMERAL
+provisioning:
+ diskSelector:
+ match: disk.transport == "nvme"
+ minSize: 32GiB
+ maxSize: 64GiB
+ grow: false
+---
+apiVersion: v1alpha1
+kind: UserVolumeConfig
+name: local-path-provisioner
+provisioning:
+ diskSelector:
+ match: disk.transport == "nvme"
+ minSize: 150GiB
+ maxSize: 160GiB
+ grow: false
+filesystem:
+ type: xfs
+mount:
+ disableAccessTime: true
The patch makes all installation-time changes together:
- Installs the Image Factory build with the NVIDIA extensions and wipes the selected NVMe disk.
- Loads the four NVIDIA kernel modules supplied by that image.
- Allows workloads to run on the single control-plane node.
- Caps
EPHEMERALat 64 GiB and creates a separate 150-160 GiB XFS user volume for persistent workload data.
The installation wipes the NVMe disk
wipe: true removes the existing Talos installation, user-volume
partitions, and workload data on nvme0n1. Verify backups and the selected
device before applying this configuration.
The 256 GB disk is approximately 238 GiB. The two volume maximums consume 224
GiB, leaving room for Talos system partitions and unallocated headroom. Because
grow is disabled, this layout should be decided before initial provisioning.
Validate and apply
Validate the complete multi-document configuration before writing the disk:
talosctl validate \
--config controlplane.yaml \
--mode metal \
--strict
The expected result is:
controlplane.yaml is valid for metal mode
Apply it while the node is still in maintenance mode:
talosctl apply-config \
--insecure \
--nodes "$CONTROL_PLANE_IP" \
--file controlplane.yaml
Wait for the installed system to boot from the NVMe disk before continuing.
Bootstrap the cluster
Configure the Talos endpoint from the generated credentials:
talosctl \
--talosconfig ./talosconfig \
config endpoints "$CONTROL_PLANE_IP"
Bootstrap the single etcd member exactly once:
talosctl bootstrap \
--nodes "$CONTROL_PLANE_IP" \
--talosconfig ./talosconfig
Retrieve Kubernetes credentials:
talosctl kubeconfig \
--nodes "$CONTROL_PLANE_IP" \
--talosconfig ./talosconfig
Verify the complete control plane:
talosctl health \
--nodes "$CONTROL_PLANE_IP" \
--talosconfig ./talosconfig
The health check covers etcd consistency, the Talos API, boot completion, kubelet, control-plane static pods, node readiness, kube-proxy, CoreDNS, and node schedulability.
Configure the default Talos context
The generated context has an endpoint but no default node. Set it explicitly:
talosctl \
--talosconfig ./talosconfig \
config node "$CONTROL_PLANE_IP"
talosctl --talosconfig ./talosconfig config info
Install the client configuration in its default location so future commands do
not require --talosconfig:
mkdir -p ~/.talos
cp ./talosconfig ~/.talos/config
talosctl config info
Reboot only when a configuration change requires it:
talosctl reboot
Verify the installed capabilities
Confirm the node version and scheduling state:
kubectl get nodes -o wide
Confirm the custom extensions and loaded modules:
talosctl get extensions
talosctl get modules
The installed system must report the two NVIDIA extensions, the schematic ID,
and the four nvidia* modules. Confirm the disk layout and mount:
talosctl get volumestatus
talosctl get mountstatus u-local-path-provisioner
The current layout provisions EPHEMERAL as /dev/nvme0n1p4 and the XFS user
volume as /dev/nvme0n1p5, mounted at
/var/mnt/local-path-provisioner.
Ownership and recovery
Talos machine configuration remains outside this GitOps repository. Flux owns Kubernetes resources only after the API is available. Preserve these items in a secure backup:
talosconfig,controlplane.yaml, andworker.yaml- Vault recovery material and Raft snapshots
- application data stored outside the NVMe failure domain
A reinstall changes Kubernetes identity material, including the cluster CA and
service-account tokens. Vault Kubernetes authentication must therefore be
refreshed after a reinstall even when the API address remains 192.168.0.50.
Continue with NVIDIA GPU on Talos and the Local Path Provisioner for the Kubernetes-facing layers.