diff --git a/k8s/AGENTS.md b/k8s/AGENTS.md new file mode 100644 index 0000000..a346fcc --- /dev/null +++ b/k8s/AGENTS.md @@ -0,0 +1,125 @@ +# AGENTS.md + +> [!NOTE] +> This file describes the constraints and conventions for the `k8s` directory, which contains deployments for the **haumdaucher.de** Kubernetes cluster. + +## Project Overview +This directory contains the Kubernetes manifests and Helm charts for a single-node Kubernetes cluster (Haumdaucher). +* **Domain**: `*.haumdaucher.de` +* **Orchestration**: Self-managed Kubernetes (single node). +* **Ingress**: `ingress-nginx` +* **SSL**: `cert-manager` (LetsEncrypt) + +## Directory Structure +* **Top-level folders**: Each folder corresponds to a Kubernetes **namespace**. + * Example: `mailu/` contains resources for the `mailu` namespace. +* **Documentation**: `README.md` is the **authoritative source** for deployment commands. Always check it before running commands. + +## Code Style & Conventions +* **Helm Version**: Helm 3 (`helm`) is used. +* **Implementation Order**: Top-down. +* **Naming**: Namespaces matches folder names. +* **Formatting**: Standard YAML conventions. + +## Security & Secrets +> [!IMPORTANT] +> **Git-Crypt is enforced.** +> Do not touch encrypted files unless you have the key and know how to unlock them. + +**Encrypted File Patterns**: +* `*.secret` +* `*.secret.yaml` +* `*.secret.values` +* `*.secret.sh` + +## Deployment Instructions +**Always consult `README.md` first.** Deployments vary between Helm charts and raw manifests. + +### Common Patterns +* **Helm**: + ```bash + helm upgrade --install -n -f + ``` +* **Kubectl**: + ```bash + kubectl apply -f /.yaml + ``` + +### Operational Tasks +* **Cleanup Error Pods**: + ```bash + kubectl get pods | grep Error | cut -d' ' -f 1 | xargs kubectl delete pod + ``` + +## Ingress Configuration +Ingress resources **must** follow these strict conventions to work with the cluster's ingress controller (`nginx`) and certificate manager (`cert-manager`). + +### Annotations +All Ingress resources must include: +```yaml +annotations: + kubernetes.io/ingress.class: "nginx" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + kubernetes.io/tls-acme: "true" + # Standard nginx tweaks + nginx.ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" +``` + +### Hostnames & TLS +* **Domain**: Use a subdomain of `haumdaucher.de` or `moritzgraf.de`. +* **TLS Secret Name**: Must use **hyphens** instead of dots. + * Pattern: `--` + * Example: `n8n.moritzgraf.de` -> `n8n-moritzgraf-de` + +### Example +```yaml +spec: + ingressClassName: nginx + tls: + - hosts: + - n8n.moritzgraf.de + secretName: n8n-moritzgraf-de + rules: + - host: n8n.moritzgraf.de + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: n8n + port: + number: 5678 +``` + +## Storage / Persistence +The cluster uses **OpenEBS** for dynamic local storage provisioning. + +### PersistentVolumeClaims (PVC) +* **Provisioner**: `openebs.io/local` (or similar, managed via `openebs-hostpath`). +* **StorageClass**: `openebs-hostpath`. +* **AccessMode**: Typically `ReadWriteOnce` (RWO) as it's local storage. + +To request storage, simply create a PVC or configure Helm charts to use the default storage class (or explicitly `openebs-hostpath`). + +```yaml +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: my-data +spec: + storageClassName: openebs-hostpath + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +``` + +## Deployment Constraints +* **Resources**: Always define `requests` and `limits` for CPU and Memory to ensure fair scheduling on the single node. +* **Namespaces**: Every application gets its own namespace. +* **Secrets**: Encrypt all secrets using `git-crypt`. +