Files
homelab-infrastructure-as-code/03-k8s-infra/CLAUDE.md
T
kasun 6753be7f09
Deploy Proxmox Infra / Pulumi Preview (pull_request) Successful in 1m20s
Deploy Proxmox Infra / Pulumi Deploy (pull_request) Has been skipped
Deploy k8s Infra / Pulumi Preview (pull_request) Successful in 48s
Deploy k8s Infra / Pulumi Deploy (pull_request) Has been skipped
Deploy k8s Apps / Pulumi Preview (pull_request) Successful in 42s
Deploy k8s Apps / Pulumi Deploy (pull_request) Has been skipped
Deploy Monitoring / Pulumi Preview (pull_request) Successful in 49s
Deploy Monitoring / Pulumi Deploy (pull_request) Has been skipped
refactor code
2026-06-12 18:33:09 +02:00

56 lines
2.2 KiB
Markdown

# k8s-infra
This file provides guidance to Claude Code when working in `03-k8s-infra`. See the [repo-root CLAUDE.md](../CLAUDE.md) for shared conventions, deployment order, and CI/CD.
Cluster-level infrastructure for the k3s homelab cluster, deployed via Helm and `@pulumi/kubernetes`. Reads `kubeconfig` from `k8s-bootstrap` via StackReference.
## Common Commands
```bash
npm install
pulumi refresh --yes && pulumi up --yes
```
CI installs the `helm` CLI (`azure/setup-helm`) before running Pulumi.
## Architecture
| Component | What it does |
| --- | --- |
| NFS CSI Driver | `csi-driver-nfs` Helm chart — enables NFS-backed PVCs |
| `truenas-nfs` StorageClass | Backed by an NFS share on TrueNAS (`Retain` reclaim policy) |
| cert-manager | Certificate lifecycle management |
| `letsencrypt-prod` ClusterIssuer | DNS-01 via Cloudflare, issues Let's Encrypt TLS certs |
| Longhorn | Default block storage (`longhorn` StorageClass, 3 replicas) — used by app/monitoring PVCs |
| kube-vip | DaemonSet that ARP-announces a virtual IP for LoadBalancer Services |
| kube-vip-cloud-provider | Allocates LoadBalancer IPs from a single-address pool (`kubeVipAddress`) — k3s's built-in ServiceLB is not used |
| `traefik` ServicePatch | Pins Traefik's LoadBalancer IP to `kubeVipAddress` |
**Export**: `nfsStorageClass = "truenas-nfs"`.
## Required Pulumi config
```bash
pulumi config set --secret truenasHost <truenas-ip>
pulumi config set --secret truenasNfsPath /mnt/pool/k8s
pulumi config set --secret cloudflareApiToken <cf-token>
pulumi config set --secret letsencryptEmail <your-email>
pulumi config set --secret kubeVipAddress <vip-ip>
pulumi config set kubeVipInterface <e.g. eth0>
```
`kubeconfig` is read automatically via StackReference — do not set it here.
## TrueNAS one-time setup (before deploying)
1. Create dataset `pool/k8s`
2. Add an NFS share for that dataset:
- ACL type: POSIX/generic Unix permissions (not SMB/NFSv4 ACLs) on TrueNAS SCALE
- Maproot User / Group: `root` / `root`
- Allowed Hosts/Networks: restrict to the k3s node IPs/CIDR
3. In Network → Allowed Networks, permit your LAN subnet (e.g. `192.168.1.0/24`)
## CI/CD
Workflow: `../.gitea/workflows/03-deploy-k8s-infra.yaml`. Secret: `K8S_INFRA_PULUMI_DEV_YAML`.