nlopez/k8s_home
nlopez/k8s_home has 47 GitHub stars and 8 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 04:08 UTC. Last push 2026-11-08.
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Kubernetes
Self-hostedREADME.md
Originalk8s
Kubernetes gitops for my personal infra
Notes
kubeadm
sudo kubeadm init --config kubeadm-init.conf --upload-certs
Run the control plane join command on additional nodes.
Untaint master/control-plane
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
Approve CSRs
This is necessary because we're using serverTLSBootstrap: true in kubeadm.
for csr in $(kubectl get csr --sort-by=.metadata.creationTimestamp -o name); do kubectl certificate approve $csr; done
CNI: Cilium
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.19.2 --namespace kube-system --values apps-helm/cilium/values.yaml
cilium status --wait
kubectl apply --server-side -Rf apps-helm/cilium/manifests
Wait for coredns/control plane running
kubectl get pod --all-namespaces -owide --watch
ArgoCD
helm repo add argo https://argoproj.github.io/argo-helm
helm install --create-namespace --namespace argocd --version 9.0.1 argocd argo/argo-cd --values apps-helm/argocd/values.yaml
argocd login --core
argocd admin initial-password -n argocd
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
export ARGOCD_SVC_IP="$(kubectl get svc -n argocd -l app.kubernetes.io/name=argocd-server -o jsonpath='{.items[*].spec.clusterIP}')"
argocd login "$ARGOCD_SVC_IP" --insecure --username admin
argocd account update-password
1Password Connect
kubectl create namespace 1password --dry-run=client -o yaml | kubectl apply -f -
op read 'op://bamv726zv6zbcfke3cnbwjtnuu/lkbaozihk6xqhrtlcq6vycu2ua/1password-credentials.json' --no-newline > 1password-credentials.json
kubectl create secret generic op-credentials -n 1password --from-file=1password-credentials.json --dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic onepassword-token -n 1password --from-literal=token="$(op read op://bamv726zv6zbcfke3cnbwjtnuu/lshy7xejhopza2xq6qpjqlcw5y/credential --no-newline)" --dry-run=client -o yaml | kubectl apply -f -
Disaster recovery: restoring PV/PVC data after a re-init
kubeadm init wipes etcd, so every PersistentVolume/PersistentVolumeClaim object is lost —
but the underlying data on TrueNAS (nas1.lga1.radoncanyon.com) is untouched, since it's external
to the cluster. Velero (apps-helm/velero) tracks CSI snapshots of the stateful namespaces in
DigitalOcean Spaces, which also survives a re-init, so restoring is normally just velero restore create rather than hand-reconstructing PV/PVC manifests from TrueNAS.
Before a planned re-init, take a fresh on-demand backup so restore doesn't depend on schedule timing:
velero backup create cluster-pre-reinit-$(date +%Y%m%d) \
--include-namespaces atuin,harbor,jellyfin,obsidian-livesync,palworld,palworld-modded,pms,radarr,seadexarr,sonarr,warp
For CNPG-managed namespaces (atuin, harbor), hibernate the Cluster first
(cnpg.io/hibernation: "on" annotation) so the snapshot is transactionally consistent rather than
crash-consistent — see commit 4bd437f7 for the full hibernate/restore dance.
After re-init, restore before the apps AppSet syncs — if it syncs a stateful app's plain
PVC manifest first, that PVC binds to a brand-new empty volume and permanently orphans the real
data. Velero itself, external-snapshotter, democratic-csi, and CloudNativePG are all deployed
by the other AppSet (apps-helm), so bootstrap that one first and hold apps back:
kubectl apply --server-side -f bootstrap/apps-helm.yaml(not the wholebootstrap/dir yet) and wait for Velero,external-snapshotter,democratic-csi-*, andcloudnative-pgto sync healthy — these are what CSI snapshot restore and CNPGClusterrestore depend on.- Wait for the
BackupStorageLocationto reportAvailable:velero backup-location get. velero restore create --from-backup <name>for each namespace that needs its data back.- Only then
kubectl apply --server-side -f bootstrap/apps.yaml(andbootstrap/Application.yaml) so ArgoCD adopts the already-restored PVCs instead of creating fresh ones.
If a namespace isn't covered by any Velero backup (new app, or backup window missed), fall back
to the manual recovery process demonstrated in apps/nas1-mtank-recovery/: reclaim the orphaned
TrueNAS volume as a static PV/PVC, snapshot it, then re-expose that snapshot as the app's PVC
dataSource.
Bootstrap Argo AppSets
Apply the infra ApplicationSet first and wait for it healthy, then the workload apps — this is the
default even on a fresh cluster, not just for recovery, since apps/* workloads (CNPG Clusters,
PVCs) can otherwise race against storage/secrets/networking still coming up:
kubectl apply --server-side -f bootstrap/apps-helm.yaml
# wait for it healthy: kubectl get applications -n argocd -w
kubectl apply --server-side -f bootstrap/apps.yaml -f bootstrap/Application.yaml
apps-helm.yaml itself now uses ArgoCD ApplicationSet Progressive Syncs
(spec.strategy.type: RollingSync) to sync its own three tiers in order — network/secrets,
then storage, then everything else — so a single kubectl apply -f bootstrap/apps-helm.yaml is
enough; you don't need to hand-split that file further.
If you don't care about first-boot ordering (e.g. a disposable test cluster), apply everything at once instead:
kubectl apply --server-side -Rf bootstrap
Renovate
Run renovate locally against the working tree (no GitHub token required):
docker run --rm \
-v $(pwd):/usr/src/app \
-e RENOVATE_PLATFORM=local \
-e LOG_LEVEL=debug \
ghcr.io/renovatebot/renovate \
--dry-run=full
To open actual PRs on GitHub, set RENOVATE_TOKEN to a GitHub PAT with repo scope and drop --dry-run=full:
RENOVATE_TOKEN=<github-pat> docker run --rm \
-e RENOVATE_TOKEN \
-e LOG_LEVEL=debug \
ghcr.io/renovatebot/renovate \
nlopez/k8s_home
Thanks
- Lots of inspiration drawn from nicolerenee/k8s-state.