diff --git a/Charts/tiled/templates/NOTES.txt b/Charts/tiled/templates/NOTES.txt index 2560662..f3fb01c 100644 --- a/Charts/tiled/templates/NOTES.txt +++ b/Charts/tiled/templates/NOTES.txt @@ -1,22 +1,11 @@ 1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- range $.Values.beamlines }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}/api/v1/search/{{ .name }} {{- end }} {{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "tiled.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "tiled.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "tiled.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "tiled.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") +{{- else }} echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT + kubectl --namespace {{ .Release.Namespace }} port-forward svc/{{ include "tiled.fullname" . }}-envoy 8080:{{ .Values.envoy.service.port }} {{- end }} diff --git a/Charts/tiled/templates/_helpers.tpl b/Charts/tiled/templates/_helpers.tpl index 2312e52..b3ee1b7 100644 --- a/Charts/tiled/templates/_helpers.tpl +++ b/Charts/tiled/templates/_helpers.tpl @@ -60,3 +60,15 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + +{{/* +Name of a beamline's Deployment and Service. Called with (dict "root" $ "beamline" .). +Fails rather than truncates, so two beamlines can never collide on one name. +*/}} +{{- define "tiled.beamlineFullname" -}} +{{- $name := printf "%s-%s" (include "tiled.fullname" .root) .beamline.name }} +{{- if gt (len $name) 63 }} +{{- fail (printf "%q is longer than 63 characters, shorten the release or beamline name" $name) }} +{{- end }} +{{- $name }} +{{- end }} diff --git a/Charts/tiled/templates/deployment.yaml b/Charts/tiled/templates/deployment.yaml index 7021db6..82ce563 100644 --- a/Charts/tiled/templates/deployment.yaml +++ b/Charts/tiled/templates/deployment.yaml @@ -1,67 +1,73 @@ +{{- range .Values.beamlines }} +--- apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "tiled.fullname" . }} + name: {{ include "tiled.beamlineFullname" (dict "root" $ "beamline" .) }} labels: - {{- include "tiled.labels" . | nindent 4 }} + {{- include "tiled.labels" $ | nindent 4 }} + tiled.io/beamline: {{ .name }} spec: - {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.replicaCount }} + {{- if not $.Values.autoscaling.enabled }} + replicas: {{ $.Values.replicaCount }} {{- end }} selector: matchLabels: - {{- include "tiled.selectorLabels" . | nindent 6 }} + {{- include "tiled.selectorLabels" $ | nindent 6 }} + tiled.io/beamline: {{ .name }} template: metadata: annotations: - {{- if .Values.rollOnConfigChange }} - checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- if $.Values.rollOnConfigChange }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") $ | sha256sum }} {{- end }} - {{- with .Values.podAnnotations }} + {{- with $.Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "tiled.labels" . | nindent 8 }} - {{- with .Values.podLabels }} + {{- include "tiled.labels" $ | nindent 8 }} + tiled.io/beamline: {{ .name }} + {{- with $.Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} spec: - {{- with .Values.imagePullSecrets }} + {{- with $.Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "tiled.serviceAccountName" . }} + serviceAccountName: {{ include "tiled.serviceAccountName" $ }} + {{- $beamlineSC := .securityContext | default dict }} securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- toYaml (merge (pick $beamlineSC "supplementalGroups") $.Values.podSecurityContext) | nindent 8 }} containers: - - name: {{ .Chart.Name }} + - name: {{ $.Chart.Name }} securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- with .Values.command }} + {{- toYaml (merge (omit $beamlineSC "supplementalGroups") $.Values.securityContext) | nindent 12 }} + image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag | default $.Chart.AppVersion }}" + imagePullPolicy: {{ $.Values.image.pullPolicy }} + {{- with $.Values.command }} command: {{- toYaml . | nindent 12 }} {{- end }} - {{- with .Values.args }} + {{- with $.Values.args }} args: {{- toYaml . | nindent 12 }} {{- end }} ports: - name: http - containerPort: {{ .Values.service.port }} + containerPort: 8000 protocol: TCP livenessProbe: - {{- toYaml .Values.livenessProbe | nindent 12 }} + {{- toYaml (merge (.livenessProbe | default dict) $.Values.livenessProbe) | nindent 12 }} readinessProbe: - {{- toYaml .Values.readinessProbe | nindent 12 }} + {{- toYaml (merge (.readinessProbe | default dict) $.Values.readinessProbe) | nindent 12 }} resources: - {{- toYaml .Values.resources | nindent 12 }} + {{- toYaml $.Values.resources | nindent 12 }} + {{- with concat $.Values.volumeMounts (.volumeMounts | default list) }} volumeMounts: - {{- with .Values.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} - {{- with .Values.extraEnvVars }} + {{- with concat $.Values.extraEnvVars (.extraEnvVars | default list) }} env: {{- toYaml . | nindent 12 }} {{- end }} @@ -70,19 +76,20 @@ spec: projected: sources: - configMap: - name: {{ include "tiled.fullname" . }}-config - {{- with .Values.volumes }} + name: {{ include "tiled.fullname" $ }}-config + {{- with concat $.Values.volumes (.volumes | default list) }} {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.nodeSelector }} + {{- with $.Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.affinity }} + {{- with $.Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.tolerations }} + {{- with $.Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} +{{- end }} diff --git a/Charts/tiled/templates/envoy-configmap.yaml b/Charts/tiled/templates/envoy-configmap.yaml new file mode 100644 index 0000000..924b44a --- /dev/null +++ b/Charts/tiled/templates/envoy-configmap.yaml @@ -0,0 +1,97 @@ +{{- if .Values.envoy.enabled }} +{{- /* A bad config stops envoy starting and takes the whole ingress down, so fail the render instead */}} +{{- $names := list }} +{{- range .Values.beamlines }}{{ $names = append $names .name }}{{ end }} +{{- if not (has .Values.envoy.defaultBeamline $names) }} +{{- fail (printf "envoy.defaultBeamline %q must be one of beamlines %v" .Values.envoy.defaultBeamline $names) }} +{{- end }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "tiled.fullname" . }}-envoy-config + labels: + {{- include "tiled.labels" . | nindent 4 }} + app.kubernetes.io/component: envoy-proxy +data: + envoy.yaml: | + # Only reachable from inside the pod (kubectl exec), so other pods can't + # e.g. POST /quitquitquit + admin: + address: + socket_address: { address: 127.0.0.1, port_value: {{ .Values.envoy.adminPort }} } + # The beamline regexes list every tiled endpoint, which is over RE2's default limit + layered_runtime: + layers: + - name: static + static_layer: + re2.max_program_size.error_level: 1000 + static_resources: + listeners: + - name: listener_http + address: + socket_address: { address: 0.0.0.0, port_value: {{ .Values.envoy.listenerPort }} } + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http + normalize_path: true + merge_slashes: true + # For the websockets of /api/v1/stream/single/... + upgrade_configs: + - upgrade_type: websocket + access_log: + - name: envoy.access_loggers.stdout + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog + route_config: + name: local_route + virtual_hosts: + - name: tiled_backend + domains: ["*"] + routes: + - match: + path: /envoy-ready + direct_response: + status: 200 + {{- range .Values.beamlines }} + {{- if ne .name $.Values.envoy.defaultBeamline }} + # The beamline is the first segment of the tiled path, + # e.g. /api/v1/search/{{ .name }}/... or /zarr/v2/{{ .name }}/... + - match: + safe_regex: + regex: {{ printf "^/(%s)/%s(/.*)?$" (join "|" $.Values.envoy.pathPrefixes) (regexQuoteMeta .name) | quote }} + route: + cluster: {{ .name }}_cluster + # No timeout: large array/asset reads and slow searches + # can take longer than envoy's 15s default + timeout: 0s + {{- end }} + {{- end }} + - match: + prefix: "/" + route: + cluster: {{ .Values.envoy.defaultBeamline }}_cluster + timeout: 0s + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + {{- range .Values.beamlines }} + - name: {{ .name }}_cluster + connect_timeout: 5s + type: STRICT_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: {{ .name }}_cluster + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: {{ include "tiled.beamlineFullname" (dict "root" $ "beamline" .) }}.{{ $.Release.Namespace }}.svc.cluster.local + port_value: {{ $.Values.service.port }} + {{- end }} +{{- end }} diff --git a/Charts/tiled/templates/envoy-deployment.yaml b/Charts/tiled/templates/envoy-deployment.yaml new file mode 100644 index 0000000..2d79ea5 --- /dev/null +++ b/Charts/tiled/templates/envoy-deployment.yaml @@ -0,0 +1,76 @@ +{{- if .Values.envoy.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "tiled.fullname" . }}-envoy + labels: + {{- include "tiled.labels" . | nindent 4 }} + app.kubernetes.io/component: envoy-proxy +spec: + replicas: {{ .Values.envoy.replicaCount }} + selector: + matchLabels: + {{- include "tiled.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: envoy-proxy + template: + metadata: + labels: + {{- include "tiled.labels" . | nindent 8 }} + app.kubernetes.io/component: envoy-proxy + {{- if .Values.rollOnConfigChange }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/envoy-configmap.yaml") . | sha256sum }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.envoy.podSecurityContext | nindent 8 }} + containers: + - name: envoy + image: "{{ .Values.envoy.image.repository }}:{{ .Values.envoy.image.tag }}" + imagePullPolicy: {{ .Values.envoy.image.pullPolicy }} + securityContext: + {{- toYaml .Values.envoy.securityContext | nindent 12 }} + command: + - envoy + args: + - -c + - /etc/envoy/envoy.yaml + ports: + - name: http + containerPort: {{ .Values.envoy.listenerPort }} + protocol: TCP + readinessProbe: + httpGet: + path: /envoy-ready + port: http + livenessProbe: + httpGet: + path: /envoy-ready + port: http + volumeMounts: + - name: envoy-config + mountPath: /etc/envoy + readOnly: true + resources: + {{- toYaml .Values.envoy.resources | nindent 12 }} + volumes: + - name: envoy-config + configMap: + name: {{ include "tiled.fullname" . }}-envoy-config + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/Charts/tiled/templates/envoy-pdb.yaml b/Charts/tiled/templates/envoy-pdb.yaml new file mode 100644 index 0000000..0592a44 --- /dev/null +++ b/Charts/tiled/templates/envoy-pdb.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.envoy.enabled (gt (int .Values.envoy.replicaCount) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "tiled.fullname" . }}-envoy + labels: + {{- include "tiled.labels" . | nindent 4 }} + app.kubernetes.io/component: envoy-proxy +spec: + maxUnavailable: 1 + selector: + matchLabels: + {{- include "tiled.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: envoy-proxy +{{- end }} diff --git a/Charts/tiled/templates/envoy-service.yaml b/Charts/tiled/templates/envoy-service.yaml new file mode 100644 index 0000000..439db5d --- /dev/null +++ b/Charts/tiled/templates/envoy-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.envoy.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "tiled.fullname" . }}-envoy + labels: + {{- include "tiled.labels" . | nindent 4 }} + app.kubernetes.io/component: envoy-proxy +spec: + type: {{ .Values.envoy.service.type }} + ports: + - port: {{ .Values.envoy.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "tiled.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: envoy-proxy +{{- end }} diff --git a/Charts/tiled/templates/hpa.yaml b/Charts/tiled/templates/hpa.yaml index 26e05d5..ed17b86 100644 --- a/Charts/tiled/templates/hpa.yaml +++ b/Charts/tiled/templates/hpa.yaml @@ -1,32 +1,36 @@ {{- if .Values.autoscaling.enabled }} +{{- range .Values.beamlines }} +--- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: - name: {{ include "tiled.fullname" . }} + name: {{ include "tiled.beamlineFullname" (dict "root" $ "beamline" .) }} labels: - {{- include "tiled.labels" . | nindent 4 }} + {{- include "tiled.labels" $ | nindent 4 }} + tiled.io/beamline: {{ .name }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: {{ include "tiled.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} + name: {{ include "tiled.beamlineFullname" (dict "root" $ "beamline" .) }} + minReplicas: {{ $.Values.autoscaling.minReplicas }} + maxReplicas: {{ $.Values.autoscaling.maxReplicas }} metrics: - {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- if $.Values.autoscaling.targetCPUUtilizationPercentage }} - type: Resource resource: name: cpu target: type: Utilization - averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + averageUtilization: {{ $.Values.autoscaling.targetCPUUtilizationPercentage }} {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- if $.Values.autoscaling.targetMemoryUtilizationPercentage }} - type: Resource resource: name: memory target: type: Utilization - averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + averageUtilization: {{ $.Values.autoscaling.targetMemoryUtilizationPercentage }} {{- end }} {{- end }} +{{- end }} diff --git a/Charts/tiled/templates/ingress.yaml b/Charts/tiled/templates/ingress.yaml index 64cc215..cb87c88 100644 --- a/Charts/tiled/templates/ingress.yaml +++ b/Charts/tiled/templates/ingress.yaml @@ -25,19 +25,15 @@ spec: {{- end }} rules: {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} + - host: {{ . | quote }} http: paths: - {{- range .paths }} - - path: {{ .path }} - {{- with .pathType }} - pathType: {{ . }} - {{- end }} + - path: / + pathType: Prefix backend: service: - name: {{ include "tiled.fullname" $ }} + name: {{ include "tiled.fullname" $ }}-envoy port: - number: {{ $.Values.service.port }} - {{- end }} + number: {{ $.Values.envoy.service.port }} {{- end }} {{- end }} diff --git a/Charts/tiled/templates/service.yaml b/Charts/tiled/templates/service.yaml index 5feb1af..338401f 100644 --- a/Charts/tiled/templates/service.yaml +++ b/Charts/tiled/templates/service.yaml @@ -1,15 +1,20 @@ +{{- range .Values.beamlines }} +--- apiVersion: v1 kind: Service metadata: - name: {{ include "tiled.fullname" . }} + name: {{ include "tiled.beamlineFullname" (dict "root" $ "beamline" .) }} labels: - {{- include "tiled.labels" . | nindent 4 }} + {{- include "tiled.labels" $ | nindent 4 }} + tiled.io/beamline: {{ .name }} spec: - type: {{ .Values.service.type }} + type: {{ $.Values.service.type }} ports: - - port: {{ .Values.service.port }} + - port: {{ $.Values.service.port }} targetPort: http protocol: TCP name: http selector: - {{- include "tiled.selectorLabels" . | nindent 4 }} + {{- include "tiled.selectorLabels" $ | nindent 4 }} + tiled.io/beamline: {{ .name }} +{{- end }} diff --git a/Charts/tiled/templates/tests/test-connection.yaml b/Charts/tiled/templates/tests/test-connection.yaml index 54d3daa..bb75378 100644 --- a/Charts/tiled/templates/tests/test-connection.yaml +++ b/Charts/tiled/templates/tests/test-connection.yaml @@ -11,5 +11,5 @@ spec: - name: wget image: busybox command: ['wget'] - args: ['{{ include "tiled.fullname" . }}:{{ .Values.service.port }}'] + args: ['{{ include "tiled.fullname" . }}-envoy:{{ .Values.envoy.service.port }}/healthz'] restartPolicy: Never diff --git a/Charts/tiled/values.yaml b/Charts/tiled/values.yaml index 2ca1612..56104b4 100644 --- a/Charts/tiled/values.yaml +++ b/Charts/tiled/values.yaml @@ -2,6 +2,21 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. +# One tiled Deployment and Service per beamline. Each may add its own +# securityContext (supplementalGroups for POSIX access to the beamline data), +# livenessProbe, readinessProbe, extraEnvVars, volumes and volumeMounts, which are merged with or appended to the global values below, e.g. +# - name: p51 +# securityContext: +# supplementalGroups: [12345] +# volumes: +# - name: data +# hostPath: {path: /dls/p51/data} +# volumeMounts: +# - name: data +# mountPath: /dls/p51/data +beamlines: + - name: default + # The tiled server config, rendered into a ConfigMap mounted at /deploy/config. config: # Opt in to the dls-tiled plugins by listing their routers, e.g. the ViSR binning @@ -10,6 +25,12 @@ config: # - dls_tiled.visr:visr_router authentication: allow_anonymous_access: false + # Envoy sends /...//... to that beamline's pod, unchanged, so the + # beamline is the first node under the tree's root. + # To let tokens issued by one pod verify on the others (all /api/v1/auth/* traffic + # goes to envoy.defaultBeamline), share the signing keys, e.g. + # secret_keys: ["$TILED_SECRET_KEY"] + # with TILED_SECRET_KEY added to extraEnvVars from a Secret. trees: - path: / tree: catalog @@ -18,8 +39,8 @@ config: writable_storage: "/storage/data" init_if_not_exists: true -# Restart the tiled pods when their ConfigMap changes, by putting a checksum of -# it in a pod annotation. See +# Restart the tiled and envoy pods when their ConfigMap changes, by putting a +# checksum of it in a pod annotation. See # https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments rollOnConfigChange: true @@ -81,25 +102,77 @@ service: # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types type: ClusterIP # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + # The Service port; tiled itself always listens on 8000 (the image CMD) port: 8000 # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: enabled: false className: "" + # A single "/" path (plain "Prefix" pathType) is forwarded to the envoy + # proxy Service (see .Values.envoy below), which performs the actual + # per-beamline regex routing. Cluster policy (Kyverno) disallows + # "ImplementationSpecific"/regex paths directly on Ingress resources, + # so that routing logic lives in envoy instead of here. annotations: {} - # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific + - chart-example.local tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local +# Envoy proxy that performs regex-based routing to the per-beamline +# Services, matching requests where the beamline name is the first segment of +# the tiled path (e.g. /api/v1/search/p51/cm44254/cm44254-1/data) and +# forwarding the complete, unmodified request to that beamline's own +# Service. This exists because the Ingress resource itself can't do regex +# path matching under the cluster's Kyverno policy (see ingress.annotations +# comment above). Any request that doesn't match a beamline's name-in-path +# regex (e.g. the UI at "/") falls through to the defaultBeamline's Service. +envoy: + enabled: true + # Envoy is in front of every beamline, so run more than one; a + # PodDisruptionBudget is added when this is above 1 + replicaCount: 2 + image: + repository: envoyproxy/envoy + tag: v1.39.4 + pullPolicy: IfNotPresent + listenerPort: 10000 + # Bound to 127.0.0.1, use with kubectl exec + adminPort: 9901 + # The tiled endpoints, before the tiled path, that envoy routes on. Add any + # plugin routers enabled in config.routers (mounted at /custom and /api/v1). + pathPrefixes: + - api/v1/(search|distinct|metadata|register|data_source|revisions) + - api/v1/(array|ragged)/(block|full) + - api/v1/(table/partition|table/full|container/full|node/full) + - api/v1/(awkward/buffers|awkward/full|asset/bytes|asset/manifest) + - api/v1/stream/(single|close) + - (api/v1|custom)/binned + - zarr/v[23] + # Name of the entry in .Values.beamlines that catch-all (unmatched) requests + # are routed to. + defaultBeamline: default + service: + type: ClusterIP + port: 8080 + resources: {} + # Run as a fixed non-root user. The Deployment starts envoy directly with + # `command: [envoy]`, skipping the image's docker-entrypoint.sh, which only + # matters when starting as root. + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little @@ -113,6 +186,8 @@ resources: {} # memory: 128Mi # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +# Each beamline in .Values.beamlines may set its own livenessProbe/readinessProbe +# to override these defaults (same merge pattern as beamlines[].securityContext). livenessProbe: httpGet: path: /healthz diff --git a/README.md b/README.md index 828956e..0b8a89f 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,43 @@ Plugins are off by default; see the `config.routers` comment in `Charts/tiled/values.yaml`. The `TILED_SINGLE_USER_API_KEY` environment variable is read from the optional secret `tiled-secrets`. +### Postgres databases + +Tiled uses postgres for the catalog (`tiled`), the authentication database +(`auth`) and tabular data storage (`data`). Until this is done by an init +container in the chart, create and initialize them by hand. + +Create the databases from the postgres pod: + +```bash +kubectl exec -it tiled-testing-postgres-77669bf4c5-t8jmc -n tiled-staging -- psql -U postgres +``` + +```sql +CREATE DATABASE tiled; +CREATE DATABASE auth; +CREATE DATABASE data; +``` + +Then start a throwaway tiled pod, exec into it and create the tables: + +```bash +kubectl run tiled-init -n tiled-staging --image=ghcr.io/bluesky/tiled:0.2.18 \ + --restart=Never --command \ + -- sleep infinity +kubectl exec -it tiled-init -n tiled-staging -- bash +``` + +```bash +export POSTGRESQL_PASSWORD="password" + +tiled catalog init --if-not-exists postgresql+asyncpg://postgres:${POSTGRESQL_PASSWORD}@tiled-testing-postgres:5432/tiled + +tiled admin initialize-database postgresql+asyncpg://postgres:${POSTGRESQL_PASSWORD}@tiled-testing-postgres:5432/auth + +kubectl delete pod tiled-init -n tiled-staging --now +``` + ## Logging tiled's default logging config has no handler for the plugin loggers, so their