initial import
This commit is contained in:
commit
04d764c492
4
0ns.yaml
Normal file
4
0ns.yaml
Normal file
|
@ -0,0 +1,4 @@
|
|||
kind: Namespace
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: garage
|
25
cm.yaml
Normal file
25
cm.yaml
Normal file
|
@ -0,0 +1,25 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: garage-config
|
||||
namespace: garage
|
||||
data:
|
||||
metadata_dir: "/var/lib/garage/meta"
|
||||
data_dir: "/var/lib/garage/data"
|
||||
rpc_bind_addr: "[::]:3901"
|
||||
|
||||
replication_factor: "2"
|
||||
consistency_mode: "consistent"
|
||||
|
||||
bootstrap_peers: |
|
||||
[]
|
||||
|
||||
s3_api.s3_region: "us-east-1"
|
||||
s3_api.api_bind_addr: "[::]:3900"
|
||||
s3_api.root_domain: ".strudelline.net"
|
||||
|
||||
s3_web.bind_addr: "[::]:3902"
|
||||
s3_web.root_domain: ".web.strudelline.net"
|
||||
s3_web.add_host_to_metrics: "true"
|
||||
|
||||
admin.api_bind_addr: "[::]:3903"
|
172
ds.yaml
Normal file
172
ds.yaml
Normal file
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
namespace: garage
|
||||
name: garage
|
||||
labels:
|
||||
app: garage
|
||||
annotations:
|
||||
reloader.stakater.com/auto: "true"
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: garage
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: garage
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 0
|
||||
hostNetwork: true
|
||||
initContainers:
|
||||
- name: config
|
||||
restartPolicy: Always
|
||||
image: git.strudelline.net/cascade/tools:latest
|
||||
command: [bash, -c]
|
||||
args:
|
||||
- |
|
||||
set -e
|
||||
|
||||
cd /config-in
|
||||
|
||||
# enumerate the global configs
|
||||
# with the while loop, restartPolicy, and startupProbe: operate as a sidecar.
|
||||
# this has a huge delay and probably isn't safe so it's disabled for now.
|
||||
#while true;do
|
||||
(
|
||||
find . -maxdepth 1 -mindepth 1 -name '[a-z]*' -not -name '*.*' -print | (
|
||||
while read -r f;do
|
||||
echo -n "${f#./} = "
|
||||
# if it's valid json, keep it that way (true/false, numbers, etc).
|
||||
# IF IT IS REQUIRED TO PASS "true" AS A STRING:
|
||||
# put it in quoted quotes in the configmap like stupid_hostname: '"true"'
|
||||
jq . "$f" 2> /dev/null || jq -R . "$f"
|
||||
done)
|
||||
# enumerate the sectioned configs
|
||||
find . -maxdepth 1 -mindepth 1 -name '[a-z]*.*' -not -name garage.toml -print | (
|
||||
cut -c 3- | cut -d. -f1 |
|
||||
sort | uniq | while read -r SECTION;do
|
||||
echo
|
||||
echo "[$SECTION]"
|
||||
for f in "$SECTION".*;do
|
||||
echo -n "${f#*.} = "
|
||||
# if it's valid json, keep it that way (true/false, numbers, etc).
|
||||
# IF IT IS REQUIRED TO PASS "true" AS A STRING:
|
||||
# put it in quoted quotes in the configmap like stupid_hostname: '"true"'
|
||||
jq . "$f" 2> /dev/null || jq -R . "$f"
|
||||
done
|
||||
done)
|
||||
) > /config/garage.toml
|
||||
#) > /config/garage.toml.new
|
||||
#if diff -Nq "/config/garage.toml.new" "/config/garage.toml";then
|
||||
# mv /config/garage.toml.new /config/garage.toml
|
||||
# echo "config settled."
|
||||
# inotifywait -r -t 30 /config-in
|
||||
#else
|
||||
# mv /config/garage.toml.new /config/garage.toml
|
||||
# echo "rerunning shortly to settle config"
|
||||
# sleep 1
|
||||
#fi
|
||||
#done
|
||||
while true;do
|
||||
(
|
||||
DD="$(cat data_dir)"
|
||||
DDFREE="$(stat -fc "%a * %s" "$DD" | bc)"
|
||||
echo "strudelline.net/garage-data-free-bytes"="$DDFREE"
|
||||
|
||||
MD="$(cat metadata_dir)"
|
||||
MDFREE="$(stat -fc "%a * %s" "$MD" | bc)"
|
||||
echo "strudelline.net/garage-meta-free-bytes"="$MDFREE"
|
||||
) | sponge /nfd-features-d/garage
|
||||
cat /nfd-features-d/garage
|
||||
echo "sleeping."
|
||||
sleep 60
|
||||
done
|
||||
startupProbe:
|
||||
exec:
|
||||
command: [ grep, -q, "metadata_dir", /config/garage.toml ]
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
failureThreshold: 20
|
||||
volumeMounts:
|
||||
- name: meta
|
||||
mountPath: /var/lib/garage/meta
|
||||
- name: data
|
||||
mountPath: /var/lib/garage/data
|
||||
- name: config-in
|
||||
mountPath: /config-in
|
||||
- name: config-xfr
|
||||
mountPath: /config
|
||||
- name: nfd-features-d
|
||||
mountPath: /nfd-features-d
|
||||
containers:
|
||||
- image: dxflrs/garage:v1.1.0
|
||||
name: garage
|
||||
env:
|
||||
- name: PATH
|
||||
value: "/"
|
||||
- name: GARAGE_ADMIN_TOKEN_FILE
|
||||
value: /secrets/admin-token
|
||||
- name: GARAGE_RPC_SECRET_FILE
|
||||
value: /secrets/rpc-secret
|
||||
- name: GARAGE_METRICS_TOKEN_FILE
|
||||
value: /secrets/metrics-token
|
||||
- name: GARAGE_CONFIG_FILE
|
||||
value: /config/garage.toml
|
||||
- name: GARAGE_ALLOW_WORLD_READABLE_SECRETS
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 3900
|
||||
name: s3-api
|
||||
- containerPort: 3901
|
||||
name: rpc
|
||||
- containerPort: 3902
|
||||
name: s3-web
|
||||
- containerPort: 3903
|
||||
name: admin-api
|
||||
volumeMounts:
|
||||
- name: meta
|
||||
mountPath: /var/lib/garage/meta
|
||||
- name: data
|
||||
mountPath: /var/lib/garage/data
|
||||
- name: config-xfr
|
||||
mountPath: /config
|
||||
- name: secrets
|
||||
mountPath: /secrets
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: admin-api
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 1
|
||||
failureThreshold: 120
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: admin-api
|
||||
initialDelaySeconds: 1
|
||||
periodSeconds: 5
|
||||
failureThreshold: 10
|
||||
volumes:
|
||||
- name: config-xfr
|
||||
emptyDir: {}
|
||||
- name: config-in
|
||||
configMap:
|
||||
name: garage-config
|
||||
- name: meta
|
||||
hostPath:
|
||||
path: /var/lib/garage/meta
|
||||
type: DirectoryOrCreate
|
||||
- name: data
|
||||
hostPath:
|
||||
path: /var/lib/garage/data
|
||||
type: DirectoryOrCreate
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: garage-secrets
|
||||
- name: nfd-features-d
|
||||
hostPath:
|
||||
path: /etc/kubernetes/node-feature-discovery/features.d
|
||||
type: DirectoryOrCreate
|
||||
restartPolicy: Always
|
29
ingress.yaml
Normal file
29
ingress.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: garage-web
|
||||
namespace: garage
|
||||
spec:
|
||||
ingressClassName: haproxy
|
||||
rules:
|
||||
- host: 'strudelline.net'
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: garage
|
||||
port:
|
||||
name: s3-web
|
||||
- host: '*.strudelline.net'
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: garage
|
||||
port:
|
||||
name: s3-api
|
29
svc.yaml
Normal file
29
svc.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: garage
|
||||
name: garage
|
||||
namespace: garage
|
||||
spec:
|
||||
selector:
|
||||
app: garage
|
||||
ports:
|
||||
- port: 3900
|
||||
name: s3-api
|
||||
protocol: TCP
|
||||
targetPort: s3-api
|
||||
- port: 3901
|
||||
name: rpc
|
||||
protocol: TCP
|
||||
targetPort: rpc
|
||||
- port: 3902
|
||||
name: s3-web
|
||||
protocol: TCP
|
||||
targetPort: s3-web
|
||||
- port: 3903
|
||||
name: admin
|
||||
protocol: TCP
|
||||
targetPort: admin
|
||||
|
||||
type: ClusterIP
|
160
tools
Executable file
160
tools
Executable file
|
@ -0,0 +1,160 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e -o pipefail
|
||||
|
||||
shq() {(
|
||||
while [ $# -gt 0 ];do
|
||||
echo -n "'$(echo -n "$1" | sed -e "s/'/'\"'\"'/g")'"
|
||||
shift
|
||||
done
|
||||
)}
|
||||
|
||||
json() {( # json encode the argument
|
||||
jq -n --arg v "$@" '$v'
|
||||
)}
|
||||
|
||||
GARAGE_NAMESPACE="${GARAGE_NAMESPACE-garage}"
|
||||
|
||||
ARGS="$(shq "$@")"
|
||||
ZERO="$0"
|
||||
ONE="$1"
|
||||
ONE_UNDER="$(echo -n "$ONE" | tr - _)"
|
||||
NL="$(echo)"
|
||||
|
||||
enumerate_pods() { # enumerate kubernetes-based garage pods
|
||||
kubectl get pod -n "$GARAGE_NAMESPACE" -l app=garage -o json | yq -ot '.items[] | [
|
||||
.metadata.name,
|
||||
.status.podIP,
|
||||
.spec.containers[].ports[]|select(.name == "rpc")|.hostPort,
|
||||
.spec.nodeName
|
||||
]' | while read -r pod ip port node;do
|
||||
gnid="$(grun "$pod" node id -q)"
|
||||
printf "%${#pod}s %25s %s\n" $pod $node "$gnid@$ip:$port"
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
get_ids() { # get the public id of all discoverable servers
|
||||
enumerate_pods | while read -r pod node gnid;do
|
||||
echo "$gnid"
|
||||
done
|
||||
}
|
||||
|
||||
iterstats() { # get stats from running garage nodes via iteration over discovered ids
|
||||
get_ids | while read -r id;do
|
||||
garage -h "$id" stats
|
||||
done
|
||||
}
|
||||
|
||||
grun() {
|
||||
TARGET="$1"
|
||||
shift
|
||||
kubectl exec -n "$GARAGE_NAMESPACE" -c garage "$TARGET" -- garage "$@"
|
||||
}
|
||||
|
||||
garage() { # run an arbitrary garage command via a random garage pod
|
||||
grun ds/garage "$@"
|
||||
}
|
||||
|
||||
generate_secrets() { # generates secrets required to run garage
|
||||
kubectl create secret -n "$GARAGE_NAMESPACE" generic garage-secrets \
|
||||
--from-literal=admin-token="$( openssl rand -base64 32 )" \
|
||||
--from-literal=metrics-token="$( openssl rand -base64 32 )" \
|
||||
--from-literal=rpc-secret="$( openssl rand -hex 32 )"
|
||||
}
|
||||
|
||||
generate_layout() {( # generates a sample layout, (args are included verbatim, e.g. -t k8s)
|
||||
enumerate_pods | while read -r pod node gnid;do
|
||||
kubectl get node/$node -o json | jq -r --arg zero "$ZERO" '
|
||||
[
|
||||
$zero,
|
||||
"garage", "layout", "assign",
|
||||
"-t", .metadata.name,
|
||||
"-c", "\(.metadata.labels["strudelline.net/garage-meta-free-bytes"]|tonumber/1024/1024/1024|floor)G"
|
||||
]+$ARGS.positional
|
||||
| @sh' --args -- "$@" "${gnid%%@*}" | while read -r cmd;do
|
||||
eval "set $cmd"
|
||||
printf " %q" "$@" | cut -c 2-
|
||||
done
|
||||
done
|
||||
)}
|
||||
|
||||
make_bucket() { # make a bucket along with metadata in a namespace
|
||||
TARGETBUCKET="$1"
|
||||
TARGETKEYNAME="${2-$TARGETBUCKET}-app-key"
|
||||
TARGETNS="${3-$TARGETBUCKET}"
|
||||
TARGETSECRET="${3-$TARGETKEYNAME}"
|
||||
|
||||
kubectl get namespace "$TARGETNS" > /dev/null
|
||||
|
||||
garage bucket create "$TARGETBUCKET"
|
||||
eval "$(
|
||||
(garage key info "$TARGETKEYNAME" 2> /dev/null || garage key create "$TARGETKEYNAME") | awk '
|
||||
/^key id: /i {printf("KID=%s\n", $3);}
|
||||
/^secret key: /i {printf("SK=%s\n", $3);}
|
||||
')"
|
||||
garage bucket allow --read --write --owner "$TARGETBUCKET" --key "$TARGETKEYNAME"
|
||||
|
||||
kubectl create secret generic \
|
||||
-n "$TARGETNS" "$TARGETSECRET" \
|
||||
--type kubernetes.io/basic-auth \
|
||||
--from-literal=username="$KID" \
|
||||
--from-literal=password="$SK" \
|
||||
--from-literal=AWS_ACCESS_KEY_ID="$KID" \
|
||||
--from-literal=AWS_SECRET_ACCESS_KEY="$SK" \
|
||||
--from-literal=bucket="$TARGETBUCKET"
|
||||
|
||||
kubectl label -n "$TARGETNS" secret/$TARGETSECRET bucket="$TARGETBUCKET" key="$TARGETKEYNAME"
|
||||
}
|
||||
|
||||
connect() { # attempt to connect all nodes
|
||||
allids="$(get_ids)"
|
||||
primary="$(echo "$allids" | head -1)"
|
||||
echo "$allids" | sed 1d | while read -r id;do
|
||||
garage -h $primary node connect "$id"
|
||||
done
|
||||
}
|
||||
|
||||
env() { # connect your local garage cli to a random node
|
||||
jq -n -r \
|
||||
--argjson secret "$(kubectl get secret -n "$GARAGE_NAMESPACE" garage-secrets -o json)" \
|
||||
--arg gnid "$(get_ids | head -1)" \
|
||||
'
|
||||
rpc_secret=\($secret.data."rpc-secret")",
|
||||
RPC_HOST=\($gnid)"
|
||||
'
|
||||
}
|
||||
|
||||
help() {( # this help
|
||||
exec 1>&2
|
||||
|
||||
echo "usage: $0 <subcmd> [options]"
|
||||
echo
|
||||
echo GARAGE SUBCOMMANDS:
|
||||
( 2>&1 garage --help || true ) | awk 'p==1&&/^ / {print lc,$0;next} p==1 {lc=$1;print;} /^SUBCOMMANDS:$/ {p=1}' | while read -r cmd help;do
|
||||
printf " %-25s %s\n" "garage $cmd" "$help"
|
||||
done
|
||||
echo
|
||||
echo "GARAGE CLUSTER TOOLS:"
|
||||
grep -E "^[a-z_]+[(][)] {[(]? # .*" "$ZERO" | sed -Ee 's@[(][)] [{][(]? # @: @' |
|
||||
while read cmd help;do
|
||||
printf " %-25s %s\n" "$(echo -n $cmd | tr _ -)" "$help"
|
||||
done
|
||||
echo
|
||||
)}
|
||||
|
||||
if [ "x$1" = x ];then
|
||||
help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# we translate - to _ to allow enumerate-pods or enumerate_pods.
|
||||
# it also changes -h to _h.
|
||||
|
||||
if [ "x$ONE" = "x-h" ];then
|
||||
help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
shift 1
|
||||
"$ONE_UNDER" "$@"
|
Loading…
Reference in New Issue
Block a user