infrapuzzle/k8s/AGENTS.md

126 lines
3.8 KiB
Markdown

# 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 <release> <chart> -n <namespace> -f <values-file>
```
* **Kubectl**:
```bash
kubectl apply -f <folder>/<file>.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: `<subdomain>-<domain>-<tld>`
* 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`.