diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..a306b2c --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,4 @@ +creation_rules: + - encrypted_regex: '^(data|stringData)$' + path_regex: \.yaml$ + pgp: F20CF3DE0B4ACDFCAF07A9D76399FB237185E764 diff --git a/apps/forgejo-runner/deployment.yaml b/apps/forgejo-runner/deployment.yaml new file mode 100644 index 0000000..384bb28 --- /dev/null +++ b/apps/forgejo-runner/deployment.yaml @@ -0,0 +1,75 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: forgejo-runner + namespace: forgejo + labels: + app: forgejo-runner +spec: + replicas: 1 + selector: + matchLabels: + app: forgejo-runner + template: + metadata: + labels: + app: forgejo-runner + spec: + restartPolicy: Always + volumes: + - name: docker-certs + emptyDir: {} + - name: runner-data + emptyDir: {} + initContainers: + - name: runner-config-generation + image: code.forgejo.org/forgejo/runner:6.3.1 + command: + [ + "sh", + "-c", + "forgejo-runner create-runner-file --instance $FORGEJO_INSTANCE_URL --secret $RUNNER_SECRET --connect" + ] + env: + - name: RUNNER_SECRET + valueFrom: + secretKeyRef: + name: forgejo-runner-token + key: token + - name: FORGEJO_INSTANCE_URL + value: https://git.patanix.de + volumeMounts: + - name: runner-data + mountPath: /data + containers: + - name: runner + image: code.forgejo.org/forgejo/runner:6.3.1 + command: + [ + "sh", + "-c", + "while ! nc -z localhost 2376 " # Finde die passende Version auf ArtifactHub - sourceRef: - kind: HelmRepository - name: cnpg # Das zuvor definierte Repository - namespace: flux-system - interval: 1m - values: - # Cluster Konfiguration - # Name des Clusters, der im cnpg-system Namespace erstellt wird - name: shared-pg - # Anzahl der Instanzen (für Hochverfügbarkeit anpassen) - instances: 3 - # Storage Konfiguration (Longhorn verwenden, wie in deinen anderen Setups) - storage: - size: "10Gi" # Gesamtgröße für den Cluster, anpassen nach Bedarf - storageClass: "longhorn" # Deine Longhorn StorageClass - # PostgreSQL Version (prüfe Kompatibilität mit deinen Anwendungen) - # postgresql: - # imageName: "ghcr.io/cloudnative-pg/postgresql:15.3" # Beispiel - - # Wichtig: Konfiguriere Backups! Hier nicht im Detail gezeigt. - # backup: - # barmanObjectStore: - # ... - - # Monitoring (optional, aber empfohlen) - # monitoring: - # enablePodMonitor: true - - # Initiale Datenbanken und Benutzer (optional, kann auch manuell oder per Job erfolgen) - # Beachte, dass du für jede Anwendung (Gitea, SonarQube) eigene Datenbanken und Benutzer - # in diesem geteilten Cluster benötigst. CloudNativePG kann Benutzer verwalten. - # Beispiel für einen initialen Benutzer (NICHT für Anwendungen direkt verwenden, - # sondern spezifische Benutzer pro Anwendung erstellen) - # bootstrap: - # initdb: - # database: app_db_1 # Beispiel: Gitea DB - # owner: app_user_1 # Beispiel: Gitea User - # # Weitere Datenbanken hier - # - # # Deklarative Rollen/Benutzer - # postgresql: - # managed: - # roles: - # - name: gitea_user - # # passwordSecret: # Besser ein Secret verwenden - # # name: gitea-db-credentials - # # key: password - # - name: sonarqube_user - # # passwordSecret: - # # name: sonarqube-db-credentials - # # key: password diff --git a/infrastructure/cnpg/helmrelease-operator.yaml b/infrastructure/cnpg/helmrelease-operator.yaml deleted file mode 100644 index 147ebfe..0000000 --- a/infrastructure/cnpg/helmrelease-operator.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2beta1 -kind: HelmRelease -metadata: - name: cnpg-operator - namespace: cnpg-system -spec: - interval: 10m - chart: - spec: - chart: cloudnative-pg - version: "0.23.2" - sourceRef: - kind: HelmRepository - name: cnpg - namespace: flux-system - interval: 1m diff --git a/infrastructure/cnpg/helmrepository.yaml b/infrastructure/cnpg/helmrepository.yaml deleted file mode 100644 index fa469e7..0000000 --- a/infrastructure/cnpg/helmrepository.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: source.toolkit.fluxcd.io/v1beta2 # Oder v1 je nach deiner Flux-Version -kind: HelmRepository -metadata: - name: cnpg - namespace: flux-system -spec: - interval: 1h - url: https://cloudnative-pg.io/charts diff --git a/infrastructure/gitea-runner/helmrelease.yaml b/infrastructure/gitea-runner/helmrelease.yaml deleted file mode 100644 index e5a1976..0000000 --- a/infrastructure/gitea-runner/helmrelease.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2beta2 -kind: HelmRelease -metadata: - name: gitea-act-runner - namespace: gitea -spec: - releaseName: gitea-act-runner - interval: 10m - chart: - spec: - chart: gitea-act-runner - version: "0.5.2" - sourceRef: - kind: HelmRepository - name: gitea-charts - namespace: flux-system - values: - provisioning: - enabled: true - # Gitea-URL wie im Cluster erreichbar (interner Service-Name!) - serverURL: "http://gitea-http.gitea.svc.cluster.local:3000" - # Admin-Zugangsdaten wie oben im Gitea-Chart gesetzt - adminUser: "giteaadmin" - # adminPassword: "changeme" - adminPassword: "F3l1x-230113?" - rbac: - create: true - # Optional: Runner-Name, falls du mehrere Runner willst - runner: - labels: ["k3s", "fluxcd"] diff --git a/infrastructure/gitea-runner/namespace.yaml b/infrastructure/gitea-runner/namespace.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/infrastructure/kustomization.yaml b/infrastructure/kustomization.yaml index 620a250..1db4b1a 100644 --- a/infrastructure/kustomization.yaml +++ b/infrastructure/kustomization.yaml @@ -1,9 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - monitoring/ - - longhorn/ - - gitea/ - # - gitea-runner/ - # - sonarqube/ - - cnpg + - cert-manager/ + - cert-manager-webhook-hetzner/ + # - monitoring/ diff --git a/infrastructure/longhorn/helmrelease.yaml b/infrastructure/longhorn/helmrelease.yaml deleted file mode 100644 index 695713b..0000000 --- a/infrastructure/longhorn/helmrelease.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2beta2 -kind: HelmRelease -metadata: - name: longhorn - namespace: longhorn-system -spec: - releaseName: longhorn - chart: - spec: - chart: longhorn - version: "1.8.1" - sourceRef: - kind: HelmRepository - name: longhorn - namespace: flux-system - interval: 5m - install: - createNamespace: true - values: - defaultSettings: - defaultReplicaCount: 2 - persistence: - defaultClassReplicaCount: 2 diff --git a/infrastructure/longhorn/longhorn-ingress.yaml b/infrastructure/longhorn/longhorn-ingress.yaml deleted file mode 100644 index ce7f130..0000000 --- a/infrastructure/longhorn/longhorn-ingress.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: longhorn-ui - namespace: longhorn-system - annotations: - kubernetes.io/ingress.class: "traefik" -spec: - rules: - - host: longhorn.local - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: longhorn-frontend - port: - number: 80 diff --git a/infrastructure/ocirepositories/forgejo.yaml b/infrastructure/ocirepositories/forgejo.yaml new file mode 100644 index 0000000..cf40613 --- /dev/null +++ b/infrastructure/ocirepositories/forgejo.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: OCIRepository +metadata: + name: forgejo + namespace: flux-system +spec: + interval: 30m + url: oci://code.forgejo.org/forgejo-helm/forgejo + ref: + tag: "12.5.1" diff --git a/infrastructure/sonarqube/helmrelease.yaml b/infrastructure/sonarqube/helmrelease.yaml deleted file mode 100644 index 9544394..0000000 --- a/infrastructure/sonarqube/helmrelease.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2beta2 -kind: HelmRelease -metadata: - name: sonarqube - namespace: sonarqube -spec: - interval: 10m - chart: - spec: - chart: sonarqube - version: "2025.2.0" - sourceRef: - kind: HelmRepository - name: sonarqube - namespace: flux-system - values: - community: - enabled: true - monitoringPasscode: "supersecret123" - persistence: - enabled: true - storageClass: longhorn - size: 5Gi - postgresql: - enabled: true - persistence: - enabled: true - storageClass: longhorn - size: 2Gi - ingress: - enabled: true - hosts: - - name: sonarqube.local - path: / - ingressClassName: traefik diff --git a/infrastructure/sonarqube/helmrepository.yaml b/infrastructure/sonarqube/helmrepository.yaml deleted file mode 100644 index 5d2cb5a..0000000 --- a/infrastructure/sonarqube/helmrepository.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: sonarqube - namespace: flux-system -spec: - url: https://SonarSource.github.io/helm-chart-sonarqube - interval: 1h diff --git a/notes/cert-manager-webhook.md b/notes/cert-manager-webhook.md new file mode 100644 index 0000000..e1367bd --- /dev/null +++ b/notes/cert-manager-webhook.md @@ -0,0 +1,79 @@ +# Schritt: cert-manager-webhook-hetzner (vadimkim) und ClusterIssuer + +## 1. HelmRepository für Webhook anlegen +```bash +cat < infrastructure/cert-manager-webhook-hetzner/helmrepository.yaml +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: vadimkim-cert-manager-webhook-hetzner + namespace: flux-system +spec: + interval: 30m + url: https://vadimkim.github.io/cert-manager-webhook-hetzner +EOF +``` + +## 2. HelmRelease für Webhook anlegen +```bash +cat < infrastructure/cert-manager-webhook-hetzner/helmrelease.yaml +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: cert-manager-webhook-hetzner + namespace: cert-manager +spec: + interval: 15m + chart: + spec: + chart: cert-manager-webhook-hetzner + version: 2.9.0 + sourceRef: + kind: HelmRepository + name: vadimkim-cert-manager-webhook-hetzner + namespace: flux-system + values: + groupName: patanix.de +EOF +``` + +## 3. ClusterIssuer anlegen +```bash +cat < infrastructure/cert-manager/letsencrypt-clusterissuer.yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-dns +spec: + acme: + email: patryk-hegenberg@outlook.de + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-dns-key + solvers: + - dns01: + webhook: + groupName: patanix.de + solverName: hetzner + config: + apiTokenSecretRef: + name: hetzner-dns-api-token + key: token +EOF +``` + +## 4. Dateien ins Git-Repo legen und pushen +```bash +git add infrastructure/cert-manager-webhook-hetzner/* +git add infrastructure/cert-manager/letsencrypt-clusterissuer.yaml +git commit -m "Add vadimkim cert-manager-webhook-hetzner and ClusterIssuer for patanix.de" +git push origin main +``` + +## 5. Flux synchronisieren und prüfen +```bash +flux reconcile source git flux-system +flux get helmreleases -A +kubectl get pods -n cert-manager +kubectl get clusterissuer +``` diff --git a/notes/cert-manager.md b/notes/cert-manager.md new file mode 100644 index 0000000..338b3ae --- /dev/null +++ b/notes/cert-manager.md @@ -0,0 +1,40 @@ +# Schritt 1: cert-manager v1.17.2 mit FluxCD deployen + +## Verzeichnisstruktur +infrastructure/ + cert-manager/ + namespace.yaml + helmrepository.yaml + configmap-values.yaml + helmrelease.yaml + kustomization-cert-manager.yaml + +## Vorgehen + +1. YAML-Dateien wie oben beschrieben im Git-Repository anlegen. +2. Änderungen committen und pushen: +```bash + git add infrastructure/cert-manager/* + git add infrastructure/kustomization-cert-manager.yaml + git commit -m "Deploy cert-manager v1.17.2 via FluxCD" + git push origin main +``` + +3. Flux synchronisiert automatisch. Manuelles Triggern: +```bash + flux reconcile source git flux-system + flux get kustomizations + kubectl -n cert-manager get pods +``` + +4. Prüfen, ob cert-manager läuft: +```bash + kubectl -n cert-manager get pods + kubectl -n cert-manager get deployments +``` + +5. Fehlerdiagnose: +```bash + flux logs + kubectl -n cert-manager logs deploy/cert-manager +``` diff --git a/notes/home-assistant.md b/notes/home-assistant.md new file mode 100644 index 0000000..c21df6b --- /dev/null +++ b/notes/home-assistant.md @@ -0,0 +1,86 @@ +# Home Assistant Best Practices + +## Secret +- Nicht zwingend nötig, nur für zusätzliche Umgebungsvariablen. +- Kann jederzeit nachgerüstet werden. + +## Zertifikat +- Standard: Ingress mit cert-manager-Annotation, cert-manager erstellt das Zertifikat automatisch. +- Alternativ: Certificate-Objekt selbst anlegen, dann Annotation im Ingress entfernen. + +## HelmRepository (pajikos) +```bash +cat < infrastructure/services/home-assistant/helmrepository.yaml +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: pajikos-home-assistant + namespace: flux-system +spec: + interval: 30m + url: https://pajikos.github.io/home-assistant-helm-chart +EOF +``` + +## HelmRelease (Beispiel) +```bash +cat < infrastructure/services/home-assistant/helmrelease.yaml +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: home-assistant + namespace: home-assistant +spec: + interval: 15m + chart: + spec: + chart: home-assistant + version: 15.3.5 + sourceRef: + kind: HelmRepository + name: pajikos-home-assistant + namespace: flux-system + values: + persistence: + enabled: true + existingClaim: home-assistant-config + ingress: + main: + enabled: true + hosts: + - host: ha.patanix.de + paths: + - / + tls: + - secretName: ha-patanix-de-tls + hosts: + - ha.patanix.de + annotations: + cert-manager.io/cluster-issuer: letsencrypt-dns +EOF +``` + +## 2. Secret verschlüsseln - falls vorhanden +```bash +sops -e -i infrastructure/services/home-assistant/secret.yaml +``` + +## 3. Dateien ins Repo legen und pushen +```bash +git add infrastructure/services/home-assistant/* +git add infrastructure/kustomization-home-assistant.yaml +git commit -m "Deploy Home Assistant via FluxCD (20GiB, ha.patanix.de)" +git push origin main +``` + +## 4. Flux synchronisieren +```bash +flux reconcile source git flux-system +flux get kustomizations +kubectl -n home-assistant get pods +kubectl -n home-assistant get ingress +kubectl -n home-assistant get certificate +``` + +## 5. Erreichbarkeit testen +# Nach DNS-Propagation und Zertifikatsausstellung: https://ha.patanix.de aufrufen diff --git a/notes/sops-and-hetzner-secret.md b/notes/sops-and-hetzner-secret.md new file mode 100644 index 0000000..75618e6 --- /dev/null +++ b/notes/sops-and-hetzner-secret.md @@ -0,0 +1,84 @@ +# SOPS für FluxCD einrichten + +## SOPS & GPG installieren +```bash +sudo dnf install gnupg +``` +### Download the binary +```bash +curl -LO https://github.com/getsops/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64 +``` + +### Move the binary in to your PATH +```bash +mv sops-v3.10.2.linux.amd64 /usr/local/bin/sops +``` + +### Make the binary executable +```bash +chmod +x /usr/local/bin/sops +``` + +## GPG Key generieren +```bash +export KEY_NAME="k3s.homelab" +export KEY_COMMENT="flux secrets" +gpg --batch --full-generate-key < +``` + +## GPG Key als Kubernetes Secret speichern +```bash +gpg --export-secret-keys --armor "${KEY_FP}" | \ +kubectl create secret generic sops-gpg \ + --namespace=flux-system \ + --from-file=sops.asc=/dev/stdin +``` +## .sops.yaml im Repo anlegen +```bash +cat < .sops.yaml +creation_rules: + - encrypted_regex: '^(data|stringData)$' + path_regex: \.yaml$ + pgp: +EOF +``` + +## Hetzner DNS API Token in Secret-Datei eintragen +```bash +cat < infrastructure/cert-manager/hetzner-dns-api-token-secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: hetzner-dns-api-token + namespace: cert-manager +type: Opaque +stringData: + token: "" +EOF +``` +## Mit SOPS verschlüsseln +```bash +sops -e -i infrastructure/cert-manager/hetzner-dns-api-token-secret.yaml +``` + +## Ins Git-Repo legen und pushen +```bash +git add infrastructure/cert-manager/hetzner-dns-api-token-secret.yaml +git commit -m "Add Hetzner DNS API token secret (encrypted with SOPS)" +git push origin main +``` diff --git a/notes/test-certificate.md b/notes/test-certificate.md new file mode 100644 index 0000000..ee91d95 --- /dev/null +++ b/notes/test-certificate.md @@ -0,0 +1,40 @@ +# Test: Zertifikatsausstellung mit cert-manager und Hetzner DNS + +## Test-Zertifikat anlegen +```bash +cat < infrastructure/cert-manager/test-certificate.yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: test-certificate + namespace: cert-manager +spec: + secretName: test-certificate-tls + issuerRef: + name: letsencrypt-dns + kind: ClusterIssuer + commonName: test.patanix.de + dnsNames: + - test.patanix.de +EOF +``` + +## Datei ins Repo legen und pushen +```bash +git add infrastructure/cert-manager/test-certificate.yaml +git commit -m "Add test certificate request for test.patanix.de" +git push origin main +``` + +## Status prüfen +```bash +kubectl -n cert-manager get certificate +kubectl -n cert-manager describe certificate test-certificate +kubectl -n cert-manager get secret test-certificate-tls +``` + +# Events und Fehlerdiagnose +```bash +kubectl -n cert-manager get events --sort-by=.metadata.creationTimestamp +kubectl -n cert-manager logs deploy/cert-manager +``` diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 7190a60..0000000 --- a/renovate.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json" -}