192 lines
4.7 KiB
YAML
192 lines
4.7 KiB
YAML
# Garage — S3-compatible object storage, single-node
|
|
# Metadata (LMDB, mmap-heavy → NFS-hostile) on local-path PVC
|
|
# Data blobs on NAS via nas-nfs (subdir "garage" on /volume1/samantha-private)
|
|
# Anti-affinity excludes game-worker-hdd (slow spinning disk)
|
|
#
|
|
# Ports (NodePort only for S3 API):
|
|
# 3900 — S3 API → NodePort 32390
|
|
# 3901 — inter-node RPC (not exposed; single-node)
|
|
# 3902 — S3 web hosting (not exposed for now)
|
|
# 3903 — admin API (bound to 127.0.0.1 inside pod; kubectl exec to use)
|
|
#
|
|
# Deploy:
|
|
# kubectl create secret generic garage-secret \
|
|
# --from-literal=rpc-secret="$(openssl rand -hex 32)" \
|
|
# --from-literal=admin-token="$(openssl rand -hex 32)" \
|
|
# --from-literal=metrics-token="$(openssl rand -hex 32)"
|
|
# kubectl apply -f garage.yaml
|
|
#
|
|
# First-time layout init (run once after pod is Ready):
|
|
# kubectl exec -n default deploy/garage -- garage status
|
|
# # copy the node ID from the output, then:
|
|
# kubectl exec -n default deploy/garage -- \
|
|
# garage layout assign -z dc1 -c 500G <node-id>
|
|
# kubectl exec -n default deploy/garage -- \
|
|
# garage layout apply --version 1
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: garage-config
|
|
data:
|
|
garage.toml: |
|
|
metadata_dir = "/meta"
|
|
data_dir = "/data"
|
|
db_engine = "lmdb"
|
|
|
|
replication_factor = 1
|
|
consistency_mode = "consistent"
|
|
|
|
rpc_bind_addr = "[::]:3901"
|
|
rpc_public_addr = "127.0.0.1:3901"
|
|
|
|
[s3_api]
|
|
api_bind_addr = "[::]:3900"
|
|
s3_region = "garage"
|
|
root_domain = ".s3.garage.homelab"
|
|
|
|
[s3_web]
|
|
bind_addr = "[::]:3902"
|
|
root_domain = ".page.sjasoft.com"
|
|
index = "index.html"
|
|
|
|
[admin]
|
|
api_bind_addr = "[::]:3903"
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: garage-meta-pvc
|
|
spec:
|
|
accessModes: [ReadWriteOnce]
|
|
storageClassName: local-path
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: garage-data-pvc
|
|
annotations:
|
|
nfs.io/storage-path: "garage"
|
|
spec:
|
|
accessModes: [ReadWriteMany]
|
|
storageClassName: nas-nfs
|
|
resources:
|
|
requests:
|
|
storage: 500Gi
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: garage
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: garage
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: garage
|
|
spec:
|
|
affinity:
|
|
nodeAffinity:
|
|
requiredDuringSchedulingIgnoredDuringExecution:
|
|
nodeSelectorTerms:
|
|
- matchExpressions:
|
|
- key: kubernetes.io/hostname
|
|
operator: NotIn
|
|
values:
|
|
- game-worker-hdd
|
|
containers:
|
|
- name: garage
|
|
image: dxflrs/garage:v2.3.0
|
|
command: ["/garage"]
|
|
args: ["server"]
|
|
env:
|
|
- name: GARAGE_RPC_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: garage-secret
|
|
key: rpc-secret
|
|
- name: GARAGE_ADMIN_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: garage-secret
|
|
key: admin-token
|
|
- name: GARAGE_METRICS_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: garage-secret
|
|
key: metrics-token
|
|
- name: GARAGE_CONFIG_FILE
|
|
value: /etc/garage/garage.toml
|
|
ports:
|
|
- containerPort: 3900
|
|
name: s3
|
|
- containerPort: 3901
|
|
name: rpc
|
|
- containerPort: 3902
|
|
name: web
|
|
- containerPort: 3903
|
|
name: admin
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /etc/garage
|
|
- name: meta
|
|
mountPath: /meta
|
|
- name: data
|
|
mountPath: /data
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: garage-config
|
|
- name: meta
|
|
persistentVolumeClaim:
|
|
claimName: garage-meta-pvc
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: garage-data-pvc
|
|
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: garage
|
|
spec:
|
|
selector:
|
|
app: garage
|
|
ports:
|
|
- name: s3
|
|
port: 3900
|
|
targetPort: 3900
|
|
nodePort: 32390
|
|
- name: web
|
|
port: 3902
|
|
targetPort: 3902
|
|
type: NodePort
|
|
|
|
---
|
|
# Admin API — ClusterIP only (not publicly reachable).
|
|
# Use via: kubectl port-forward -n default svc/garage-admin 3903:3903
|
|
# Then hit http://localhost:3903 with bearer $(pass show homelab/GARAGE_ADMIN_TOKEN)
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: garage-admin
|
|
spec:
|
|
selector:
|
|
app: garage
|
|
ports:
|
|
- name: admin
|
|
port: 3903
|
|
targetPort: 3903
|
|
type: ClusterIP
|