refactor(k8s): Reorganize into 5-layer structure with production kustomizations
This commit is contained in:
@@ -0,0 +1,319 @@
|
||||
# k8s/ingress/ingress.yaml
|
||||
# Ingress rules for all homelab services.
|
||||
# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.homelab.com)
|
||||
# as its default-ssl-certificate. No per-rule tls: blocks or cert-manager annotations
|
||||
# are needed — cert-manager manages one cert, nginx uses it for all hosts.
|
||||
#
|
||||
# DNS: *.riotpiao.homelab.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN).
|
||||
|
||||
# ── Grafana ───────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: grafana
|
||||
namespace: logging
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: grafana.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: grafana
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
# ── Loki (API access for external tools) ─────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: loki
|
||||
namespace: logging
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: loki.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: loki
|
||||
port:
|
||||
number: 3100
|
||||
|
||||
---
|
||||
# ── Authentik ─────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: authentik
|
||||
namespace: iam
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: authentik.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: authentik-server
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
# ── Vault ─────────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: vault
|
||||
namespace: iam
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: vault.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: vault
|
||||
port:
|
||||
number: 8200
|
||||
|
||||
---
|
||||
# ── MinIO console (storage namespace) ────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio
|
||||
namespace: storage
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/affinity: "cookie"
|
||||
nginx.ingress.kubernetes.io/session-cookie-name: "minio-console-affinity"
|
||||
nginx.ingress.kubernetes.io/session-cookie-max-age: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: minio.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio-console
|
||||
port:
|
||||
number: 9001
|
||||
|
||||
---
|
||||
# ── MinIO S3 API ──────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minio-api
|
||||
namespace: storage
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: minio-api.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: minio
|
||||
port:
|
||||
number: 9000
|
||||
|
||||
---
|
||||
# ── Prometheus ────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: prometheus
|
||||
namespace: monitoring
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: prometheus.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: prometheus-kube-prometheus-prometheus
|
||||
port:
|
||||
number: 9090
|
||||
|
||||
---
|
||||
# ── Portainer ─────────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: portainer
|
||||
namespace: dashboard
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: portainer.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: portainer
|
||||
port:
|
||||
number: 9000
|
||||
|
||||
---
|
||||
# ── Forgejo (git forge + OCI registry UI) ────────────────────────────────────
|
||||
# nginx terminates TLS using the wildcard cert, then proxies plain HTTP to
|
||||
# Forgejo on port 3000. ROOT_URL stays https:// so Forgejo generates correct URLs.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: cicd
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: forgejo.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: forgejo-gitea-http
|
||||
port:
|
||||
number: 3000
|
||||
|
||||
---
|
||||
# ── Argo CD (cicd namespace) ──────────────────────────────────────────────────
|
||||
# argocd-server runs HTTPS internally — nginx proxies via backend-protocol: HTTPS.
|
||||
# proxy-ssl-verify: off because argocd-server's pod cert is self-signed (not homelab-ca).
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: argocd
|
||||
namespace: cicd
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
|
||||
nginx.ingress.kubernetes.io/proxy-ssl-verify: "off"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: argocd.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: argocd-server
|
||||
port:
|
||||
number: 443
|
||||
|
||||
---
|
||||
# ── Longhorn UI ───────────────────────────────────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: longhorn
|
||||
namespace: longhorn-system
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: longhorn.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: longhorn-frontend
|
||||
port:
|
||||
number: 80
|
||||
|
||||
---
|
||||
# ── Temporal Web UI ────────────────────────────────────────────────────────────
|
||||
# Temporal workflow orchestration Web UI
|
||||
# TLS: wildcard cert managed by cert-manager, served by nginx default-ssl-certificate
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: temporal
|
||||
namespace: temporal
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: temporal.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: temporal-web
|
||||
port:
|
||||
number: 8080
|
||||
|
||||
---
|
||||
# ── kmsvc (SQS/Kafka REST API) ────────────────────────────────────────────
|
||||
# SQS-compatible messaging API via kmsvc management service
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: kmsvc
|
||||
namespace: sqs
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: kmsvc.riotpiao.homelab.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: management-service
|
||||
port:
|
||||
number: 8080
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
namespace: ingress-nginx
|
||||
resources: []
|
||||
# Ingress controller deployed via Helm chart
|
||||
@@ -0,0 +1,78 @@
|
||||
# k8s/ingress/nginx-values.yaml
|
||||
# Nginx Ingress Controller — bare-metal homelab config.
|
||||
# LoadBalancer service with Cilium LB-IPAM assigns fixed IP (192.168.1.160).
|
||||
# Access services at https://grafana.riotpiao.homelab.com (80/443 via LoadBalancer).
|
||||
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
|
||||
# Single wildcard cert served for every *.riotpiao.homelab.com host.
|
||||
# Applied by the ingress-nginx presync hook (wildcard-cert.yaml) before nginx starts.
|
||||
# nginx hot-reloads when cert-manager renews homelab-tls — no restart needed.
|
||||
extraArgs:
|
||||
default-ssl-certificate: "ingress-nginx/homelab-tls"
|
||||
|
||||
hostPort:
|
||||
enabled: true
|
||||
ports:
|
||||
http: 80
|
||||
https: 443
|
||||
|
||||
# TCP proxy: forward port 2222 on every node → Forgejo SSH service.
|
||||
# This lets `git clone [email protected]:repo` work via the
|
||||
# same hostname as HTTPS without a separate LoadBalancer IP for SSH.
|
||||
tcp:
|
||||
2222: "cicd/forgejo-gitea-ssh:2222"
|
||||
|
||||
# Service as LoadBalancer — Cilium LB-IPAM assigns fixed IP.
|
||||
service:
|
||||
type: LoadBalancer
|
||||
annotations:
|
||||
io.cilium/lb-ipam-ips: "192.168.1.160"
|
||||
|
||||
# Allow the controller to land on the control-plane node.
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
|
||||
# Use the ingress-nginx IngressClass by default.
|
||||
ingressClassResource:
|
||||
default: true
|
||||
|
||||
# Required when using hostPort so DNS resolves correctly inside the pod.
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
|
||||
# Reduce noise in a single-admin homelab.
|
||||
admissionWebhooks:
|
||||
enabled: false
|
||||
|
||||
# ── Connection timeouts to upstreams ──────────────────────────────────────────
|
||||
# Increased to tolerate 5+ second pod-to-pod network latency spikes.
|
||||
# Default: 60s for all — acceptable but explicitly set for clarity.
|
||||
config:
|
||||
upstream-connect-timeout: "60"
|
||||
upstream-send-timeout: "60"
|
||||
upstream-read-timeout: "60"
|
||||
keepalive-timeout: "65"
|
||||
keepalive-requests: "100"
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
|
||||
# RED metrics (rate/errors/duration) for every host fronted by this controller —
|
||||
# every exposed service in the cluster goes through here, so this single block
|
||||
# is the cluster-wide "latency and availability" signal. Prometheus auto-discovers
|
||||
# the ServiceMonitor (serviceMonitorSelectorNilUsesHelmValues: false in prometheus-values.yaml).
|
||||
metrics:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
namespace: ingress-nginx
|
||||
interval: 30s
|
||||
scrapeTimeout: 60s
|
||||
@@ -0,0 +1,22 @@
|
||||
# k8s/ingress/wildcard-cert.yaml
|
||||
# Single wildcard TLS certificate for all *.riotpiao.homelab.com services.
|
||||
# Lives in the ingress-nginx namespace and is set as nginx's default-ssl-certificate,
|
||||
# so every ingress host gets it automatically — no per-service TLS blocks needed.
|
||||
#
|
||||
# Renewal: cert-manager auto-renews 30 days before expiry (renewBefore: 720h).
|
||||
# nginx detects the secret update via its K8s watch and hot-reloads — no pod restart.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: homelab-tls
|
||||
namespace: ingress-nginx
|
||||
spec:
|
||||
secretName: homelab-tls
|
||||
dnsNames:
|
||||
- "*.riotpiao.homelab.com"
|
||||
- "riotpiao.homelab.com"
|
||||
issuerRef:
|
||||
name: homelab-ca
|
||||
kind: ClusterIssuer
|
||||
duration: 8760h # 1 year
|
||||
renewBefore: 720h # renew 30 days before expiry
|
||||
Reference in New Issue
Block a user