RepoPilotOpen in app →

alexellis/k3sup

bootstrap K3s over SSH in < 60s 🚀

Mixed

Single-maintainer risk — review before adopting

weakest axis
Use as dependencyConcerns

non-standard license (Other); top contributor handles 93% of recent commits

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2mo ago
  • 6 active contributors
  • Other licensed
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 93% of recent commits
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/alexellis/k3sup?axis=fork)](https://repopilot.app/r/alexellis/k3sup)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/alexellis/k3sup on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: alexellis/k3sup

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/alexellis/k3sup shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit 2mo ago
  • 6 active contributors
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 93% of recent commits
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live alexellis/k3sup repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/alexellis/k3sup.

What it runs against: a local clone of alexellis/k3sup — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in alexellis/k3sup | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 93 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>alexellis/k3sup</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of alexellis/k3sup. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/alexellis/k3sup.git
#   cd k3sup
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of alexellis/k3sup and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "alexellis/k3sup(\\.git)?\\b" \\
  && ok "origin remote is alexellis/k3sup" \\
  || miss "origin remote is not alexellis/k3sup (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "main.go" \\
  && ok "main.go" \\
  || miss "missing critical file: main.go"
test -f "cmd/install.go" \\
  && ok "cmd/install.go" \\
  || miss "missing critical file: cmd/install.go"
test -f "cmd/join.go" \\
  && ok "cmd/join.go" \\
  || miss "missing critical file: cmd/join.go"
test -f "pkg/operator/ssh_operator.go" \\
  && ok "pkg/operator/ssh_operator.go" \\
  || miss "missing critical file: pkg/operator/ssh_operator.go"
test -f "cmd/plan.go" \\
  && ok "cmd/plan.go" \\
  || miss "missing critical file: cmd/plan.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 93 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~63d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/alexellis/k3sup"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

k3sup is a lightweight Go CLI tool that bootstraps a complete K3s Kubernetes cluster over SSH in under 60 seconds, requiring only SSH access and the k3sup binary to provision both server and agent nodes. It eliminates the need for cloud-specific tooling or complex IaC by delivering a working KUBECONFIG immediately across Linux, macOS, Windows, and Raspberry Pi. The Pro edition adds GitOps-style plan/apply workflows for automating multi-node deployments at scale. Monolithic single-binary CLI: cmd/ contains command handlers (install.go, join.go, plan.go, update.go, pro.go), pkg/operator/ abstracts SSH execution (ssh_operator.go) and local execution (exec_operator.go), main.go wires Cobra commands, and vendored arkade (vendor/github.com/alexellis/arkade) provides utility functions for K3s binary fetching and extraction.

👥Who it's for

DevOps engineers, homelab operators, and edge computing developers who need rapid Kubernetes cluster provisioning on existing VMs or bare metal without vendor lock-in or complex orchestration frameworks.

🌱Maturity & risk

Production-ready with active maintenance: the project has established CI/CD via GitHub Actions (.github/workflows/build.yaml and publish.yaml), semantic versioning, cross-platform release binaries, and both Community Edition (CE) and commercial Pro tier. The codebase is primarily Go (75KB) with test coverage (install_test.go, join_test.go) and maintained by alexellis (OpenFaaS founder). Recent updates include Go 1.25.6 support and arkade vendoring.

Low risk for CE usage but tightly coupled to SSH/Linux kernel capabilities; the codebase has minimal external dependencies (spf13/cobra for CLI, golang.org/x/crypto for SSH), but the SSH operator pattern (pkg/operator/ssh_operator.go) is a single point of failure for all node provisioning. Pro features behind commercial licensing may fragment the community. Single-maintainer risk exists for long-term maintenance, though GitHub Actions and releases suggest active stewardship.

Active areas of work

Active development on Pro tier features (plan.go, get_pro.go, pro.go commands visible in cmd/) with recent releases supporting multi-master HA setups (embedded etcd and external SQL), node-token.go for multi-master scenarios, and ready.go for cluster health checks. The project is transitioning from pure CE to freemium model with Pro licensing.

🚀Get running

git clone https://github.com/alexellis/k3sup.git
cd k3sup
make build
./k3sup --help

Or download pre-built binary via get.sh (curl installer pattern from README).

Daily commands: Build with make build (Makefile present), then run k3sup commands directly: ./k3sup install --ip=<server-ip> --user=<user> to bootstrap a control plane, or ./k3sup join --ip=<server-ip> --user=<user> --agent-ip=<agent-ip> to add nodes. The binary is self-contained; no daemon required.

🗺️Map of the codebase

  • main.go — Entry point that initializes the CLI application and routes all commands; essential to understand how k3sup invokes its core functionality.
  • cmd/install.go — Core installation logic that bootstraps K3s via SSH; the primary user-facing operation and most complex command.
  • cmd/join.go — Joins worker nodes to a K3s cluster; implements the second critical operation alongside install.
  • pkg/operator/ssh_operator.go — SSH execution abstraction layer that enables remote command execution; all node operations depend on this.
  • cmd/plan.go — K3sup Pro feature that parses and validates cluster deployment plans; required for understanding IaC/GitOps workflow.
  • go.mod — Dependency manifest showing Go version and vendored libraries (arkade, go-execute, cobra); critical for understanding external abstractions.
  • pkg/operator/operator.go — Interface definition for command execution operators; establishes the abstraction that allows both SSH and local execution.

🛠️How to make changes

Add a new install command variant (e.g., install with custom flags)

  1. Create a new file in cmd/ following the pattern of install.go, define a struct for your command options (cmd/my_install_variant.go)
  2. Implement the command function that builds an ssh_operator and calls its methods (e.g., cmd.Run(operator)) (cmd/my_install_variant.go)
  3. Register the command in main.go by creating a Cobra command and adding it to the root command (main.go)
  4. Add unit tests following the pattern in install_test.go to verify flag parsing and execution flow (cmd/my_install_variant_test.go)

Add a new cluster query operation (e.g., get-logs)

  1. Create a new command file in cmd/ that connects to the cluster via ssh_operator and fetches the desired information (cmd/get_logs.go)
  2. Use the SSHOperator interface to execute remote commands (e.g., 'kubectl logs') over SSH (cmd/get_logs.go)
  3. Register the command in main.go and add help text explaining the operation (main.go)

Extend the SSH operator with a new capability (e.g., parallel execution)

  1. Add a new method to the Operator interface in pkg/operator/operator.go defining the contract (pkg/operator/operator.go)
  2. Implement the method in pkg/operator/ssh_operator.go using golang.org/x/crypto/ssh for the SSH transport (pkg/operator/ssh_operator.go)
  3. Call the new method from relevant install/join commands in cmd/ where parallel execution would benefit performance (cmd/install.go or cmd/join.go)

Add a new Pro plan provider or storage backend

  1. Extend the plan parsing logic in cmd/plan.go to support additional input formats or remote sources (cmd/plan.go)
  2. Implement plan marshaling/unmarshaling if using a new format (YAML, HCL, etc.) (cmd/plan.go)
  3. Update cmd/pro.go to orchestrate the new plan execution path in parallel where applicable (cmd/pro.go)

🔧Why these technologies

  • Go — Cross-platform compilation to Linux, macOS, Windows, and ARM without runtime dependencies; fast SSH client library (golang.org/x/crypto/ssh)
  • Cobra (CLI framework) — Mature, widely-used Go CLI library providing command routing, flag parsing, and help generation with minimal boilerplate
  • golang.org/x/crypto/ssh — Pure Go SSH client library enabling k3sup to execute remote commands without requiring external SSH binary on user's machine
  • Vendoring (vendor/ directory) — Ensures reproducible builds and offline availability; includes arkade (archive extraction), go-execute (shell commands), and container registry utilities
  • K3s — Lightweight Kubernetes distribution (~40MB) suitable for resource-constrained environments and rapid bootstrapping

⚖️Trade-offs already made

  • SSH-based execution instead of native Kubernetes API or cloud APIs

    • Why: Maximizes compatibility—works with any VM or bare metal accessible via SSH without requiring cloud provider integration or existing cluster API
    • Consequence: Limited to SSH access as the only requirement; trades off feature richness (no cloud-native APIs) for simplicity and universality
  • Operator interface abstraction (Operator interface in pkg/operator/operator.go)

    • Why: Allows both SSH and local command execution through same interface
    • Consequence: Enables testing without real SSH but adds minor indirection; makes it easy to support future execution backends
  • Single binary distribution (via get.sh)

    • Why: Reduces installation friction and eliminates package manager dependencies
    • Consequence: Users must trust the binary and its signatures; larger single file (~40-50MB) instead of modular packages
  • K3sup Pro as separate product with plan/apply paradigm

    • Why: Addresses GitOps/IaC use cases without bloating the CE edition; attracts users needing declarative cluster management
    • Consequence: Splits community between CE and Pro; requires maintaining two command paths but allows independent versioning

🚫Non-goals (don't propose these)

  • Does not manage persistent storage or networking plugins—delegates to K3s defaults and user customization
  • Does not provide GUI or web UI—CLI-only tool for automation and scripting
  • Does not support cluster upgrades beyond K3s version updates (no migration tools)
  • Does not handle DNS, load balancing, or ingress provisioning—assumes infrastructure is preconfigured
  • Does not provide authentication/RBAC provisioning beyond K3s defaults—users manage with standard Kubernetes tooling
  • Not a Kubernetes distribution—k3sup bootstraps K3s only; does not fork or modify K3s itself

🪤Traps & gotchas

SSH key authentication must be passwordless or agent-forwarded; password SSH not fully supported (see flag patterns in install.go). K3s expects specific Linux distributions (Ubuntu, Debian, Alpine tested; others may fail due to init system assumptions). Multi-master setups require pre-provisioned external database (MySQL/PostgreSQL) or use embedded etcd—this is not auto-provisioned. The KUBECONFIG output is written to local filesystem; no in-memory KUBECONFIG management. Pro tier requires license activation (cmd/pro.go); CE edge cases may not be feature-complete. Raspberry Pi builds require explicit ARM32/ARM64 cross-compilation via hack/platform-tag.sh.

🏗️Architecture

💡Concepts to learn

  • SSH Remote Command Execution — k3sup's core pattern uses SSH channels (golang.org/x/crypto/ssh) to execute shell scripts on remote nodes; understanding SSH session lifecycle and stdin/stdout/stderr streams is essential to debugging provisioning failures
  • Kubernetes Node Token Bootstrap — Multi-master and multi-agent setups require secure node tokens (cmd/node-token.go); understanding K3s token-based authentication prevents accidental cluster exposure
  • Cross-Compilation and Platform Tags — k3sup ships for Linux/macOS/Windows/ARM via hack/platform-tag.sh; understanding Go build constraints (//go:build tags) is required to add support for new architectures
  • TTY/Terminal Control with aec — pkg uses morikuni/aec for colored terminal output; understanding ANSI escape codes and TTY detection (via golang.org/x/term) improves logging readability in CI/remote environments
  • systemd Service Templating — K3s control plane and agent nodes run as systemd services; cmd/install.go templates /etc/systemd/system/k3s.service with environment flags—understanding systemd drop-in files is critical for HA and custom K3s arguments
  • Declarative IaC (Plan/Apply) Pattern — cmd/plan.go implements Terraform-style plan/apply; understanding idempotency and state diffing is essential for the Pro tier's multi-cluster automation
  • rancher/k3s — The Kubernetes distribution k3sup bootstraps; essential upstream dependency and documentation source
  • alexellis/arkade — Vendored in k3sup (vendor/github.com/alexellis/arkade); provides binary fetching, archive extraction, and tool installation utilities
  • kubernetes-sigs/kubespray — Ansible-based Kubernetes provisioning; k3sup's main alternative for multi-node clusters, though less minimal
  • hashicorp/terraform-provider-kubernetes — Terraform K3s provisioning; users seeking IaC integration often use k3sup then Terraform for post-bootstrap state
  • alexellis/openfaas — Same author (alexellis); k3sup commonly used to bootstrap OpenFaaS serverless workloads on K3s

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for cmd/join.go and cmd/install.go SSH operations

The repo has cmd/install_test.go and cmd/join_test.go files that exist but are likely minimal. Given that k3sup's core value is bootstrapping K3s over SSH, these SSH operator tests need comprehensive coverage for edge cases (connection failures, timeout handling, invalid node tokens, etc.). This directly impacts reliability for the main use case.

  • [ ] Examine existing tests in cmd/install_test.go and cmd/join_test.go to identify gaps
  • [ ] Add mock SSH operator tests using pkg/operator/ssh_operator.go interfaces
  • [ ] Test node-token retrieval failure scenarios in cmd/node-token.go
  • [ ] Add tests for concurrent join operations to validate parallel execution
  • [ ] Verify tests run in CI by checking .github/workflows/build.yaml

Add cmd/update_test.go for upgrade path validation

cmd/update.go exists but has no corresponding test file. Since updating K3s clusters is a critical operation, this is a gap. Tests should validate version detection, rollback scenarios, and pre-flight checks before updating live clusters.

  • [ ] Create cmd/update_test.go from scratch
  • [ ] Mock the SSH operator to test K3s version detection logic
  • [ ] Test update command with different version constraints
  • [ ] Add tests for handling failed updates and error recovery
  • [ ] Ensure tests follow the pattern of existing cmd/*_test.go files

Implement GitHub Actions workflow for cross-platform binary testing (cmd/plan.go validation)

The repo has .github/workflows/build.yaml and publish.yaml, but there's no validation that the plan/apply feature (cmd/plan.go, cmd/pro.go) actually works end-to-end. Add a workflow that tests k3sup-pro's plan file parsing and dry-run execution against mock infrastructure to catch breaking changes early.

  • [ ] Review existing .github/workflows/ structure to understand build/publish patterns
  • [ ] Create .github/workflows/test-pro-plan.yaml that validates cmd/plan.go parsing
  • [ ] Add test fixtures for sample plan files in docs/ or hack/
  • [ ] Test plan validation logic without requiring actual SSH (use mocked operators)
  • [ ] Ensure workflow runs on pull requests to catch regressions in plan syntax

🌿Good first issues

  • Add integration test for cmd/update.go (currently no test file exists; cmd/install_test.go and cmd/join_test.go are patterns to follow): Update command lacks test coverage; tests would validate K3s binary version upgrade logic
  • Document cmd/ready.go behavior and add examples to README.md (currently undocumented despite being a shipped command): Users need clarity on cluster health check semantics before dependent tooling runs
  • Create cmd/plan_test.go for plan.go YAML parsing (cmd/plan.go is new Pro feature with no unit tests visible): Plan declarative syntax needs regression tests to prevent breakage as syntax evolves

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 0e44269 — Note ce overlap commands (alexellis)
  • 585e3d0 — Remove one more note (alexellis)
  • 1aa59d4 — Correct k3sup pro to k3sup-pro command (alexellis)
  • ce927dd — Bump go.mod (alexellis)
  • 90ab647 — Bump to Go 1.26 (alexellis)
  • 48e5a16 — Updates on asking for sponsors (alexellis)
  • d0d16bf — Add ascii diagram (alexellis)
  • 23ca623 — Make intro a link (alexellis)
  • bdbf47f — Note on CE EULA (alexellis)
  • 6a73d3b — Add EULA for K3sup Pro (ONLY) (alexellis)

🔒Security observations

  • High · Outdated Go Version — go.mod. The project specifies 'go 1.25.6' in go.mod, which appears to be a future or invalid version number. Go 1.25 does not exist as of the analysis date. This suggests either a configuration error or use of an unreleased version, which may lack security patches and should be clarified. Fix: Update to a stable, released Go version (e.g., 1.21 or 1.22 LTS). Verify the correct version intended and ensure all security patches are applied.
  • High · Potential SSH Key Management Risk — pkg/operator/ssh_operator.go. The codebase uses SSH operations extensively (pkg/operator/ssh_operator.go) for remote K3s installations. SSH key handling and credential management could be vulnerable to improper storage, logging, or transmission if not properly secured. The presence of SSH operator without visible credential management safeguards is concerning. Fix: Implement secure SSH key handling: (1) Use SSH agent forwarding instead of key files when possible, (2) Never log or display SSH keys, (3) Use read-only file permissions (0600) for private keys, (4) Consider using go.crypto/ssh with proper key verification, (5) Implement host key verification to prevent MITM attacks.
  • Medium · Vendored Dependencies Not Updated — vendor/ directory. The project vendors multiple dependencies including docker/cli, containerd/stargz-snapshotter, and other components. Vendored code may not receive security updates automatically and requires manual updates. Several vendored packages appear potentially outdated. Fix: Establish a regular dependency update schedule. Use 'go mod tidy' and 'go mod vendor' regularly. Monitor vendored packages for security advisories. Consider using 'go get -u' periodically and running 'go mod verify' to ensure integrity.
  • Medium · golang.org/x/crypto Aging Version — go.mod. The project uses golang.org/x/crypto v0.48.0, which may contain known vulnerabilities. Cryptographic libraries should be kept up-to-date as they frequently receive security patches. Fix: Update golang.org/x/crypto to the latest available version. Run 'go get -u golang.org/x/crypto' and verify compatibility. Check https://pkg.go.dev/golang.org/x/crypto for any known vulnerabilities.
  • Medium · Remote Code Execution via SSH Command Execution — pkg/operator/exec_operator.go, pkg/operator/ssh_operator.go. The pkg/operator/exec_operator.go and pkg/operator/ssh_operator.go allow execution of arbitrary commands on remote systems. If command arguments are not properly sanitized, this could lead to command injection attacks, particularly if user input is incorporated into K3s installation commands. Fix: Implement strict input validation and sanitization for all user-supplied parameters. Use parameterized command execution (avoid shell interpolation). Whitelist allowed characters in inputs. Consider using Go's os/exec package with explicit argument arrays rather than shell commands. Validate all URLs, paths, and configuration options.
  • Medium · Potential Information Disclosure via Error Messages — cmd/ directory (all command files). The tool performs SSH connections and system operations. Error messages may contain sensitive information (hostnames, paths, environment details) that could be leaked to users or logs. Fix: Sanitize error messages to avoid leaking sensitive information. Implement separate verbose/debug logging modes that are disabled by default. Log sensitive operations to secure audit logs only, not to user-facing output.
  • Low · Missing Input Validation Documentation — cmd/install.go, cmd/join.go, cmd/get.go. The CLI tool accepts various inputs (hosts, paths, configuration options) but there is no visible evidence of comprehensive input validation or sanitization patterns. This could lead to unexpected behavior or security issues. Fix: Add comprehensive input validation for all CLI parameters including: (1) IP address/hostname format validation, (2) Path traversal prevention, (3) Port number validation, (4) File permission verification, (5) Configuration option bounds checking. Document all input constraints.
  • Low · Hardcoded Credentials Risk in Tests — undefined. Test files (cmd/install_test.go, cmd/join_test Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · alexellis/k3sup — RepoPilot