126 lines
3.8 KiB
Markdown
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`.
|
|
|