Recovering ~/.kube
Kubeconfig files are the only credentials your tools use to reach the cluster. Lose them and kubectl, helm, flux, and k9s all stop working. The cluster itself is unaffected — the API server and certificates are still there. You just need new credential files.
Three situations lead here, and each requires different steps:
| Scenario | Cluster state | What you need |
|---|---|---|
| A — Wiped ~/.kube | k0s running on this machine | Re-export the kubeconfig |
| B — New machine, existing cluster | k0s running on another machine | Copy or generate a kubeconfig, set up local tooling |
| C — Fresh start | No cluster anywhere | Install k0s, bootstrap everything |
Scenario A: Wiped ~/.kube on the same machine
Section titled “Scenario A: Wiped ~/.kube on the same machine”The cluster is running locally. You deleted ~/.kube/ or the config files inside it. k0s still has its CA and certs — you just need a fresh export.
-
Re-export the kubeconfig
Terminal window mkdir -p ~/.kubesudo k0s kubeconfig admin > ~/.kube/k0s-admin.confchmod 600 ~/.kube/k0s-admin.confThe project’s
mise.tomlalready setsKUBECONFIG=/var/home/ryan/.kube/k0s-admin.conf, so every tool picks this up when youcdinto the project. Thekbbinary also reads this value frommise.tomldirectly, so it works even outside a mise-activated shell. -
Verify access
Terminal window kubectl get nodesIf the node shows
Ready, you are done. Flux is already running in the cluster, the SOPS age key is already there, TLS certs and/etc/hostsentries are on disk from before. Nothing else to do.
That’s it. Skip to Generating user kubeconfigs if you want RBAC-scoped credentials instead of admin.
Scenario B: New machine, existing cluster elsewhere
Section titled “Scenario B: New machine, existing cluster elsewhere”You rsync’d or cloned the project to a new workstation. k0s is running on the original machine (reachable over the network). The cluster already has Flux, the SOPS age key, and all workloads — you do not need to bootstrap anything on the cluster side.
What you need on the new machine: a kubeconfig pointing at the remote API server, local tooling, TLS for the browser, and DNS entries.
-
Get a kubeconfig
You have two options.
Option A — Copy the admin config from the cluster machine:
Terminal window mkdir -p ~/.kubescp cluster-host:~/.kube/k0s-admin.conf ~/.kube/k0s-admin.confchmod 600 ~/.kube/k0s-admin.confThe copied config has
server: https://localhost:6443— edit it to point at the cluster machine’s IP or hostname:Terminal window sed -i 's|https://localhost:6443|https://cluster-host:6443|' ~/.kube/k0s-admin.confOption B — Generate a user kubeconfig on the cluster machine:
SSH into the cluster machine and run:
Terminal window sudo k0s kubeconfig create --groups team-admins ryanThis prints a kubeconfig to stdout. Save it locally as
~/.kube/k0s-ryan.confand updatemise.tomlto point at it. The server address in the generated config should already reflect the cluster machine’s hostname. -
Verify access
Terminal window kubectl get nodesIf this fails, check that port 6443 is open on the cluster machine’s firewall and reachable from your network.
-
Install tools
The project’s
mise.tomldeclares all required tools (kubectl, flux, helm, k9s, mkcert, etc.). Trust the config and install:Terminal window mise trust allmise install -
Build the CLI
Terminal window cd .mise/cli && bun run build.ts && cd ../.. -
Set up local TLS
mkcert creates a local CA on your machine so browsers trust
*.k8s.localcertificates. This is per-machine — the cluster’s TLS secret already exists, but your browser needs the local CA root:Terminal window kb tls mkcert-setupSee Local TLS with mkcert for details.
-
Add DNS entries
Terminal window grep -q k8s.local /etc/hosts || sudo tee -a /etc/hosts <<< '127.0.0.1 docs.k8s.local grafana.k8s.local traefik.k8s.local' -
Start the dev environment
Terminal window kb dev startThis builds container images locally, applies the dev overlay, and forwards ports. Flux is already reconciling on the cluster —
kb dev starttemporarily suspends it, applies the dev overlay, and resumes on exit.For live editing with Astro HMR:
Terminal window kb dev start --dev
What you do NOT need to do: bootstrap Flux (already running), inject the SOPS age key (already in the cluster), or open firewall ports on the cluster (already configured). All cluster-side state is intact.
Scenario C: Fresh start — no cluster anywhere
Section titled “Scenario C: Fresh start — no cluster anywhere”A blank machine with nothing set up. No k0s, no cluster, no kubeconfig. This is the full sequence.
-
Install k0s
Terminal window curl --proto '=https' --tlsv1.2 -sSf https://get.k0s.sh | sudo shSee Installing k0s for manual install, SELinux configuration, and multi-node setups.
-
Open firewall ports
Terminal window sudo firewall-cmd --permanent --add-port=6443/tcpsudo firewall-cmd --permanent --add-port=10250/tcpsudo firewall-cmd --permanent --zone=trusted --add-interface=kube-bridgesudo firewall-cmd --permanent --add-masqueradesudo firewall-cmd --reload -
Create the cluster
Terminal window sudo k0s install controller --enable-worker --no-taintssudo k0s start--enable-workerruns a kubelet on the same node.--no-taintslets workloads schedule there. -
Export the kubeconfig
Terminal window mkdir -p ~/.kubesudo k0s kubeconfig admin > ~/.kube/k0s-admin.confchmod 600 ~/.kube/k0s-admin.conf -
Verify the cluster
Terminal window kubectl get nodesWait for the node to reach
Ready(usually under two minutes). -
Install tools
Terminal window mise trust allmise install -
Build the CLI
Terminal window cd .mise/cli && bun run build.ts && cd ../.. -
Set up local TLS
Terminal window kb tls mkcert-setup -
Add DNS entries
Terminal window sudo tee -a /etc/hosts <<< '127.0.0.1 docs.k8s.local grafana.k8s.local traefik.k8s.local' -
Inject the SOPS age key
Flux needs the age private key to decrypt secrets. Retrieve it from your password manager (or KeePass) and inject it:
Terminal window echo "AGE-SECRET-KEY-..." | kubectl create secret generic sops-age \--namespace=flux-system \--from-file=age.agekey=/dev/stdinIf you are creating a brand-new cluster (not restoring an existing one), generate a fresh keypair instead:
Terminal window age-keygen -o /tmp/age.keycat /tmp/age.key | kubectl create secret generic sops-age \--namespace=flux-system \--from-file=age.agekey=/dev/stdinAdd the public key to
.sops.yamlunder a newcreation_rulesentry, then re-encrypt any secrets. See Managing Secrets with SOPS for the full workflow. Store the private key in your password manager and delete/tmp/age.key. -
Bootstrap Flux
Terminal window mise run flux-bootstrapThis installs the Flux controllers, commits component manifests to
clusters/vale/flux-system/, and starts reconciling the cluster toward the declared Git state. It needs a GitHub token — the command reads it from the encrypted.env.json. See Bootstrapping Flux. -
Start the dev environment
Terminal window kb dev startOr with live editing:
Terminal window kb dev start --devOnce running, open https://docs.k8s.local.
Step comparison
Section titled “Step comparison”Which steps apply to which scenario:
| Step | A (wiped config) | B (new machine) | C (fresh start) |
|---|---|---|---|
| Install k0s | - | - | yes |
| Firewall ports | - | - | yes |
| Create cluster | - | - | yes |
| Export/copy kubeconfig | yes | yes | yes |
| Install tools (mise) | - | yes | yes |
| Build CLI | - | yes | yes |
| Local TLS (mkcert) | - | yes | yes |
| DNS entries (/etc/hosts) | - | yes | yes |
| Inject SOPS age key | - | - | yes |
| Bootstrap Flux | - | - | yes |
| Start dev environment | optional | yes | yes |
Generating user kubeconfigs
Section titled “Generating user kubeconfigs”The admin config gives full cluster access. For RBAC-scoped permissions, generate user certificates on the machine running k0s:
sudo uv run scripts/create-users/generate-kubeconfigs.py generatecp /tmp/kubeconfigs/ryan.kubeconfig ~/.kube/k0s-ryan.confchmod 600 ~/.kube/k0s-ryan.confusers.yaml defines users, group memberships, and certificate expiry durations. To switch from admin to user credentials, update mise.toml:
[env]KUBECONFIG = "~/.kube/k0s-ryan.conf"Cloud cluster configs
Section titled “Cloud cluster configs”If you also use managed clusters, regenerate configs from the provider:
# DigitalOceankb infra do kubeconfig --path ~/.kube/do-cluster.conf
# GKEkb infra gke kubeconfig --path ~/.kube/gke-cluster.confVerifying everything
Section titled “Verifying everything”Inspect all kubeconfig files — the script parses certificates and shows username, groups, server, and expiry:
uv run scripts/create-users/generate-kubeconfigs.py inspect ~/.kube/*.confCheck cluster health:
kubectl get nodeskubectl get pods -Aflux get all