From 5ddba311cf4b43e36a998bc253556dc1b7ca5554 Mon Sep 17 00:00:00 2001 From: Alex Lebens Date: Mon, 27 Oct 2025 20:19:43 -0500 Subject: [PATCH] add local garage --- .../cl01tl/applications/homepage/values.yaml | 8 +- clusters/cl01tl/services/blocky/values.yaml | 2 + clusters/cl01tl/storage/garage/Chart.yaml | 22 ++++ .../garage/templates/external-secret.yaml | 35 ++++++ .../storage/garage/templates/http-route.yaml | 58 +++++++++ .../garage/templates/service-monitor.yaml | 22 ++++ clusters/cl01tl/storage/garage/values.yaml | 117 ++++++++++++++++++ hosts/ps08rp/blocky/config.yml | 2 + hosts/ps09rp/blocky/config.yml | 2 + 9 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 clusters/cl01tl/storage/garage/Chart.yaml create mode 100644 clusters/cl01tl/storage/garage/templates/external-secret.yaml create mode 100644 clusters/cl01tl/storage/garage/templates/http-route.yaml create mode 100644 clusters/cl01tl/storage/garage/templates/service-monitor.yaml create mode 100644 clusters/cl01tl/storage/garage/values.yaml diff --git a/clusters/cl01tl/applications/homepage/values.yaml b/clusters/cl01tl/applications/homepage/values.yaml index ea0aa7529..7d272d1f9 100644 --- a/clusters/cl01tl/applications/homepage/values.yaml +++ b/clusters/cl01tl/applications/homepage/values.yaml @@ -492,7 +492,13 @@ homepage: href: https://ceph.alexlebens.net siteMonitor: http://rook-ceph-mgr-dashboard.rook-ceph:7000 statusStyle: dot - - Remote Storage: + - Object Storage (NAS): + icon: sh-garage.webp + description: Garage + href: https://garage-webui.alexlebens.net + siteMonitor: http://garage.garage:3909 + statusStyle: dot + - Object Storage (ps10rp): icon: sh-garage.webp description: Garage href: https://garage-ui-ps10rp.boreal-beaufort.ts.net diff --git a/clusters/cl01tl/services/blocky/values.yaml b/clusters/cl01tl/services/blocky/values.yaml index 3ec34b07b..4c8806bde 100644 --- a/clusters/cl01tl/services/blocky/values.yaml +++ b/clusters/cl01tl/services/blocky/values.yaml @@ -114,6 +114,8 @@ blocky: calibre-downloader IN CNAME traefik-cl01tl ceph IN CNAME traefik-cl01tl code-server IN CNAME traefik-cl01tl + garage-s3 IN CNAME traefik-cl01tl + garage-webui IN CNAME traefik-cl01tl gatus IN CNAME traefik-cl01tl gitea IN CNAME traefik-cl01tl grafana IN CNAME traefik-cl01tl diff --git a/clusters/cl01tl/storage/garage/Chart.yaml b/clusters/cl01tl/storage/garage/Chart.yaml new file mode 100644 index 000000000..3a8d9d025 --- /dev/null +++ b/clusters/cl01tl/storage/garage/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +name: garage +version: 1.0.0 +description: Garage +keywords: + - garage + - storage + - s3 +home: https://wiki.alexlebens.dev/s/ +sources: + - https://git.deuxfleurs.fr/Deuxfleurs/garage + - https://hub.docker.com/r/dxflrs/garage + - https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template +maintainers: + - name: alexlebens +dependencies: + - name: app-template + alias: garage + repository: https://bjw-s-labs.github.io/helm-charts/ + version: 4.4.0 +icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/kubernetes.png +appVersion: v2.1.0 diff --git a/clusters/cl01tl/storage/garage/templates/external-secret.yaml b/clusters/cl01tl/storage/garage/templates/external-secret.yaml new file mode 100644 index 000000000..9305dc16b --- /dev/null +++ b/clusters/cl01tl/storage/garage/templates/external-secret.yaml @@ -0,0 +1,35 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: garage-token-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: garage-token-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: GARAGE_RPC_SECRET + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/garage/token + metadataPolicy: None + property: rpc + - secretKey: GARAGE_ADMIN_TOKEN + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /ccl01tl/garage/token + metadataPolicy: None + property: admin + - secretKey: GARAGE_METRICS_TOKEN + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/garage/token + metadataPolicy: None + property: metric diff --git a/clusters/cl01tl/storage/garage/templates/http-route.yaml b/clusters/cl01tl/storage/garage/templates/http-route.yaml new file mode 100644 index 000000000..79dbfc926 --- /dev/null +++ b/clusters/cl01tl/storage/garage/templates/http-route.yaml @@ -0,0 +1,58 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-route-garage-webui + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: http-route-garage-webui + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: traefik-gateway + namespace: traefik + hostnames: + - garage-webui.alexlebens.net + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: '' + kind: Service + name: garage + port: 3909 + weight: 100 + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-route-garage-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: http-route-garage-s3 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: traefik-gateway + namespace: traefik + hostnames: + - garage-s3.alexlebens.net + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: '' + kind: Service + name: garage + port: 3900 + weight: 100 diff --git a/clusters/cl01tl/storage/garage/templates/service-monitor.yaml b/clusters/cl01tl/storage/garage/templates/service-monitor.yaml new file mode 100644 index 000000000..349b251c1 --- /dev/null +++ b/clusters/cl01tl/storage/garage/templates/service-monitor.yaml @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: garage + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: garage + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: garage + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: admin + interval: 1m + scrapeTimeout: 30s + path: /metrics + bearerTokenSecret: + name: garage-token-secret + key: GARAGE_METRICS_TOKEN diff --git a/clusters/cl01tl/storage/garage/values.yaml b/clusters/cl01tl/storage/garage/values.yaml new file mode 100644 index 000000000..561045577 --- /dev/null +++ b/clusters/cl01tl/storage/garage/values.yaml @@ -0,0 +1,117 @@ +garage: + controllers: + main: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + containers: + main: + image: + repository: dxflrs/garage + tag: v2.1.0 + pullPolicy: IfNotPresent + envFrom: + - secretRef: + name: garage-token-secret + resources: + requests: + cpu: 10m + memory: 128Mi + webui: + image: + repository: khairul169/garage-webui + tag: 1.1.0 + pullPolicy: IfNotPresent + env: + - name: API_BASE_URL + value: http://127.0.0.1:3903 + - name: S3_ENDPOINT_URL + value: http://127.0.0.1:3900 + resources: + requests: + cpu: 10m + memory: 128Mi + configMaps: + config: + enabled: true + data: + garage.toml: | + replication_factor = 1 + + metadata_dir = "/var/lib/garage/meta" + data_dir = "/var/lib/garage/data" + + db_engine = "sqlite" + + compression_level = 1 + + rpc_bind_addr = "[::]:3901" + rpc_public_addr = "127.0.0.1:3901" + + allow_world_readable_secrets = false + + [s3_api] + s3_region = "us-east-1" + api_bind_addr = "[::]:3900" + root_domain = ".garage-s3.alexlebens.net" + + [s3_web] + bind_addr = "[::]:3902" + root_domain = ".garage-s3.alexlebens.net" + + [admin] + api_bind_addr = "[::]:3903" + metrics_require_token = true + + service: + main: + controller: main + ports: + webui: + port: 3909 + targetPort: 3909 + protocol: HTTP + s3: + port: 3900 + targetPort: 3900 + protocol: HTTP + rpc: + port: 3901 + targetPort: 3901 + protocol: HTTP + web: + port: 3902 + targetPort: 3902 + protocol: HTTP + admin: + port: 3903 + targetPort: 3903 + protocol: HTTP + persistence: + config: + enabled: true + type: configMap + name: garage + advancedMounts: + main: + main: + - path: /etc/garage.toml + readOnly: true + mountPropagation: None + subPath: garage.toml + webui: + - path: /etc/garage.toml + readOnly: true + mountPropagation: None + subPath: garage.toml + data: + storageClass: synology-iscsi-delete + accessMode: ReadWriteOnce + size: 200Gi + retain: true + advancedMounts: + main: + main: + - path: /var/lib/garage + readOnly: false diff --git a/hosts/ps08rp/blocky/config.yml b/hosts/ps08rp/blocky/config.yml index 6453409bb..d1811f8fa 100644 --- a/hosts/ps08rp/blocky/config.yml +++ b/hosts/ps08rp/blocky/config.yml @@ -90,6 +90,8 @@ customDNS: calibre-downloader IN CNAME traefik-cl01tl ceph IN CNAME traefik-cl01tl code-server IN CNAME traefik-cl01tl + garage-s3 IN CNAME traefik-cl01tl + garage-webui IN CNAME traefik-cl01tl gatus IN CNAME traefik-cl01tl gitea IN CNAME traefik-cl01tl grafana IN CNAME traefik-cl01tl diff --git a/hosts/ps09rp/blocky/config.yml b/hosts/ps09rp/blocky/config.yml index 6453409bb..d1811f8fa 100644 --- a/hosts/ps09rp/blocky/config.yml +++ b/hosts/ps09rp/blocky/config.yml @@ -90,6 +90,8 @@ customDNS: calibre-downloader IN CNAME traefik-cl01tl ceph IN CNAME traefik-cl01tl code-server IN CNAME traefik-cl01tl + garage-s3 IN CNAME traefik-cl01tl + garage-webui IN CNAME traefik-cl01tl gatus IN CNAME traefik-cl01tl gitea IN CNAME traefik-cl01tl grafana IN CNAME traefik-cl01tl