Compare commits

..

2 commits

Author SHA1 Message Date
root
49cd3e023e Forgejo + Longhorn mit Let's Encrypt, Traefik-Import
All checks were successful
Talos Platform Deploy / deploy (push) Successful in 15s
2026-11-13 22:39:17 +01:00
root
c9cd360fd3 last 2 2026-11-13 22:34:18 +01:00
7 changed files with 134 additions and 2 deletions

View file

@ -0,0 +1,5 @@
apiVersion: v2
name: forgejo-proxy
description: Traefik-Route forgejo.boday-it.ch -> Forgejo auf BITCLAW01 (ausserhalb des Clusters)
type: application
version: 0.1.0

View file

@ -0,0 +1,23 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: forgejo
annotations:
cert-manager.io/cluster-issuer: {{ .Values.clusterIssuer | quote }}
spec:
ingressClassName: traefik
tls:
- secretName: forgejo-tls
hosts:
- {{ .Values.host | quote }}
rules:
- host: {{ .Values.host | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: forgejo-external
port:
name: https

View file

@ -0,0 +1,9 @@
# Interner Hop Traefik -> nginx auf BITCLAW01 nutzt das selbstsignierte Zertifikat (CN registry.local).
# Nach aussen liefert Traefik das gültige Let's-Encrypt-Zertifikat aus.
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: forgejo-transport
spec:
serverName: {{ .Values.backend.serverName | quote }}
insecureSkipVerify: true

View file

@ -0,0 +1,30 @@
# Service ohne Selector: zeigt auf einen Host ausserhalb des Clusters (EndpointSlice unten)
apiVersion: v1
kind: Service
metadata:
name: forgejo-external
annotations:
traefik.ingress.kubernetes.io/service.serversscheme: https
traefik.ingress.kubernetes.io/service.serverstransport: {{ .Release.Namespace }}-forgejo-transport@kubernetescrd
spec:
ports:
- name: https
port: 443
protocol: TCP
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: forgejo-external-1
labels:
kubernetes.io/service-name: forgejo-external
addressType: IPv4
ports:
- name: https
port: {{ .Values.backend.port }}
protocol: TCP
endpoints:
- addresses:
- {{ .Values.backend.ip | quote }}
conditions:
ready: true

View file

@ -0,0 +1,6 @@
host: forgejo.boday-it.ch
clusterIssuer: letsencrypt-prod
backend:
ip: 172.25.65.20 # BITCLAW01
port: 3005 # nginx (HTTPS) vor Forgejo; von den Talos-Nodes aus bereits freigegeben
serverName: registry.local

44
main.tf
View file

@ -50,6 +50,12 @@ variable "longhorn_host" {
default = "longhorn.boday.lan"
}
# Wer das Longhorn-Dashboard erreichen darf (Quell-IPs, wie sie bei Traefik ankommen)
variable "longhorn_allowed_cidrs" {
type = list(string)
default = ["172.25.64.0/24", "172.25.65.0/24"]
}
# BasicAuth für Longhorn als htpasswd-Zeile, z.B.: htpasswd -nbB admin 'geheim'
variable "longhorn_basic_auth" {
type = string
@ -167,6 +173,12 @@ resource "helm_release" "traefik" {
metadata = { name = "longhorn-auth", namespace = "longhorn-system" }
spec = { basicAuth = { secret = "longhorn-basic-auth" } }
},
{
apiVersion = "traefik.io/v1alpha1"
kind = "Middleware"
metadata = { name = "longhorn-allowlist", namespace = "longhorn-system" }
spec = { ipAllowList = { sourceRange = var.longhorn_allowed_cidrs } }
},
{
apiVersion = "networking.k8s.io/v1"
kind = "Ingress"
@ -174,11 +186,17 @@ resource "helm_release" "traefik" {
name = "longhorn"
namespace = "longhorn-system"
annotations = {
"traefik.ingress.kubernetes.io/router.middlewares" = "longhorn-system-longhorn-auth@kubernetescrd"
# Erst IP-Allowlist (nur LAN/DMZ), dann Login
"traefik.ingress.kubernetes.io/router.middlewares" = "longhorn-system-longhorn-allowlist@kubernetescrd,longhorn-system-longhorn-auth@kubernetescrd"
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
}
}
spec = {
ingressClassName = "traefik"
tls = [{
secretName = "longhorn-tls"
hosts = [var.longhorn_host]
}]
rules = [{
host = var.longhorn_host
http = {
@ -195,11 +213,33 @@ resource "helm_release" "traefik" {
})]
}
# --- Forgejo (läuft als Docker auf BITCLAW01) über Traefik veröffentlichen ---
variable "forgejo_host" {
type = string
default = "forgejo.boday-it.ch"
}
resource "helm_release" "forgejo_proxy" {
name = "forgejo-proxy"
chart = "${path.module}/charts/forgejo-proxy"
namespace = "forgejo"
create_namespace = true
set {
name = "host"
value = var.forgejo_host
}
depends_on = [helm_release.traefik, helm_release.cluster_issuer]
}
output "traefik_lb_ip" {
value = var.traefik_lb_ip
}
# Adopt Traefik into the state again (lost when Consul restarted)
# --- Traefik wieder in den State übernehmen (State ging beim Consul-Neustart verloren) ---
# Nach erfolgreichem Lauf dürfen die Blöcke bleiben oder entfernt werden.
import {
to = kubernetes_namespace.traefik
id = "traefik"

19
talos/coredns-hosts.md Normal file
View file

@ -0,0 +1,19 @@
# CoreDNS-Hosts-Eintrag (manuell gepflegt)
Pods im Cluster (u.a. die Selbstprüfung von cert-manager) sollen die eigenen öffentlichen Namen
direkt auf den Traefik-Ingress auflösen, statt über die öffentliche IP 46.4.148.66 (kein Hairpin-NAT).
`kubectl -n kube-system edit configmap coredns`, im Block `.:53 {` nach `errors`:
```
hosts {
172.25.64.200 boday-it.ch www.boday-it.ch forgejo.boday-it.ch longhorn.boday-it.ch
fallthrough
}
```
Danach: `kubectl -n kube-system rollout restart deployment coredns`
Achtung: `talosctl upgrade-k8s` kann die ConfigMap überschreiben. Nach jedem Kubernetes-Upgrade prüfen:
`kubectl run dnstest --rm -i --restart=Never --image=busybox -- nslookup boday-it.ch` → 172.25.64.200
Neue öffentliche Hostnamen auf Talos hier ergänzen.