Initial: Add all homelab manifests

This commit is contained in:
2026-03-20 00:05:50 +00:00
commit b538e87d69
33 changed files with 3036 additions and 0 deletions

69
k8s/gitea/deployment.yaml Normal file
View File

@@ -0,0 +1,69 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
nodeSelector:
kubernetes.io/hostname: rnk-wrk01
initContainers:
- name: wait-for-postgres
image: busybox
command: ['sh', '-c', 'until nc -z gitea-postgres 5432; do echo waiting; sleep 2; done']
containers:
- name: gitea
image: gitea/gitea:latest
ports:
- containerPort: 3000
name: web
- containerPort: 22
name: ssh
env:
- name: GITEA__database__DB_TYPE
value: postgres
- name: GITEA__database__HOST
value: gitea-postgres:5432
- name: GITEA__database__NAME
value: gitea
- name: GITEA__database__USER
value: gitea
- name: GITEA__database__PASSWD
valueFrom:
secretKeyRef:
name: gitea-secret
key: postgres-password
- name: GITEA__server__DOMAIN
value: gitea.192.168.11.180.nip.io
- name: GITEA__server__ROOT_URL
value: http://gitea.192.168.11.180.nip.io
- name: GITEA__server__SSH_DOMAIN
value: gitea.192.168.11.180.nip.io
- name: GITEA__server__SSH_PORT
value: "22"
- name: GITEA__security__INSTALL_LOCK
value: "true"
- name: TZ
value: "Europe/Vienna"
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-data

20
k8s/gitea/ingress.yaml Normal file
View File

@@ -0,0 +1,20 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-web
namespace: gitea
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
ingressClassName: traefik
rules:
- host: gitea.192.168.11.180.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-web
port:
number: 3000

View File

@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- secret.yaml
- pvc.yaml
- postgres.yaml
- deployment.yaml
- service.yaml
- ingress.yaml

4
k8s/gitea/namespace.yaml Normal file
View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: gitea

60
k8s/gitea/postgres.yaml Normal file
View File

@@ -0,0 +1,60 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-postgres
namespace: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea-postgres
template:
metadata:
labels:
app: gitea-postgres
spec:
nodeSelector:
kubernetes.io/hostname: rnk-wrk01
containers:
- name: postgres
image: postgres:16-alpine
env:
- name: POSTGRES_DB
value: gitea
- name: POSTGRES_USER
value: gitea
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: gitea-secret
key: postgres-password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-postgres
---
apiVersion: v1
kind: Service
metadata:
name: gitea-postgres
namespace: gitea
spec:
selector:
app: gitea-postgres
ports:
- port: 5432
targetPort: 5432

25
k8s/gitea/pvc.yaml Normal file
View File

@@ -0,0 +1,25 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-data
namespace: gitea
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-postgres
namespace: gitea
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 2Gi

29
k8s/gitea/service.yaml Normal file
View File

@@ -0,0 +1,29 @@
apiVersion: v1
kind: Service
metadata:
name: gitea-web
namespace: gitea
spec:
type: ClusterIP
selector:
app: gitea
ports:
- name: web
port: 3000
targetPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: gitea-ssh
namespace: gitea
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.11.182
spec:
type: LoadBalancer
selector:
app: gitea
ports:
- name: ssh
port: 22
targetPort: 22

View File

@@ -0,0 +1,18 @@
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: homelab-pool
namespace: metallb-system
spec:
addresses:
- 192.168.11.180-192.168.11.199
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: homelab-l2
namespace: metallb-system
spec:
ipAddressPools:
- homelab-pool

View File

