Getting Started with K3s (K3d)
K3s is a lightweight, certified Kubernetes distribution designed for resource-constrained environments. KSail uses K3d to run K3s clusters in Docker containers, giving you fast cluster creation with batteries-included defaults like a built-in load balancer, local storage provisioner, and metrics server.
What is K3s (K3d)?
Section titled āWhat is K3s (K3d)?āK3s is a minimal Kubernetes distribution that bundles everything into a single binary. K3d wraps K3s in Docker containers so you can run full clusters locally. It offers a minimal footprint, batteries-included defaults (ServiceLB, local-path-provisioner, metrics-server), fast 15ā30 s cluster creation, and standard k3d.yaml files with no lock-in.
K3s (K3d) is ideal for quick local development, resource-constrained machines or CI runners, CI/CD pipelines with ephemeral clusters, and multi-node topology testing.
Quick Start
Section titled āQuick StartāCreate your first K3s cluster in under 30 seconds.
Prerequisites
Section titled āPrerequisitesā- Docker Desktop or Docker Engine installed and running
docker pscommand works
Step 1: Initialize Project
Section titled āStep 1: Initialize Projectāksail cluster init \ --name my-cluster \ --distribution K3s \ --control-planes 1 \ --workers 2This creates:
ksail.yamlā KSail configurationk3d.yamlā K3d-specific cluster configuration
Step 2: Create Cluster
Section titled āStep 2: Create Clusterāksail cluster createStep 3: Verify Cluster
Section titled āStep 3: Verify Clusterā# Check cluster infoksail cluster info
# View nodeskubectl get nodes
# Expected output:# NAME STATUS ROLES AGE VERSION# k3d-my-cluster-server-0 Ready control-plane,master 2m v1.31.x+k3s1# k3d-my-cluster-agent-0 Ready <none> 2m v1.31.x+k3s1# k3d-my-cluster-agent-1 Ready <none> 2m v1.31.x+k3s1Step 4: Deploy Sample Application
Section titled āStep 4: Deploy Sample Applicationā# Create a deploymentkubectl create deployment nginx --image=nginx
# Expose as LoadBalancer (K3s ServiceLB assigns an IP automatically)kubectl expose deployment nginx --port=80 --type=LoadBalancer
# Verify ā EXTERNAL-IP should appear within a few secondskubectl get svc nginxStep 5: Cleanup
Section titled āStep 5: Cleanupā# Delete cluster and all resourcesksail cluster deleteConfiguration
Section titled āConfigurationāBasic Configuration
Section titled āBasic ConfigurationāThe ksail.yaml file controls your cluster:
apiVersion: ksail.io/v1alpha1kind: Clusterspec: cluster: name: my-cluster distribution: K3s provider: Docker controlPlanes: 1 workers: 2K3d-Specific Configuration
Section titled āK3d-Specific ConfigurationāCustomize K3d behavior in k3d.yaml:
apiVersion: k3d.io/v1alpha5kind: Simplemetadata: name: my-clusterservers: 1 # control-plane nodesagents: 2 # worker nodesports: - port: 8080:80@loadbalancer # Map host port 8080 to cluster port 80 - port: 8443:443@loadbalancer # Map host port 8443 to cluster port 443options: k3s: extraArgs: - arg: --disable=traefik # Disable built-in Traefik ingress nodeFilters: - server:*Built-in Components
Section titled āBuilt-in ComponentsāK3s includes these components by defaultāKSail does not reinstall them:
| Component | Notes |
|---|---|
| ServiceLB (Klipper-LB) | LoadBalancer support via host ports |
| local-path-provisioner | Dynamic PersistentVolume provisioning |
| Metrics Server | kubectl top and HPA support |
| CoreDNS | Cluster DNS |
| Traefik | Ingress controller (can be disabled) |
Registry Mirrors
Section titled āRegistry MirrorsāConfigure registry mirrors to avoid rate limits. KSail enables docker.io, ghcr.io, quay.io, and registry.k8s.io mirrors by default. Override with --mirror-registry flags:
ksail cluster init --name my-cluster --distribution K3s \ --mirror-registry 'docker.io=https://registry-1.docker.io' \ --mirror-registry 'ghcr.io=https://ghcr.io' \ --mirror-registry 'quay.io=https://quay.io' \ --mirror-registry 'registry.k8s.io=https://registry.k8s.io'K3d injects registry configuration so all nodes use your mirrors automatically.
Architecture
Section titled āArchitectureāK3d uses Docker containers as cluster nodes. A dedicated K3d load balancer container routes traffic to control-plane nodes. Each control-plane container runs the K3s server binary (embedding all control-plane components, etcd, ServiceLB, local-path-provisioner, and metrics-server). Worker nodes run the K3s agent with containerd.
Distribution Comparison
Section titled āDistribution ComparisonāSee the Support Matrix for a full feature and component comparison across all distributions.
Troubleshooting
Section titled āTroubleshootingā1. Cluster Creation Fails
Section titled ā1. Cluster Creation FailsāSymptom: ksail cluster create fails with Docker errors.
docker ps # Check Docker is runningdf -h # Check available disk spacedocker system prune -f # WARNING: removes unused containers, networks, images, and build cacheksail cluster create2. Nodes Not Ready
Section titled ā2. Nodes Not ReadyāSymptom: kubectl get nodes shows NotReady status.
kubectl describe node <node-name>kubectl get pods -n kube-systemksail cluster delete && ksail cluster create3. LoadBalancer Stuck in Pending
Section titled ā3. LoadBalancer Stuck in PendingāK3s uses ServiceLB (Klipper-LB), which binds to host ports. Ensure the port is not already in use:
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep k3d
# Use different ports in k3d.yamlports: - port: 9080:80@loadbalancer4. Port Already in Use
Section titled ā4. Port Already in UseāSymptom: address already in use error during cluster creation.
k3d cluster listk3d cluster delete <cluster-name># Or initialize with a different name:ksail cluster init --name my-cluster-2 --distribution K3s5. Out of Memory or Disk Space
Section titled ā5. Out of Memory or Disk SpaceāReduce node count in ksail.yaml (workers: 0 for a single-node cluster) and run docker system prune. Increase Docker Desktop resources under Settings ā Resources.
Advanced Topics
Section titled āAdvanced TopicsāWorker Node Scaling
Section titled āWorker Node ScalingāUnlike Vanilla (Kind), K3s supports in-place worker node scaling:
# ksail.yaml ā increase workersspec: cluster: workers: 4ksail cluster update # Adds/removes worker containers without recreationDisabling Built-in Components
Section titled āDisabling Built-in ComponentsāRemove K3s default components you donāt need:
options: k3s: extraArgs: - arg: --disable=traefik # Remove Traefik ingress nodeFilters: ["server:*"] - arg: --disable=servicelb # Remove ServiceLB (use MetalLB instead) nodeFilters: ["server:*"]Custom CNI
Section titled āCustom CNIāReplace the default Flannel CNI with Cilium:
spec: cluster: cni: Cilium# k3d.yaml ā disable built-in Flanneloptions: k3s: extraArgs: - arg: --flannel-backend=none nodeFilters: ["server:*"] - arg: --disable-network-policy nodeFilters: ["server:*"]Kubernetes Version
Section titled āKubernetes VersionāK3s version is determined by the K3d image. Pin a specific version in k3d.yaml:
image: rancher/k3s:v1.31.0-k3s1See K3d image tags for available versions.
Port Mappings
Section titled āPort MappingsāExpose services on host ports:
ports: - port: 8080:80@loadbalancer # HTTP - port: 8443:443@loadbalancer # HTTPS - port: 30080:30080@agent:0 # NodePort on first workerIntegration with Native K3d
Section titled āIntegration with Native K3dāKSail generates standard k3d.yaml filesāuse K3d CLI directly (k3d cluster create --config k3d.yaml) if needed. No vendor lock-in: configurations are portable and KSail can interact with any K3d cluster accessible via your kubeconfig.
Next Steps
Section titled āNext Stepsā- GitOps Integration: Bootstrap Flux or ArgoCD
- Secret Management: Encrypt secrets with SOPS
- AI Chat: Interactive cluster management with GitHub Copilot
- VSCode Extension: Manage clusters from your editor
- Use Cases: Workflows for learning, development, and CI/CD
- Vanilla (Kind): Upstream Kubernetes for maximum compatibility
- Talos: Immutable infrastructure for production
- VCluster: Virtual clusters for multi-tenancy
- Installation Guide: Install KSail on your system
- Contributing: How to contribute to KSail
- CLI Flags: Comprehensive command documentation
- Configuration Reference: Detailed YAML options
- LoadBalancer Configuration: LoadBalancer options for K3s