From cbb03e2d0af8e878b46e37f7fcaf504c55fe7ac7 Mon Sep 17 00:00:00 2001 From: Daniel Paul Date: Tue, 29 Sep 2026 18:07:39 +0200 Subject: [PATCH 1/5] initial garage setup --- assets/garage/garage.yaml | 243 ++++++++++++++++++++++++++++++++++++++ scripts/garage | 16 +++ 2 files changed, 259 insertions(+) create mode 100644 assets/garage/garage.yaml create mode 100644 scripts/garage diff --git a/assets/garage/garage.yaml b/assets/garage/garage.yaml new file mode 100644 index 00000000..8cb19c3f --- /dev/null +++ b/assets/garage/garage.yaml @@ -0,0 +1,243 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: garage + namespace: garage +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: manage-crds-garage-garage +rules: +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch", "create", "patch"] + +- apiGroups: ["deuxfleurs.fr"] + resources: ["garagenodes"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: allow-crds-for-garage-garage +subjects: +- kind: ServiceAccount + name: garage + namespace: garage +roleRef: + kind: ClusterRole + name: manage-crds-garage-garage + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: garage-config + namespace: garage +data: + garage.toml: |- + metadata_dir = "/mnt/meta" + data_dir = "/mnt/data" + db_engine = "lmdb" + block_size = "1048576" + replication_factor = 1 + consistency_mode = "consistent" + compression_level = 1 + rpc_bind_addr = "[::]:3901" + # rpc_secret will be populated by the init container from a k8s secret object + rpc_secret = "__RPC_SECRET_REPLACE__" + bootstrap_peers = [ + ] + [kubernetes_discovery] + namespace = "garage" + service_name = "garage" + skip_crd = false + [s3_api] + s3_region = "garage" + api_bind_addr = "[::]:3900" + root_domain = ".s3.garage.tld" + [s3_web] + bind_addr = "[::]:3902" + root_domain = ".web.garage.tld" + index = "index.html" + [admin] + api_bind_addr = "[::]:3903" +--- +apiVersion: v1 +kind: Service +metadata: + name: garage-headless + namespace: garage +spec: + type: ClusterIP + clusterIP: None + ports: + - port: 3900 + targetPort: 3900 + protocol: TCP + name: s3-api + - port: 3902 + targetPort: 3902 + protocol: TCP + name: s3-web + selector: + app.kubernetes.io/name: garage + app.kubernetes.io/instance: garage +--- +apiVersion: v1 +kind: Service +metadata: + name: garage + namespace: garage +spec: + type: NodePort + ports: + - port: 3900 + targetPort: 3900 + protocol: TCP + name: s3-api + - port: 3902 + targetPort: 3902 + protocol: TCP + name: s3-web + selector: + app.kubernetes.io/name: garage + app.kubernetes.io/instance: garage +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + name: garage + namespace: garage +spec: + persistentVolumeClaimRetentionPolicy: + whenDeleted: Retain + whenScaled: Retain + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: garage + app.kubernetes.io/name: garage + serviceName: garage-headless + template: + metadata: + labels: + app.kubernetes.io/instance: garage + app.kubernetes.io/name: garage + spec: + containers: + - args: + - server + - --single-node + command: + - /garage + env: + image: dxflrs/amd64_garage:v2.4.1 + imagePullPolicy: IfNotPresent + name: garage + ports: + - containerPort: 3900 + name: s3-api + protocol: TCP + - containerPort: 3902 + name: web-api + protocol: TCP + - containerPort: 3903 + name: admin + protocol: TCP + resources: {} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /mnt/meta + name: meta + - mountPath: /mnt/data + name: data + - mountPath: /etc/garage.toml + name: etc + subPath: garage.toml + dnsPolicy: ClusterFirst + initContainers: + - command: + - sh + - -c + - sed "s/__RPC_SECRET_REPLACE__/$RPC_SECRET/" /mnt/garage.toml > /mnt/etc/garage.toml + env: + - name: RPC_SECRET + valueFrom: + secretKeyRef: + key: rpcSecret + name: garage-rpc-secret + image: busybox:stable + imagePullPolicy: IfNotPresent + name: garage-init + resources: {} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /mnt/garage.toml + name: configmap + subPath: garage.toml + - mountPath: /mnt/etc + name: etc + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + serviceAccount: garage + serviceAccountName: garage + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: garage-config + name: configmap + - emptyDir: {} + name: etc + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: meta + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi + storageClassName: px-csi-db + volumeMode: Filesystem + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi + storageClassName: px-csi-db + volumeMode: Filesystem diff --git a/scripts/garage b/scripts/garage new file mode 100644 index 00000000..83ed3cdf --- /dev/null +++ b/scripts/garage @@ -0,0 +1,16 @@ +kubectl create ns garage +kubectl create secret -n garage generic garage-rpc-secret --type=Opaque --from-literal rpcSecret="$(openssl rand -hex 32)" +kubectl apply -f /assets/garage/garage.yaml + +#alias garage='kubectl exec -it garage-0 -c garage -n garage -- /garage $*' + +# DOCS +# https://garagehq.deuxfleurs.fr/documentation/quick-start/ +# +#create key +#'garage key create demouser' +#'garage key allow --create-bucket demouser' + +#create bucket +# aws s3api create-bucket --bucket demobucket --region garage + From 9b5fa3dd7efb4dd54a2bc7b697de7c923c0402bd Mon Sep 17 00:00:00 2001 From: Daniel Paul Date: Thu, 15 Oct 2026 09:32:58 +0200 Subject: [PATCH 2/5] wip --- assets/garage/garage.yaml | 7 +++++++ scripts/garage | 2 ++ templates/garage.yml | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 templates/garage.yml diff --git a/assets/garage/garage.yaml b/assets/garage/garage.yaml index 8cb19c3f..81c2b82f 100644 --- a/assets/garage/garage.yaml +++ b/assets/garage/garage.yaml @@ -133,9 +133,16 @@ spec: - args: - server - --single-node + - --default-bucket command: - /garage env: + - name: GARAGE_DEFAULT_ACCESS_KEY + value: "miniominio" + - name: GARAGE_DEFAULT_SECRET_KEY + value: "minio1234minio1234" + - name: GARAGE_DEFAULT_BUCKET + value: "default" image: dxflrs/amd64_garage:v2.4.1 imagePullPolicy: IfNotPresent name: garage diff --git a/scripts/garage b/scripts/garage index 83ed3cdf..234f7058 100644 --- a/scripts/garage +++ b/scripts/garage @@ -14,3 +14,5 @@ kubectl apply -f /assets/garage/garage.yaml #create bucket # aws s3api create-bucket --bucket demobucket --region garage +#json +# garage json-api CreateKey '{"name": "demokey","neverExpires": true, "allow": {"createBucket":true}}' \ No newline at end of file diff --git a/templates/garage.yml b/templates/garage.yml new file mode 100644 index 00000000..416da8ad --- /dev/null +++ b/templates/garage.yml @@ -0,0 +1,2 @@ +description: Install and run Portworx on each cluster +scripts: ["install-px","install-awscli","garage"] From f9ea2be9d381d41d7499d7b77789b84180eb95d5 Mon Sep 17 00:00:00 2001 From: Daniel Paul Date: Thu, 15 Oct 2026 09:35:10 +0200 Subject: [PATCH 3/5] wip --- scripts/garage | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/garage b/scripts/garage index 234f7058..61772435 100644 --- a/scripts/garage +++ b/scripts/garage @@ -2,17 +2,17 @@ kubectl create ns garage kubectl create secret -n garage generic garage-rpc-secret --type=Opaque --from-literal rpcSecret="$(openssl rand -hex 32)" kubectl apply -f /assets/garage/garage.yaml -#alias garage='kubectl exec -it garage-0 -c garage -n garage -- /garage $*' - # DOCS # https://garagehq.deuxfleurs.fr/documentation/quick-start/ # +##alias garage='kubectl exec -it garage-0 -c garage -n garage -- /garage $*' +# #create key #'garage key create demouser' #'garage key allow --create-bucket demouser' - +# #create bucket # aws s3api create-bucket --bucket demobucket --region garage - +# #json # garage json-api CreateKey '{"name": "demokey","neverExpires": true, "allow": {"createBucket":true}}' \ No newline at end of file From 83d1d9c8838a34a2f0022a516080749cbc422252 Mon Sep 17 00:00:00 2001 From: Daniel Paul Date: Fri, 23 Oct 2026 16:38:19 +0200 Subject: [PATCH 4/5] wip --- assets/garage/garage.yaml | 44 ++++++++------------------------------- scripts/garage | 7 ++++--- 2 files changed, 13 insertions(+), 38 deletions(-) diff --git a/assets/garage/garage.yaml b/assets/garage/garage.yaml index 81c2b82f..35322802 100644 --- a/assets/garage/garage.yaml +++ b/assets/garage/garage.yaml @@ -1,4 +1,9 @@ apiVersion: v1 +kind: Namespace +metadata: + name: garage +--- +apiVersion: v1 kind: ServiceAccount metadata: name: garage @@ -45,8 +50,7 @@ data: consistency_mode = "consistent" compression_level = 1 rpc_bind_addr = "[::]:3901" - # rpc_secret will be populated by the init container from a k8s secret object - rpc_secret = "__RPC_SECRET_REPLACE__" + rpc_secret = "__RPCSECRET__" bootstrap_peers = [ ] [kubernetes_discovery] @@ -138,11 +142,11 @@ spec: - /garage env: - name: GARAGE_DEFAULT_ACCESS_KEY - value: "miniominio" + value: "__ACCESSKEY__" - name: GARAGE_DEFAULT_SECRET_KEY - value: "minio1234minio1234" + value: "__SECRETKEY__" - name: GARAGE_DEFAULT_BUCKET - value: "default" + value: "portworx" image: dxflrs/amd64_garage:v2.4.1 imagePullPolicy: IfNotPresent name: garage @@ -173,34 +177,6 @@ spec: name: etc subPath: garage.toml dnsPolicy: ClusterFirst - initContainers: - - command: - - sh - - -c - - sed "s/__RPC_SECRET_REPLACE__/$RPC_SECRET/" /mnt/garage.toml > /mnt/etc/garage.toml - env: - - name: RPC_SECRET - valueFrom: - secretKeyRef: - key: rpcSecret - name: garage-rpc-secret - image: busybox:stable - imagePullPolicy: IfNotPresent - name: garage-init - resources: {} - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /mnt/garage.toml - name: configmap - subPath: garage.toml - - mountPath: /mnt/etc - name: etc restartPolicy: Always schedulerName: default-scheduler securityContext: @@ -216,8 +192,6 @@ spec: - configMap: defaultMode: 420 name: garage-config - name: configmap - - emptyDir: {} name: etc updateStrategy: rollingUpdate: diff --git a/scripts/garage b/scripts/garage index 61772435..7a254437 100644 --- a/scripts/garage +++ b/scripts/garage @@ -1,6 +1,7 @@ -kubectl create ns garage -kubectl create secret -n garage generic garage-rpc-secret --type=Opaque --from-literal rpcSecret="$(openssl rand -hex 32)" -kubectl apply -f /assets/garage/garage.yaml +RPCSECRET=$(openssl rand -hex 32) +ACCESSKEY=$(openssl rand -hex 10) +SECRETKEY=$(openssl rand -hex 18) +sed -e "s/__ACCESSKEY__/$ACCESSKEY/" -e "s/__SECRETKEY__/$SECRETKEY/" -e "s/__RPCSECRET__/$RPCSECRET/" /assets/garage/garage.yaml | kubectl apply -f - # DOCS # https://garagehq.deuxfleurs.fr/documentation/quick-start/ From 4f204f3aac3c0c37b0e6af16ad7aadb600953428 Mon Sep 17 00:00:00 2001 From: Daniel Paul Date: Wed, 28 Oct 2026 10:15:09 +0100 Subject: [PATCH 5/5] create aws credential secret --- scripts/garage | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/garage b/scripts/garage index 7a254437..2da63668 100644 --- a/scripts/garage +++ b/scripts/garage @@ -3,6 +3,10 @@ ACCESSKEY=$(openssl rand -hex 10) SECRETKEY=$(openssl rand -hex 18) sed -e "s/__ACCESSKEY__/$ACCESSKEY/" -e "s/__SECRETKEY__/$SECRETKEY/" -e "s/__RPCSECRET__/$RPCSECRET/" /assets/garage/garage.yaml | kubectl apply -f - +PORT=$(kubectl get svc garage -n garage -ojson | jq -r '.spec.ports[] | select(.name=="s3-api") | .nodePort') + +kubectl create secret generic s3access -n garage --from-literal=AWS_ACCESS_KEY_ID=$ACCESSKEY --from-literal=AWS_SECRET_ACCESS_KEY=$SECRETKEY --from-literal=AWS_DEFAULT_REGION=garage --from-literal=AWS_ENDPOINT_URL="http://node-1-1:$PORT" + # DOCS # https://garagehq.deuxfleurs.fr/documentation/quick-start/ #