@@ -0,0 +1,85 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: omada-mcp
namespace: omada-mcp
labels:
app.kubernetes.io/name: omada-mcp
app.kubernetes.io/version: latest
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: omada-mcp
template:
metadata:
labels:
app.kubernetes.io/name: omada-mcp
spec:
containers:
- name: omada-mcp
image: jmtvms/tplink-omada-mcp:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 3000
protocol: TCP
env:
- name: MCP_SERVER_USE_HTTP
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: MCP_SERVER_USE_HTTP
- name: MCP_HTTP_BIND_ADDR
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: MCP_HTTP_BIND_ADDR
- name: OMADA_BASE_URL
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: OMADA_BASE_URL
- name: OMADA_CLIENT_ID
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: OMADA_CLIENT_ID
- name: OMADA_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: OMADA_CLIENT_SECRET
- name: OMADA_OMADAC_ID
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: OMADA_OMADAC_ID
- name: OMADA_STRICT_SSL
valueFrom:
secretKeyRef:
name: omada-mcp-credentials
key: OMADA_STRICT_SSL
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 256Mi
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 15
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
failureThreshold: 3
restartPolicy: Always

View File

@@ -0,0 +1,11 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: omada-mcp
resources:
- namespace.yaml
- secret.yaml
- deployment.yaml
- service.yaml

View File

@@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: omada-mcp
labels:
app.kubernetes.io/name: omada-mcp

View File

@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: omada-mcp
namespace: omada-mcp
labels:
app.kubernetes.io/name: omada-mcp
spec:
selector:
app.kubernetes.io/name: omada-mcp
ports:
- name: http
protocol: TCP
port: 3000
targetPort: 3000
type: NodePort

View File

@@ -0,0 +1,58 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: pihole
namespace: pihole
labels:
app: pihole
spec:
replicas: 1
selector:
matchLabels:
app: pihole
template:
metadata:
labels:
app: pihole
spec:
containers:
- name: pihole
image: pihole/pihole:latest
env:
- name: TZ
value: "Europe/Berlin"
- name: WEBPASSWORD
valueFrom:
secretKeyRef:
name: pihole-secret
key: password
- name: PIHOLE_DNS_
value: "1.1.1.1;1.0.0.1"
- name: DNSMASQ_LISTENING
value: "all"
ports:
- containerPort: 80
name: web
protocol: TCP
- containerPort: 53
name: dns-tcp
protocol: TCP
- containerPort: 53
name: dns-udp
protocol: UDP
volumeMounts:
- name: pihole-data
mountPath: /etc/pihole
- name: dnsmasq-data
mountPath: /etc/dnsmasq.d
securityContext:
capabilities:
add:
- NET_ADMIN
volumes:
- name: pihole-data
persistentVolumeClaim:
claimName: pihole-data
- name: dnsmasq-data
persistentVolumeClaim:
claimName: pihole-dnsmasq

23
k8s/pihole/ingress.yaml Normal file
View File

@@ -0,0 +1,23 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pihole-web
namespace: pihole
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
tls:
- hosts:
- pihole.192.168.11.180.nip.io
rules:
- host: pihole.192.168.11.180.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pihole-web
port:
number: 80

View File

@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: pihole
resources:
- namespace.yaml
- pvc.yaml
- deployment.yaml
- services.yaml
- ingress.yaml

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: pihole

26
k8s/pihole/pvc.yaml Normal file
View File

@@ -0,0 +1,26 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pihole-data
namespace: pihole
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pihole-dnsmasq
namespace: pihole
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 128Mi

56
k8s/pihole/services.yaml Normal file
View File

@@ -0,0 +1,56 @@
---
# DNS TCP Service (LoadBalancer with fixed IP)
apiVersion: v1
kind: Service
metadata:
name: pihole-dns-tcp
namespace: pihole
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.11.181
metallb.universe.tf/allow-shared-ip: pihole-dns
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: pihole
ports:
- name: dns-tcp
port: 53
targetPort: 53
protocol: TCP
---
# DNS UDP Service (LoadBalancer with fixed IP)
apiVersion: v1
kind: Service
metadata:
name: pihole-dns-udp
namespace: pihole
annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.11.181
metallb.universe.tf/allow-shared-ip: pihole-dns
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: pihole
ports:
- name: dns-udp
port: 53
targetPort: 53
protocol: UDP
---
# Web UI Service (ClusterIP, exposed via Ingress)
apiVersion: v1
kind: Service
metadata:
name: pihole-web
namespace: pihole
spec:
type: ClusterIP
selector:
app: pihole
ports:
- name: web
port: 80
targetPort: 80
protocol: TCP