Initial commit: imcu.ro HA k3s cluster manifests

- 3-node HA cluster (k3s v1.36.3+k3s1, embedded etcd) on Hetzner
- Netbird VPN mesh (wt0) for all cluster traffic
- Longhorn distributed storage (2 replicas, /var/lib/longhorn/)
- Traefik ingress (3 replicas, LoadBalancer on all node IPs)
- cert-manager with Let's Encrypt (auto-renewing TLS)
- Gitea (git + container registry) with SQLite on Longhorn
- 4 migrated workloads: wolsey, school-games (3 variants), randomly
- All HelmCharts and workload manifests as YAML
- deploy.sh for one-shot cluster setup
This commit is contained in:
Mihai Cimpoesu
2026-08-16 21:34:36 +03:00
commit 703c229dd2
16 changed files with 1439 additions and 0 deletions
+146
View File
@@ -0,0 +1,146 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: wolsey
name: wolsey
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: wolsey
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: wolsey
spec:
containers:
- env:
- name: PORT
value: '3000'
- name: HOSTNAME
value: 0.0.0.0
- name: NODE_ENV
value: production
- name: CONTENT_ROOT
value: /content
image: gitea.imcu.ro/homeschool/school:e76d244
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 3000
scheme: HTTP
initialDelaySeconds: 15
periodSeconds: 20
successThreshold: 1
timeoutSeconds: 1
name: wolsey
ports:
- containerPort: 3000
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: 3000
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: '1'
memory: 768Mi
requests:
cpu: 50m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /content
name: content
readOnly: true
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: gitea-registry
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: content
persistentVolumeClaim:
claimName: wolsey-content
---
apiVersion: v1
kind: Service
metadata:
name: wolsey-service
namespace: default
spec:
clusterIP: 10.43.31.159
clusterIPs:
- 10.43.31.159
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- port: 80
protocol: TCP
targetPort: 3000
selector:
app: wolsey
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
finalizers:
- kubernetes.io/pvc-protection
name: wolsey-content
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: longhorn
volumeMode: Filesystem
volumeName: pvc-06d36938-7042-4bcf-aa28-a12e695e0779
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wolsey-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- host: wolsey.imcu.ro
http:
paths:
- backend:
service:
name: wolsey-service
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- wolsey.imcu.ro
secretName: wolsey-imcu-ro-tls