Hey 🌸 I'm Shikanime Deva, this repository contains the Kubernetes manifests for my clusters.
This repo is organized around Kustomize:
apps/contains application manifests (bases, optional components, and per-cluster overlays)clusters/contains cluster entrypoints that compose shared cluster bits + app overlaysbootstraps/contains cluster bootstrap inputs (controllers/operators installation lives here)skaffold.yamlprovides renderable profiles that point at the cluster overlay entrypoints
Each app is typically structured like:
apps/<app>/base/: app resources that are common everywhereapps/<app>/components/: optional Kustomize components (e.g.tls/,ftp/,v4l/)apps/<app>/overlays/<cluster>/: cluster-specific patches/configapps/<app>/overlays/<cluster>-tailnet/: cluster-specific overlays for the “tailnet” flavor (when applicable)
Each cluster typically looks like:
clusters/<cluster>/base/: namespaces, shared PVCs, default policies, etc.clusters/<cluster>/components/: cluster-wide components (e.g.tls/,tailscale/,longhorn/)clusters/<cluster>/overlays/<overlay>/: build entrypoints that compose cluster base + components + selected app overlays
For example, clusters/nishir/overlays/tailnet/kustomization.yaml pulls in
cluster components and a list of apps/*/overlays/nishir-tailnet, plus the
cluster base.
This repository is intentionally split into two concerns:
- Compose and configure cluster services and apps with Kustomize (
clusters/+apps/) - Bootstrap the controllers/operators those manifests depend on (
bootstraps/)
The Kustomize overlays assume the underlying controllers/operators already
exist. Those are installed out-of-band using the manifests in bootstraps/.
bootstraps/telsha/containsHelmChartresources (helmchart.yaml)
This repo currently defines two cluster trees:
clusters/nishir/(overlay:tailnet, components: kubevirt, longhorn, tailscale, tls, victoriametrics)clusters/telsha/(overlay:tailnet, component: tailscale)
The “cluster services” in this repo are mostly configuration and glue for controllers installed during bootstrap.
- TLS / trust distribution:
- cert-manager resources (issuers/certs) under
clusters/<cluster>/components/tls/ - trust-manager
Bundleto publish CA material to workloads as a ConfigMap
- cert-manager resources (issuers/certs) under
- Tailnet ingress:
- Tailscale Operator credentials under
clusters/<cluster>/components/tailscale/
- Tailscale Operator credentials under
- Storage:
- Longhorn settings, storage class, and recurring jobs under
clusters/<cluster>/components/longhorn/
- Longhorn settings, storage class, and recurring jobs under
- Observability:
- VictoriaMetrics stack under
clusters/<cluster>/components/victoriametrics/ - Grafana is part of the VictoriaMetrics stack and is exposed over Tailscale
ingress in the
nishiroverlay
- VictoriaMetrics stack under
- Vertical Pod Autoscaler:
- many apps include
vpa.yamland expect a VPA controller to be present
- many apps include
- Virtualization (KubeVirt):
- installed via the version-pinned operator manifest under
infrastructure/kubevirt/base/operator.yamlplus aKubeVirtCR (kubevirt-cr.yaml), reconciled by theinfrastructure-kubevirtFluxKustomization - KubeVirt has no official Helm chart; the upstream install method is the
operator + CR manifest pair, so this component diverges from the
HelmReleasepattern used elsewhere - the operator manifest already sets the
kubevirt-systemnamespace to theprivilegedPod Security Standard - host prerequisites (per node that should run VMs):
- hardware virtualization exposed as
/dev/kvm— requires Intel VT-x (vmx) or AMD-V (svm) in/proc/cpuinfo; check withls -l /dev/kvm - if nodes are themselves virtual machines, nested virtualization must
be enabled on the hypervisor, otherwise
/dev/kvmis absent - absent
/dev/kvmfalls back to slow software emulation unless theKubeVirtCR setsspec.configuration.developerConfiguration.useEmulation virt-handlerruns as a DaemonSet on every node; VM scheduling keys off thenodes.kubevirt.io/resource/kvmlabel that KubeVirt publishes when/dev/kvmis present (node-feature-discovery is already deployed)- VM disks need a
StorageClass— Longhorn is present; pair with CDI forDataVolumeimports (not yet installed in this repo) - mixed
amd64/arm64nodes are supported, but each node still needs/dev/kvmfor its architecture
- hardware virtualization exposed as
- installed via the version-pinned operator manifest under
Most apps follow the same pattern:
- Workload:
DeploymentorStatefulSetinapps/<app>/base/ - Network:
Service+Ingressinapps/<app>/base/- generic ingress shape lives in base
- tailnet overlays own the rendered
ingress.yamland setingressClassName: tailscaleplus Tailscale annotations (example: ingress.yaml) - cluster-local internal hosts are prefixed where needed, such as
grafana
- Storage: a
PVCinapps/<app>/overlays/<cluster>/(or*-tailnet/) bound to a LonghornPV - Secrets/config: stored as
*.enc.*and fed intosecretGenerator(see Secrets)
Sensitive values are stored encrypted in-repo and materialized at render/apply time.
- Encrypted files use the
*.enc.*naming pattern (examples:.enc.env,config.enc.yaml). - Decrypted outputs are derived by stripping
.enc.from the filename (example:.enc.env→.env). - Never commit decrypted outputs. Change the encrypted source instead.
