Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blobvault): Make blobvault pvc storage optional if s3 bucket is used #148

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

## Installation

## Pre-installation steps


### Create namespace

We'll install Studio and related components in a dedicated `studio` namespace.
Expand Down Expand Up @@ -131,6 +128,19 @@ global:
-----END RSA PRIVATE KEY-----
```


## Upgrading to 0.60.x and above

This 0.60.0 fixes the issue with Ingress objects not being cleaned up.
To upgrade to 0.60.0 and above, you need to manually delete the Ingress object before upgrading:
mjasion marked this conversation as resolved.
Show resolved Hide resolved

```bash
kubectl delete ingress -l app.kubernetes.io/managed-by=Helm --namespace studio
kubectl delete ingress blobvault --namespace studio
```

The rest of upgrade process is the same as described below.
mjasion marked this conversation as resolved.
Show resolved Hide resolved

## Update Studio Version

Studio's `studio-values.yaml` file points to the `latest` image tag, instructing Helm to always pull
Expand Down Expand Up @@ -168,3 +178,4 @@ $ helm uninstall studio --namespace studio
### Available Configuration

See [values file](charts/studio/values.yaml) with all available configuration flags.

7 changes: 2 additions & 5 deletions charts/studio/Chart.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
dependencies:
- name: nginx
repository: https://charts.bitnami.com/bitnami
version: 13.2.30
- name: redis
repository: https://charts.bitnami.com/bitnami
version: 17.14.3
Expand All @@ -11,5 +8,5 @@ dependencies:
- name: kuberay-operator
repository: https://ray-project.github.io/kuberay-helm
version: 0.6.0
digest: sha256:3b2dc8c1ca3e1841605034aca0e0dd7119c1fbcf17eecc47c997bf4510bce4cf
generated: "2023-08-16T00:49:28.269211675Z"
digest: sha256:11e47f1d691977c00cf3dd4454365b63ebdb81db484e837a1f720616a50fec63
generated: "2023-08-18T21:39:06.308367+02:00"
5 changes: 1 addition & 4 deletions charts/studio/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ apiVersion: v2
name: studio
description: A Helm chart for Kubernetes
type: application
version: 0.5.2
version: 0.6.0
appVersion: "v2.29.0"
maintainers:
- name: iterative
email: [email protected]
icon: "https://static.iterative.ai/logo/studio.svg"
dependencies:
- name: nginx
version: "13.2.30"
repository: "https://charts.bitnami.com/bitnami"
- name: redis
condition: redis.enabled
version: "17.14.3"
Expand Down
16 changes: 6 additions & 10 deletions charts/studio/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# studio

![Version: 0.5.2](https://img.shields.io/badge/Version-0.5.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.29.0](https://img.shields.io/badge/AppVersion-v2.29.0-informational?style=flat-square)
![Version: 0.6.0](https://img.shields.io/badge/Version-0.6.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.29.0](https://img.shields.io/badge/AppVersion-v2.29.0-informational?style=flat-square)

A Helm chart for Kubernetes

Expand All @@ -14,7 +14,6 @@ A Helm chart for Kubernetes

| Repository | Name | Version |
|------------|------|---------|
| https://charts.bitnami.com/bitnami | nginx | 13.2.30 |
| https://charts.bitnami.com/bitnami | postgresql | 11.9.13 |
| https://charts.bitnami.com/bitnami | redis | 17.14.3 |
| https://ray-project.github.io/kuberay-helm | kuberay-operator | 0.6.0 |
Expand All @@ -27,7 +26,7 @@ A Helm chart for Kubernetes
| global.blobvault.accessKeyId | string | `""` | Blobvault S3 access key ID |
| global.blobvault.bucket | string | `""` | Blobvault S3 bucket name |
| global.blobvault.endpointUrl | string | `""` | Blobvault S3 endpoint URL |
| global.blobvault.persistentVolume | object | `{"accessModes":["ReadWriteOnce"],"size":"30Gi","storageClassName":""}` | Blobvault local backing store settings. |
| global.blobvault.persistentVolume | object | `{"accessModes":["ReadWriteOnce"],"size":"30Gi","storageClassName":""}` | Blobvault local backing store settings. Not used when `global.blobvault.bucket` is set. |
| global.blobvault.persistentVolume.accessModes | list | ReadWriteOnce | Blobvault local backing store access mode. |
| global.blobvault.persistentVolume.size | string | `"30Gi"` | Blobvault local backing store size. |
| global.blobvault.persistentVolume.storageClassName | string | default storage class in the cluster. | Blobvault local backing store storage class. |
Expand Down Expand Up @@ -84,13 +83,6 @@ A Helm chart for Kubernetes
| global.scmProviders.webhookHost | string | `$global.host` value. | Custom hostname for incoming webhook (if Studio runs on a private network and you use SaaS versions of GitHub, GitLab, or Bitbucket) |
| global.secretKey | string | `""` | Studio: Secret key for signing Webhook payloads We recommend you set this externally. If left empty, a random key will be generated. |
| imagePullSecrets | list | `[]` | Secret containing Docker registry credentials |
| nginx.extraVolumeMounts[0].mountPath | string | `"/blobvault"` | |
| nginx.extraVolumeMounts[0].name | string | `"blobvault"` | |
| nginx.extraVolumes[0].name | string | `"blobvault"` | |
| nginx.extraVolumes[0].persistentVolumeClaim.claimName | string | `"blobvault"` | |
| nginx.ingress.enabled | bool | `false` | |
| nginx.serverBlock | string | see in `values.yaml` | Nginx for blobvault configuration |
| nginx.service.type | string | `"ClusterIP"` | |
| pgBouncer | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"enabled":false,"envFromSecret":"","envVars":{},"image":{"pullPolicy":"IfNotPresent","repository":"docker.io/bitnami/pgbouncer","tag":"1.20.1"},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"1000m","memory":"1024Mi"},"requests":{"cpu":"500m","memory":"512Mi"}},"securityContext":{},"service":{"port":6432,"type":"ClusterIP"},"serviceAccountName":"","tolerations":[]}` | PgBouncer settings group |
| pgBouncer.affinity | object | `{}` | PgBouncer pod affinity configuration |
| pgBouncer.autoscaling | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | PgBouncer autoscaling configuration |
Expand Down Expand Up @@ -143,6 +135,10 @@ A Helm chart for Kubernetes
| studioBeat | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"envFromSecret":"","envVars":{},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"200m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"securityContext":{},"tolerations":[]}` | Studio Beat settings group |
| studioBeat.envFromSecret | string | `""` | The name of an existing Secret that contains sensitive environment variables passed to beat pods. |
| studioBeat.envVars | object | `{}` | Additional environment variables for beat pods |
| studioBlobvault | object | `{"image":{"repository":"nginx","tag":"1.25.1-alpine"},"podSecurityContext":{},"securityContext":{},"service":{"port":80}}` | Studio: Additional service to expose the blobvault files generated by the worker It is enabled automatically if the worker is scaled to 1 replica and no bucket is configured |
| studioBlobvault.image | object | `{"repository":"nginx","tag":"1.25.1-alpine"}` | Image to use for the blobvault service |
| studioBlobvault.image.repository | string | `"nginx"` | Image repository |
| studioBlobvault.image.tag | string | `"1.25.1-alpine"` | Image tag |
| studioDvcxWorker | object | `{"affinity":{},"autoscaling":{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80},"envFromSecret":"","envVars":{},"ephemeralStorage":{"persistentVolumeClaim":{"storageClass":""},"size":"1Gi","type":"emptyDir"},"image":{"pullPolicy":"IfNotPresent","repository":"docker.iterative.ai/studio-dvcx-worker"},"nodeSelector":{},"podAnnotations":{},"podSecurityContext":{},"replicaCount":1,"resources":{"limits":{"cpu":"8000m","ephemeral-storage":"10Gi","memory":"16Gi"},"requests":{"cpu":"500m","ephemeral-storage":"500Mi","memory":"512Mi"}},"securityContext":{},"tolerations":[]}` | Studio DVCx Worker settings group |
| studioDvcxWorker.affinity | object | `{}` | DVCx worker pod affinity configuration |
| studioDvcxWorker.autoscaling | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"targetCPUUtilizationPercentage":80}` | DVCx worker autoscaling configuration |
Expand Down
32 changes: 32 additions & 0 deletions charts/studio/nginx/backend-sidecar.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
server {
listen 80;
access_log /dev/stdout;
error_log /dev/stdout debug;

{{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }}
rewrite /{{ include "studio.basePath" . }}/(.*) /$1 break;
{{- end }}

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://backend;
}
}

upstream backend {
server 127.0.0.1:8000;
}

# Health check endpoint
server {
access_log /dev/null main;
error_log /dev/null info;

listen 8080;
location / {
return 200 'OK';
}
}
57 changes: 57 additions & 0 deletions charts/studio/nginx/blobvault.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
server {
listen 80;
server_name _;
access_log /dev/stdout;
error_log /dev/stdout debug;

root /blobvault;

add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Studio-Trace-Id';

{{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }}
rewrite /{{ include "studio.basePath" . }}/blobvault/(.*) /$1 break;
{{- else }}
rewrite /blobvault/(.*) /$1 break;
{{- end }}

location ~ \.gz$ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'GET') {
add_header Content-Encoding gzip;
}
gzip off;
types { } default_type "application/json";
}

location /blobvault {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

gzip on;

try_files $uri $uri/ =404;
}
}

# Health check endpoint
server {
access_log /dev/null main;
error_log /dev/null info;

listen 8080;
location / {
return 200 'OK';
}
}
33 changes: 33 additions & 0 deletions charts/studio/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /dev/stdout main;
error_log /dev/stdout info;

sendfile on;
tcp_nopush on;

server_tokens off;

keepalive_timeout 65;

gzip on;


include /etc/nginx/conf.d/*.conf;
}
jesper7 marked this conversation as resolved.
Show resolved Hide resolved
mjasion marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 14 additions & 0 deletions charts/studio/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "studio-blobvault.labels" -}}
helm.sh/chart: {{ include "studio.chart" . }}
{{ include "studio-blobvault.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "pgbouncer.labels" -}}
helm.sh/chart: {{ include "studio.chart" . }}
{{ include "pgbouncer.selectorLabels" . }}
Expand All @@ -115,6 +124,11 @@ app.kubernetes.io/name: {{ include "studio.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{- define "studio-blobvault.selectorLabels" -}}
app.kubernetes.io/name: studio-blobvault
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{- define "studio-backend.selectorLabels" -}}
app.kubernetes.io/name: studio-backend
app.kubernetes.io/instance: {{ .Release.Name }}
Expand Down
6 changes: 6 additions & 0 deletions charts/studio/templates/configmap-studio-nginx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-nginx
data:
{{ ( tpl (.Files.Glob "nginx/*").AsConfig . ) | indent 2 }}
50 changes: 48 additions & 2 deletions charts/studio/templates/deployment-studio-backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ spec:
metadata:
annotations:
checksum/configmap-studio-backend: {{ include (print $.Template.BasePath "/configmap-studio-backend.yaml") . | sha256sum }}
checksum/configmap-studio-nginx: {{ include (print $.Template.BasePath "/configmap-studio-nginx.yaml") . | sha256sum }}
{{- include "studio.checksum" . | indent 8 }}

{{- with .Values.studioBackend.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
Expand All @@ -46,7 +48,7 @@ spec:
args:
- |
./manage.py migrate
{{- if .Release.IsUpgrade }}
{{- if and .Release.IsUpgrade (not .Values.ci) }}
./manage.py migrate phonenumber --fake-initial
./manage.py migrate
{{- end }}
Expand All @@ -73,7 +75,7 @@ spec:
imagePullPolicy: {{ .Values.studioBackend.image.pullPolicy }}
args: [ "uwsgi", "--ini", "uwsgi.ini" ]
ports:
- name: http
- name: studio-http
containerPort: 8000
protocol: TCP
startupProbe:
Expand Down Expand Up @@ -101,8 +103,10 @@ spec:
failureThreshold: 5
timeoutSeconds: 60
volumeMounts:
{{ if not .Values.global.blobvault.bucket }}
- name: blobvault
mountPath: /blobvault
{{- end }}
- name: studio-ca-certificates
mountPath: /usr/local/share/ca-certificates
resources:
Expand All @@ -127,13 +131,55 @@ spec:
- secretRef:
name: {{ .Values.studioBackend.envFromSecret }}
{{- end }}
{{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }}
- name: nginx-sidecar
image: "{{ .Values.studioBlobvault.image.repository }}:{{ .Values.studioBlobvault.image.tag }}"
imagePullPolicy: "IfNotPresent"
ports:
- name: nginx-http
containerPort: 80
protocol: TCP
livenessProbe:
tcpSocket:
port: 8080
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 8080
periodSeconds: 10
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: nginx-sidecar
mountPath: /etc/nginx/conf.d/default.conf
subPath: backend-sidecar.conf
resources:
requests:
cpu: 10m
memory: 64Mi
limits:
cpu: 100m
memory: 256Mi
{{- end }}
volumes:
{{ if not .Values.global.blobvault.bucket }}
- name: blobvault
persistentVolumeClaim:
claimName: blobvault
{{- end }}
- name: studio-ca-certificates
configMap:
name: studio-ca-certificates
{{- if and .Values.global.basePath (not (eq .Values.global.basePath "/")) }}
- name: nginx-config
configMap:
name: {{ .Release.Name }}-nginx
- name: nginx-sidecar
configMap:
name: {{ .Release.Name }}-nginx
{{- end }}
{{- with .Values.studioBackend.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
Expand Down
Loading