Add helm chart #331

Merged
lx merged 10 commits from chemicstry/garage:helm_chart into main 2022-10-02 14:40:55 +00:00
5 changed files with 64 additions and 3 deletions
Showing only changes of commit b71fa2ddf4 - Show all commits

View file

@ -23,6 +23,13 @@ If release name contains chart name it will be used as a full name.
{{- end }} {{- end }}
{{- end }} {{- end }}
{{/*
Create the name of the rpc secret
*/}}
{{- define "garage.rpcSecretName" -}}
{{- printf "%s-rpc-secret" (include "garage.fullname" .) -}}
{{- end }}
{{/* {{/*
Create chart name and version as used by the chart label. Create chart name and version as used by the chart label.
*/}} */}}
@ -60,3 +67,22 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }} {{- default "default" .Values.serviceAccount.name }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{/*
Returns given number of random Hex characters.
In practice, it generates up to 100 randAlphaNum strings
that are filtered from non-hex characters and augmented
to the resulting string that is finally trimmed down.
*/}}
{{- define "jupyterhub.randHex" -}}
{{- $result := "" }}
{{- range $i := until 100 }}
{{- if lt (len $result) . }}
{{- $rand_list := randAlphaNum . | splitList "" -}}
{{- $reduced_list := without $rand_list "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" }}
{{- $rand_string := join "" $reduced_list }}
{{- $result = print $result $rand_string -}}
{{- end }}
{{- end }}
{{- $result | trunc . }}
{{- end }}

View file

@ -10,7 +10,8 @@ data:
replication_mode = "{{ .Values.garage.replicationMode }}" replication_mode = "{{ .Values.garage.replicationMode }}"
rpc_bind_addr = "{{ .Values.garage.rpcBindAddr }}" rpc_bind_addr = "{{ .Values.garage.rpcBindAddr }}"
rpc_secret = "{{ .Values.garage.rpcSecret }}" # rpc_secret will be populated by the init container from a k8s secret object
rpc_secret = "__RPC_SECRET_REPLACE__"
bootstrap_peers = {{ .Values.garage.bootstrapPeers }} bootstrap_peers = {{ .Values.garage.bootstrapPeers }}

View file

@ -0,0 +1,14 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "garage.rpcSecretName" . }}
labels:
{{- include "garage.labels" . | nindent 4 }}
type: Opaque
data:
{{/* retrieve the secret data using lookup function and when not exists, return an empty dictionary / map as result */}}
{{- $prevSecret := (lookup "v1" "Secret" .Release.Namespace (include "garage.rpcSecretName" .)) | default dict }}
{{- $prevSecretData := $prevSecret.data | default dict }}
{{- $prevRpcSecret := $prevSecretData.rpcSecret | default "" | b64dec }}
{{/* Priority is: 1. from values, 2. previous value, 3. generate random */}}
rpcSecret: {{ .Values.garage.rpcSecret | default $prevRpcSecret | default (include "jupyterhub.randHex" 64) | b64enc | quote }}

View file

@ -26,6 +26,23 @@ spec:
serviceAccountName: {{ include "garage.serviceAccountName" . }} serviceAccountName: {{ include "garage.serviceAccountName" . }}
securityContext: securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }} {{- toYaml .Values.podSecurityContext | nindent 8 }}
initContainers:
# Copies garage.toml from configmap to temporary etc volume and replaces RPC secret placeholder
- name: {{ .Chart.Name }}-init
image: busybox:1.28
command: ["sh", "-c", "sed \"s/__RPC_SECRET_REPLACE__/$RPC_SECRET/\" /mnt/garage.toml > /mnt/etc/garage.toml"]
env:
- name: RPC_SECRET
valueFrom:
secretKeyRef:
name: {{ include "garage.rpcSecretName" . }}
key: rpcSecret
volumeMounts:
- name: configmap
mountPath: /mnt/garage.toml
subPath: garage.toml
- name: etc
mountPath: /mnt/etc
containers: containers:
- name: {{ .Chart.Name }} - name: {{ .Chart.Name }}
securityContext: securityContext:
@ -57,9 +74,11 @@ spec:
resources: resources:
{{- toYaml .Values.resources | nindent 12 }} {{- toYaml .Values.resources | nindent 12 }}
volumes: volumes:
- name: etc - name: configmap
configMap: configMap:
name: {{ include "garage.fullname" . }}-config name: {{ include "garage.fullname" . }}-config
- name: etc
emptyDir: {}
{{- with .Values.nodeSelector }} {{- with .Values.nodeSelector }}
nodeSelector: nodeSelector:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}

View file

@ -8,7 +8,8 @@ garage:
dataDir: "/mnt/data" dataDir: "/mnt/data"
replicationMode: "3" replicationMode: "3"
rpcBindAddr: "[::]:3901" rpcBindAddr: "[::]:3901"
rpcSecret: "1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec" # If not given, a random secret will be generated
maximilien marked this conversation as resolved Outdated

Does it mean that if people deploy this helm chart without overriding this value,
they will have a working but vulnerable cluster?

We have some discussions about adding some defense in depth mechanisms to Garage (here: #310) in case this secret leaks but for now, an attack knowing this secret could join the clusteras long as the RPC port is accessible.

I think it could be better to replace this field by something that will make the cluster crashes if not overriden, like "CHANGE ME!!!!"

Does it mean that if people deploy this helm chart without overriding this value, they will have a working but vulnerable cluster? We have some discussions about adding some defense in depth mechanisms to Garage (here: https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/310) in case this secret leaks but for now, an attack knowing this secret could join the clusteras long as the RPC port is accessible. I think it could be better to replace this field by something that will make the cluster crashes if not overriden, like "CHANGE ME!!!!"

Good point. I think it would be best to store rcpSecret as a kubernetes Secret object, which is randomly generated if not provided, but then there is a problem how to inject that into container configuration. It would be easier if garage accepted configuration through env vars. Otherwise I think the only option is to fire up an init container and patch up configuration toml.

Good point. I think it would be best to store rcpSecret as a kubernetes Secret object, which is randomly generated if not provided, but then there is a problem how to inject that into container configuration. It would be easier if garage accepted configuration through env vars. Otherwise I think the only option is to fire up an init container and patch up configuration toml.
rpcSecret: ""
bootstrapPeers: [] bootstrapPeers: []
kubernetesSkipCrd: false kubernetesSkipCrd: false
s3: s3: