Files
kubesolo-os/docs/cloud-init.md
Adolfo Delorenzo 61bd28c692
Some checks failed
CI / Go Tests (push) Has been cancelled
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
CI / Shellcheck (push) Has been cancelled
feat: cloud-init supports all documented KubeSolo CLI flags
Add missing flags (--local-storage-shared-path, --debug, --pprof-server,
--portainer-edge-id, --portainer-edge-key, --portainer-edge-async) so all
10 documented KubeSolo parameters can be configured via cloud-init YAML.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:49:31 -06:00

5.9 KiB

KubeSolo OS — Cloud-Init Configuration

KubeSolo OS uses a lightweight cloud-init system to configure the node on first boot. The configuration is a YAML file placed on the data partition before the first boot.

Configuration File Location

The cloud-init config is loaded from (in priority order):

  1. Path specified by kubesolo.cloudinit=<path> boot parameter
  2. /mnt/data/etc-kubesolo/cloud-init.yaml (default)

Boot Sequence Integration

Cloud-init runs as init stage 45, before network (stage 50) and hostname (stage 60). When cloud-init applies successfully, stages 50 and 60 detect this and skip their default behavior.

Stage 20: Mount persistent storage
Stage 30: Load kernel modules
Stage 40: Apply sysctl
Stage 45: Cloud-init (parse YAML, apply hostname + network + KubeSolo config)  <--
Stage 50: Network fallback (skipped if cloud-init handled it)
Stage 60: Hostname fallback (skipped if cloud-init handled it)
Stage 70: Clock sync
Stage 80: Containerd prerequisites
Stage 90: Start KubeSolo

YAML Schema

# Hostname for the node
hostname: kubesolo-node

# Network configuration
network:
  mode: dhcp | static        # Default: dhcp
  interface: eth0             # Optional: auto-detected if omitted
  address: 192.168.1.100/24   # Required for static mode (CIDR notation)
  gateway: 192.168.1.1        # Required for static mode
  dns:                        # Optional: DNS nameservers
    - 8.8.8.8
    - 1.1.1.1

# KubeSolo settings
kubesolo:
  extra-flags: "--disable traefik"   # Extra CLI flags for KubeSolo binary
  local-storage: true                # Enable local-path provisioner (default: true)
  local-storage-shared-path: "/mnt/shared"  # Shared path for local-path-provisioner
  apiserver-extra-sans:              # Extra SANs for API server certificate
    - node.example.com
    - 10.0.0.50
  debug: false                       # Enable verbose debug logging
  pprof-server: false                # Enable Go pprof profiling server
  portainer-edge-id: ""              # Portainer Edge Agent ID
  portainer-edge-key: ""             # Portainer Edge Agent key
  portainer-edge-async: false        # Enable async Portainer Edge communication

# NTP servers (optional)
ntp:
  servers:
    - pool.ntp.org

# Air-gapped deployment (optional)
airgap:
  import-images: true          # Import container images from data partition
  images-dir: /mnt/data/images # Directory containing .tar image files

# Portainer Edge Agent (optional)
portainer:
  edge-agent:
    enabled: true
    edge-id: "your-edge-id"
    edge-key: "your-edge-key"
    portainer-url: "https://portainer.example.com"

Network Modes

DHCP (Default)

network:
  mode: dhcp

Uses BusyBox udhcpc on the first non-virtual interface. Optionally override DNS:

network:
  mode: dhcp
  dns:
    - 10.0.0.1

Static IP

network:
  mode: static
  interface: eth0
  address: 192.168.1.100/24
  gateway: 192.168.1.1
  dns:
    - 8.8.8.8
    - 8.8.4.4

Both address (CIDR) and gateway are required for static mode.

Persistence

After applying, cloud-init saves its configuration to the data partition:

File Purpose
/mnt/data/network/interfaces.sh Shell script to restore network config on next boot
/mnt/data/etc-kubesolo/hostname Saved hostname
/etc/kubesolo/extra-flags KubeSolo CLI flags
/etc/kubesolo/config.yaml KubeSolo configuration

On subsequent boots, stage 50 (network) sources the saved interfaces.sh directly, skipping cloud-init parsing entirely. This is faster and doesn't require the cloud-init binary.

CLI Usage

The cloud-init binary supports three commands:

# Apply configuration (run during boot by stage 45)
kubesolo-cloudinit apply /path/to/cloud-init.yaml

# Validate a config file
kubesolo-cloudinit validate /path/to/cloud-init.yaml

# Dump parsed config as JSON (for debugging)
kubesolo-cloudinit dump /path/to/cloud-init.yaml

KubeSolo Configuration Reference

All fields under the kubesolo: section and their corresponding CLI flags:

YAML Field CLI Flag Type Default Description
extra-flags (raw flags) string "" Arbitrary extra flags passed to KubeSolo binary
local-storage --local-storage bool true Enable local-path-provisioner for PVCs
local-storage-shared-path --local-storage-shared-path string "" Shared path for local-path-provisioner storage
apiserver-extra-sans --apiserver-extra-sans list [] Extra SANs for API server TLS certificate
debug --debug bool false Enable verbose debug logging
pprof-server --pprof-server bool false Enable Go pprof profiling server
portainer-edge-id --portainer-edge-id string "" Portainer Edge Agent ID (from Portainer UI)
portainer-edge-key --portainer-edge-key string "" Portainer Edge Agent key (from Portainer UI)
portainer-edge-async --portainer-edge-async bool false Enable async Portainer Edge communication

Note: The portainer-edge-* fields generate CLI flags for KubeSolo's built-in Edge Agent support. This is an alternative to the portainer.edge-agent section, which creates a standalone Kubernetes manifest. Use one approach or the other, not both.

Examples

See cloud-init/examples/ for complete configuration examples:

  • dhcp.yaml — DHCP with defaults
  • static-ip.yaml — Static IP configuration
  • portainer-edge.yaml — Portainer Edge Agent integration
  • airgapped.yaml — Air-gapped deployment with pre-loaded images
  • full-config.yaml — All supported KubeSolo parameters

Building

The cloud-init binary is built as part of the normal build process:

# Build just the cloud-init binary
make build-cloudinit

# Run cloud-init unit tests
make test-cloudinit

# Full build (includes cloud-init)
make iso

The binary is compiled as a static Linux/amd64 binary (CGO_ENABLED=0) and is approximately 2.7 MB.