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>
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):
- Path specified by
kubesolo.cloudinit=<path>boot parameter /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 defaultsstatic-ip.yaml— Static IP configurationportainer-edge.yaml— Portainer Edge Agent integrationairgapped.yaml— Air-gapped deployment with pre-loaded imagesfull-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.