From 1f3d01cb92f81987738e64e2c7aee86798f11f90 Mon Sep 17 00:00:00 2001 From: wbsong111 Date: Fri, 8 Aug 2025 15:33:04 +0900 Subject: [PATCH] Add ragflow chart --- charts/ragflow/.helmignore | 23 +++ charts/ragflow/Chart.yaml | 24 +++ charts/ragflow/templates/_helpers.tpl | 62 ++++++ .../templates/elasticsearch-config.yaml | 13 ++ charts/ragflow/templates/elasticsearch.yaml | 113 +++++++++++ charts/ragflow/templates/env.yaml | 56 ++++++ charts/ragflow/templates/infinity.yaml | 110 ++++++++++ charts/ragflow/templates/ingress.yaml | 43 ++++ charts/ragflow/templates/minio.yaml | 93 +++++++++ charts/ragflow/templates/mysql-config.yaml | 9 + charts/ragflow/templates/mysql.yaml | 98 +++++++++ charts/ragflow/templates/ragflow.yaml | 99 +++++++++ charts/ragflow/templates/ragflow_config.yaml | 188 ++++++++++++++++++ charts/ragflow/templates/redis.yaml | 112 +++++++++++ .../templates/tests/test-connection.yaml | 17 ++ charts/ragflow/values.yaml | 170 ++++++++++++++++ 16 files changed, 1230 insertions(+) create mode 100644 charts/ragflow/.helmignore create mode 100644 charts/ragflow/Chart.yaml create mode 100644 charts/ragflow/templates/_helpers.tpl create mode 100644 charts/ragflow/templates/elasticsearch-config.yaml create mode 100644 charts/ragflow/templates/elasticsearch.yaml create mode 100644 charts/ragflow/templates/env.yaml create mode 100644 charts/ragflow/templates/infinity.yaml create mode 100644 charts/ragflow/templates/ingress.yaml create mode 100644 charts/ragflow/templates/minio.yaml create mode 100644 charts/ragflow/templates/mysql-config.yaml create mode 100644 charts/ragflow/templates/mysql.yaml create mode 100644 charts/ragflow/templates/ragflow.yaml create mode 100644 charts/ragflow/templates/ragflow_config.yaml create mode 100644 charts/ragflow/templates/redis.yaml create mode 100644 charts/ragflow/templates/tests/test-connection.yaml create mode 100644 charts/ragflow/values.yaml diff --git a/charts/ragflow/.helmignore b/charts/ragflow/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/ragflow/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/ragflow/Chart.yaml b/charts/ragflow/Chart.yaml new file mode 100644 index 0000000..4dd5af1 --- /dev/null +++ b/charts/ragflow/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: ragflow +description: A Helm chart for deploying RAGFlow on Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "dev" diff --git a/charts/ragflow/templates/_helpers.tpl b/charts/ragflow/templates/_helpers.tpl new file mode 100644 index 0000000..8afe440 --- /dev/null +++ b/charts/ragflow/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ragflow.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ragflow.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ragflow.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ragflow.labels" -}} +helm.sh/chart: {{ include "ragflow.chart" . }} +{{ include "ragflow.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ragflow.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ragflow.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ragflow.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ragflow.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/ragflow/templates/elasticsearch-config.yaml b/charts/ragflow/templates/elasticsearch-config.yaml new file mode 100644 index 0000000..a43eabe --- /dev/null +++ b/charts/ragflow/templates/elasticsearch-config.yaml @@ -0,0 +1,13 @@ +{{- if eq .Values.env.DOC_ENGINE "elasticsearch" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "ragflow.fullname" . }}-es-config +data: + node.name: "es01" + bootstrap.memory_lock: "false" + discovery.type: "single-node" + xpack.security.enabled: "true" + xpack.security.http.ssl.enabled: "false" + xpack.security.transport.ssl.enabled: "false" +{{- end -}} diff --git a/charts/ragflow/templates/elasticsearch.yaml b/charts/ragflow/templates/elasticsearch.yaml new file mode 100644 index 0000000..9db9c9a --- /dev/null +++ b/charts/ragflow/templates/elasticsearch.yaml @@ -0,0 +1,113 @@ +{{- if eq .Values.env.DOC_ENGINE "elasticsearch" -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "ragflow.fullname" . }}-es-data + annotations: + "helm.sh/resource-policy": keep + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: elasticsearch +spec: + {{- with .Values.elasticsearch.storage.className }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.elasticsearch.storage.capacity }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ragflow.fullname" . }}-es + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: elasticsearch +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: elasticsearch + {{- with .Values.elasticsearch.deployment.strategy }} + strategy: + {{- . | toYaml | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: elasticsearch + annotations: + checksum/config-es: {{ include (print $.Template.BasePath "/elasticsearch-config.yaml") . | sha256sum }} + checksum/config-env: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} + spec: + initContainers: + - name: fix-data-volume-permissions + image: alpine + command: + - sh + - -c + - "chown -R 1000:0 /usr/share/elasticsearch/data" + volumeMounts: + - mountPath: /usr/share/elasticsearch/data + name: es-data + - name: sysctl + image: busybox + securityContext: + privileged: true + runAsUser: 0 + command: ["sysctl", "-w", "vm.max_map_count=262144"] + containers: + - name: elasticsearch + image: elasticsearch:{{ .Values.env.STACK_VERSION }} + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + - configMapRef: + name: {{ include "ragflow.fullname" . }}-es-config + ports: + - containerPort: 9200 + name: http + - containerPort: 9300 + name: transport + volumeMounts: + - mountPath: /usr/share/elasticsearch/data + name: es-data + {{- with .Values.elasticsearch.deployment.resources }} + resources: + {{- . | toYaml | nindent 10 }} + {{- end }} + securityContext: + capabilities: + add: + - "IPC_LOCK" + runAsUser: 1000 + # NOTE: fsGroup doesn't seem to + # work so use init container instead + # fsGroup: 1000 + allowPrivilegeEscalation: false + volumes: + - name: es-data + persistentVolumeClaim: + claimName: {{ include "ragflow.fullname" . }}-es-data +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-es + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: elasticsearch +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: elasticsearch + ports: + - protocol: TCP + port: 9200 + targetPort: http + type: {{ .Values.elasticsearch.service.type }} +{{- end -}} diff --git a/charts/ragflow/templates/env.yaml b/charts/ragflow/templates/env.yaml new file mode 100644 index 0000000..be0144f --- /dev/null +++ b/charts/ragflow/templates/env.yaml @@ -0,0 +1,56 @@ +{{- /* +TODO: Split env vars into separate secrets so that each pod + only gets passed the secrets it really needs. +*/}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "ragflow.fullname" . }}-env-config +type: Opaque +stringData: + {{- range $key, $val := .Values.env }} + {{- if $val }} + {{ $key }}: {{ quote $val }} + {{- end }} + {{- end }} + {{- /* + Use host names derived from internal cluster DNS + */}} + REDIS_HOST: {{ printf "%s-redis.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + MYSQL_HOST: {{ printf "%s-mysql.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + MINIO_HOST: {{ printf "%s-minio.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + {{- /* + Fail if passwords are not provided in release values + */}} + REDIS_PASSWORD: {{ .Values.env.REDIS_PASSWORD | required "REDIS_PASSWORD is required" }} + {{- /* + NOTE: MySQL uses MYSQL_ROOT_PASSWORD env var but Ragflow container expects + MYSQL_PASSWORD so we need to define both as the same value here. + */}} + {{- with .Values.env.MYSQL_PASSWORD | required "MYSQL_PASSWORD is required" }} + MYSQL_PASSWORD: {{ . }} + MYSQL_ROOT_PASSWORD: {{ . }} + {{- end }} + {{- with .Values.env.MINIO_PASSWORD | required "MINIO_PASSWORD is required" }} + MINIO_PASSWORD: {{ . }} + MINIO_ROOT_PASSWORD: {{ . }} + {{- end }} + {{- /* + Only provide env vars for enabled doc engine + */}} + {{- if eq .Values.env.DOC_ENGINE "elasticsearch" }} + ES_HOST: {{ printf "%s-es.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + ELASTIC_PASSWORD: {{ .Values.env.ELASTIC_PASSWORD | required "ELASTIC_PASSWORD is required" }} + {{- else if eq .Values.env.DOC_ENGINE "infinity" }} + INFINITY_HOST: {{ printf "%s-infinity.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + {{- else }} + {{ fail "env.DOC_ENGINE must be either 'elasticsearch' or 'infinity'" }} + {{- end }} + {{- if .Values.oidc.enable }} + DISPLAY_NAME: {{ .Values.oidc.display_name }} + CLIENT_ID: {{ .Values.oidc.client_id }} + CLIENT_SECRETS: {{ .Values.oidc.client_secret }} + ISSUER: {{ .Values.oidc.issuer }} + SCOPE: {{ .Values.oidc.scope }} + REDIRECT_URI: {{ .Values.oidc.redirect_uri }} + {{- end }} diff --git a/charts/ragflow/templates/infinity.yaml b/charts/ragflow/templates/infinity.yaml new file mode 100644 index 0000000..6ccdff0 --- /dev/null +++ b/charts/ragflow/templates/infinity.yaml @@ -0,0 +1,110 @@ +{{- if eq .Values.env.DOC_ENGINE "infinity" -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "ragflow.fullname" . }}-infinity + annotations: + "helm.sh/resource-policy": keep + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: infinity +spec: + {{- with .Values.infinity.storage.className }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.infinity.storage.capacity }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ragflow.fullname" . }}-infinity + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: infinity +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: infinity + {{- with .Values.infinity.deployment.strategy }} + strategy: + {{- . | toYaml | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: infinity + annotations: + checksum/config: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} + spec: + containers: + - name: infinity + image: {{ .Values.infinity.image.repository }}:{{ .Values.infinity.image.tag }} + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + ports: + - containerPort: 23817 + name: thrift + - containerPort: 23820 + name: http + - containerPort: 5432 + name: psql + volumeMounts: + - mountPath: /var/infinity + name: infinity-data + {{- with .Values.infinity.deployment.resources }} + resources: + {{- . | toYaml | nindent 10 }} + {{- end }} + securityContext: + capabilities: + add: + - "NET_BIND_SERVICE" + seccompProfile: + type: RuntimeDefault + livenessProbe: + httpGet: + path: /admin/node/current + port: 23820 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 10 + failureThreshold: 120 + volumes: + - name: infinity-data + persistentVolumeClaim: + claimName: {{ include "ragflow.fullname" . }}-infinity +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-infinity + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: infinity +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: infinity + ports: + - protocol: TCP + port: 23817 + targetPort: thrift + name: thrift + - protocol: TCP + port: 23820 + targetPort: http + name: http + - protocol: TCP + port: 5432 + targetPort: psql + name: psql + type: {{ .Values.infinity.service.type }} +{{- end -}} diff --git a/charts/ragflow/templates/ingress.yaml b/charts/ragflow/templates/ingress.yaml new file mode 100644 index 0000000..6547b52 --- /dev/null +++ b/charts/ragflow/templates/ingress.yaml @@ -0,0 +1,43 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "ragflow.fullname" . }} + labels: + {{- include "ragflow.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- with .pathType }} + pathType: {{ . }} + {{- end }} + backend: + service: + name: {{ $.Release.Name }} + port: + name: http + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/ragflow/templates/minio.yaml b/charts/ragflow/templates/minio.yaml new file mode 100644 index 0000000..7a5cb1a --- /dev/null +++ b/charts/ragflow/templates/minio.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "ragflow.fullname" . }}-minio + annotations: + "helm.sh/resource-policy": keep + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: minio +spec: + {{- with .Values.minio.storage.className }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.minio.storage.capacity }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ragflow-minio-deployment + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: minio + annotations: + checksum/config: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: minio + {{- with .Values.minio.deployment.strategy }} + strategy: + {{- . | toYaml | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: minio + spec: + containers: + - name: minio + image: {{ .Values.minio.image.repository }}:{{ .Values.minio.image.tag }} + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + args: + - server + - "--console-address=:9001" + - "/data" + ports: + - containerPort: 9000 + name: s3 + - containerPort: 9001 + name: console + {{- with .Values.minio.deployment.resources }} + resources: + {{- . | toYaml | nindent 10 }} + {{- end }} + volumeMounts: + - mountPath: /data + name: minio-data + volumes: + - name: minio-data + persistentVolumeClaim: + claimName: {{ include "ragflow.fullname" . }}-minio +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-minio + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: minio +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: minio + ports: + - name: s3 + protocol: TCP + port: 9000 + targetPort: s3 + - name: console + protocol: TCP + port: 9001 + targetPort: console + type: {{ .Values.minio.service.type }} diff --git a/charts/ragflow/templates/mysql-config.yaml b/charts/ragflow/templates/mysql-config.yaml new file mode 100644 index 0000000..dd85010 --- /dev/null +++ b/charts/ragflow/templates/mysql-config.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: mysql-init-script +data: + init.sql: |- + CREATE DATABASE IF NOT EXISTS rag_flow; + USE rag_flow; diff --git a/charts/ragflow/templates/mysql.yaml b/charts/ragflow/templates/mysql.yaml new file mode 100644 index 0000000..2ec6dcd --- /dev/null +++ b/charts/ragflow/templates/mysql.yaml @@ -0,0 +1,98 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "ragflow.fullname" . }}-mysql + annotations: + "helm.sh/resource-policy": keep + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: mysql +spec: + {{- with .Values.mysql.storage.className }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.mysql.storage.capacity }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ragflow.fullname" . }}-mysql + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: mysql +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: mysql + {{- with .Values.mysql.deployment.strategy }} + strategy: + {{- . | toYaml | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: mysql + annotations: + checksum/config-mysql: {{ include (print $.Template.BasePath "/mysql-config.yaml") . | sha256sum }} + checksum/config-env: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} + spec: + containers: + - name: mysql + image: {{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }} + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + args: + - --max_connections=1000 + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_general_ci + - --default-authentication-plugin=mysql_native_password + - --tls_version=TLSv1.2,TLSv1.3 + - --init-file=/data/application/init.sql + - --disable-log-bin + ports: + - containerPort: 3306 + name: mysql + {{- with .Values.mysql.deployment.resources }} + resources: + {{- . | toYaml | nindent 10 }} + {{- end }} + volumeMounts: + - mountPath: /var/lib/mysql + name: mysql-data + - mountPath: /data/application/init.sql + subPath: init.sql + readOnly: true + name: init-script-volume + volumes: + - name: mysql-data + persistentVolumeClaim: + claimName: {{ include "ragflow.fullname" . }}-mysql + - name: init-script-volume + configMap: + name: mysql-init-script +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-mysql + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: mysql +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: mysql + ports: + - protocol: TCP + port: 3306 + targetPort: mysql + type: {{ .Values.mysql.service.type }} diff --git a/charts/ragflow/templates/ragflow.yaml b/charts/ragflow/templates/ragflow.yaml new file mode 100644 index 0000000..5818d61 --- /dev/null +++ b/charts/ragflow/templates/ragflow.yaml @@ -0,0 +1,99 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ragflow.fullname" . }} + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: ragflow +spec: + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: ragflow + {{- with .Values.ragflow.deployment.strategy }} + strategy: + {{- . | toYaml | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: ragflow + annotations: + checksum/config-env: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} + checksum/config-ragflow: {{ include (print $.Template.BasePath "/ragflow_config.yaml") . | sha256sum }} + spec: + containers: + - name: ragflow + image: {{ .Values.env.RAGFLOW_IMAGE }} + ports: + - containerPort: 80 + name: http + - containerPort: 9380 + name: http-api + volumeMounts: + - mountPath: /etc/nginx/conf.d/ragflow.conf + subPath: ragflow.conf + name: nginx-config-volume + - mountPath: /etc/nginx/proxy.conf + subPath: proxy.conf + name: nginx-config-volume + - mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + name: nginx-config-volume + {{- if .Values.oidc.enable }} + - mountPath: /ragflow/conf/service_conf.yaml.template + subPath: service_conf.yaml.template + name: nginx-config-volume + {{- end }} + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + {{- with .Values.ragflow.deployment.resources }} + resources: + {{- . | toYaml | nindent 10 }} + {{- end }} + volumes: + - name: nginx-config-volume + configMap: + name: nginx-config +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }} + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: ragflow +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: ragflow + ports: + - protocol: TCP + port: 80 + targetPort: http + name: http + type: {{ .Values.ragflow.service.type }} +--- +{{- if .Values.ragflow.api.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-api + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: ragflow +spec: + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: ragflow + ports: + - protocol: TCP + port: 80 + targetPort: http-api + name: http-api + type: {{ .Values.ragflow.api.service.type }} +{{- end }} diff --git a/charts/ragflow/templates/ragflow_config.yaml b/charts/ragflow/templates/ragflow_config.yaml new file mode 100644 index 0000000..ace32c9 --- /dev/null +++ b/charts/ragflow/templates/ragflow_config.yaml @@ -0,0 +1,188 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config +data: + ragflow.conf: | + server { + listen 80; + server_name _; + root /ragflow/web/dist; + + gzip on; + gzip_min_length 1k; + gzip_comp_level 9; + gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; + gzip_vary on; + gzip_disable "MSIE [1-6]\."; + + location ~ ^/(v1|api) { + proxy_pass http://localhost:9380; + include proxy.conf; + } + + location / { + index index.html; + try_files $uri $uri/ /index.html; + } + + # Cache-Control: max-age~@~AExpires + location ~ ^/static/(css|js|media)/ { + expires 10y; + access_log off; + } + } + proxy.conf: | + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_buffering off; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + nginx.conf: | + user root; + 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 /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + client_max_body_size 128M; + + include /etc/nginx/conf.d/ragflow.conf; + } + {{- if .Values.oidc.enable }} + service_conf.yaml.template: | + ragflow: + host: ${RAGFLOW_HOST:-0.0.0.0} + http_port: 9380 + mysql: + name: '${MYSQL_DBNAME:-rag_flow}' + user: '${MYSQL_USER:-root}' + password: '${MYSQL_PASSWORD:-infini_rag_flow}' + host: '${MYSQL_HOST:-mysql}' + port: 3306 + max_connections: 900 + stale_timeout: 300 + minio: + user: '${MINIO_USER:-rag_flow}' + password: '${MINIO_PASSWORD:-infini_rag_flow}' + host: '${MINIO_HOST:-minio}:9000' + es: + hosts: 'http://${ES_HOST:-es01}:9200' + username: '${ES_USER:-elastic}' + password: '${ELASTIC_PASSWORD:-infini_rag_flow}' + os: + hosts: 'http://${OS_HOST:-opensearch01}:9201' + username: '${OS_USER:-admin}' + password: '${OPENSEARCH_PASSWORD:-infini_rag_flow_OS_01}' + infinity: + uri: '${INFINITY_HOST:-infinity}:23817' + db_name: 'default_db' + redis: + db: 1 + password: '${REDIS_PASSWORD:-infini_rag_flow}' + host: '${REDIS_HOST:-redis}:6379' + + # postgres: + # name: '${POSTGRES_DBNAME:-rag_flow}' + # user: '${POSTGRES_USER:-rag_flow}' + # password: '${POSTGRES_PASSWORD:-infini_rag_flow}' + # host: '${POSTGRES_HOST:-postgres}' + # port: 5432 + # max_connections: 100 + # stale_timeout: 30 + # s3: + # access_key: 'access_key' + # secret_key: 'secret_key' + # region: 'region' + # endpoint_url: 'endpoint_url' + # bucket: 'bucket' + # prefix_path: 'prefix_path' + # signature_version: 'v4' + # addressing_style: 'path' + # oss: + # access_key: '${ACCESS_KEY}' + # secret_key: '${SECRET_KEY}' + # endpoint_url: '${ENDPOINT}' + # region: '${REGION}' + # bucket: '${BUCKET}' + # prefix_path: '${OSS_PREFIX_PATH}' + # azure: + # auth_type: 'sas' + # container_url: 'container_url' + # sas_token: 'sas_token' + # azure: + # auth_type: 'spn' + # account_url: 'account_url' + # client_id: 'client_id' + # secret: 'secret' + # tenant_id: 'tenant_id' + # container_name: 'container_name' + # user_default_llm: + # factory: 'Tongyi-Qianwen' + # api_key: 'sk-xxxxxxxxxxxxx' + # base_url: '' + # default_models: + # chat_model: 'qwen-plus' + # embedding_model: 'BAAI/bge-large-zh-v1.5@BAAI' + # rerank_model: '' + # asr_model: '' + # image2text_model: '' + oauth: + # oauth2: + # display_name: "OAuth2" + # client_id: "your_client_id" + # client_secret: "your_client_secret" + # authorization_url: "https://your-oauth-provider.com/oauth/authorize" + # token_url: "https://your-oauth-provider.com/oauth/token" + # userinfo_url: "https://your-oauth-provider.com/oauth/userinfo" + # redirect_uri: "https://your-app.com/v1/user/oauth/callback/oauth2" + oidc: + display_name: '${DISPLAY_NAME}' + client_id: '${CLIENT_ID}' + client_secret: '${CLIENT_SECRETS}' + issuer: '${ISSUER}' + scope: '${SCOPE:openid}' + redirect_uri: '${REDIRECT_URI}' + # github: + # type: "github" + # icon: "github" + # display_name: "Github" + # client_id: "your_client_id" + # client_secret: "your_client_secret" + # redirect_uri: "https://your-app.com/v1/user/oauth/callback/github" + # authentication: + # client: + # switch: false + # http_app_key: + # http_secret_key: + # site: + # switch: false + # permission: + # switch: false + # component: false + # dataset: false + {{- end }} diff --git a/charts/ragflow/templates/redis.yaml b/charts/ragflow/templates/redis.yaml new file mode 100644 index 0000000..53e7a67 --- /dev/null +++ b/charts/ragflow/templates/redis.yaml @@ -0,0 +1,112 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-redis + annotations: + "helm.sh/resource-policy": keep + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + ports: + - port: 6379 + name: redis + protocol: TCP + clusterIP: None # Headless service for StatefulSet + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: redis +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "ragflow.fullname" . }}-redis + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + serviceName: {{ include "ragflow.fullname" . }}-redis + replicas: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: redis + template: + metadata: + labels: + {{- include "ragflow.labels" . | nindent 8 }} + app.kubernetes.io/component: redis + annotations: + checksum/config-env: {{ include (print $.Template.BasePath "/env.yaml") . | sha256sum }} + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: redis + image: {{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }} + command: + - "sh" + - "-c" + - "exec redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 128mb --maxmemory-policy allkeys-lru" + envFrom: + - secretRef: + name: {{ include "ragflow.fullname" . }}-env-config + ports: + - containerPort: 6379 + name: redis + {{- if .Values.redis.persistence.enabled }} + volumeMounts: + - name: redis-data + mountPath: /data + {{- end }} + {{- with .Values.redis.deployment.resources }} + resources: + {{- . | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.redis.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: redis-data + labels: + {{- include "ragflow.labels" . | nindent 10 }} + app.kubernetes.io/component: redis + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.redis.storage.className }} + storageClassName: {{ . }} + {{- end }} + resources: + requests: + storage: {{ .Values.redis.storage.capacity }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ragflow.fullname" . }}-redis-svc + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + ports: + - port: 6379 + targetPort: redis + protocol: TCP + selector: + {{- include "ragflow.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: redis +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "ragflow.fullname" . }}-redis-pdb + labels: + {{- include "ragflow.labels" . | nindent 4 }} + app.kubernetes.io/component: redis +spec: + minAvailable: 1 + selector: + matchLabels: + {{- include "ragflow.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: redis \ No newline at end of file diff --git a/charts/ragflow/templates/tests/test-connection.yaml b/charts/ragflow/templates/tests/test-connection.yaml new file mode 100644 index 0000000..f3d3a48 --- /dev/null +++ b/charts/ragflow/templates/tests/test-connection.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "ragflow.fullname" . }}-test-connection" + labels: + {{- include "ragflow.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: + - 'wget' + args: + - {{ printf "%s.%s.svc" (include "ragflow.fullname" .) .Release.Namespace }} + restartPolicy: Never diff --git a/charts/ragflow/values.yaml b/charts/ragflow/values.yaml new file mode 100644 index 0000000..f6f223c --- /dev/null +++ b/charts/ragflow/values.yaml @@ -0,0 +1,170 @@ +# Based on docker compose .env file +env: + # The type of doc engine to use. + # Available options: + # - `elasticsearch` (default) + # - `infinity` (https://github.com/infiniflow/infinity) + # DOC_ENGINE: elasticsearch + DOC_ENGINE: infinity + + # The version of Elasticsearch. + STACK_VERSION: "8.11.3" + + # The password for Elasticsearch + ELASTIC_PASSWORD: infini_rag_flow_helm + + # The password for MySQL + MYSQL_PASSWORD: infini_rag_flow_helm + # The database of the MySQL service to use + MYSQL_DBNAME: rag_flow + + # The username for MinIO. + MINIO_ROOT_USER: rag_flow + # The password for MinIO + MINIO_PASSWORD: infini_rag_flow_helm + + # The password for Redis + REDIS_PASSWORD: infini_rag_flow_helm + + # The RAGFlow Docker image to download. + # Defaults to the v0.19.0-slim edition, which is the RAGFlow Docker image without embedding models. + RAGFLOW_IMAGE: infiniflow/ragflow:v0.19.0-slim + # + # To download the RAGFlow Docker image with embedding models, uncomment the following line instead: + # RAGFLOW_IMAGE: infiniflow/ragflow:v0.19.0 + # + # The Docker image of the v0.19.0 edition includes: + # - Built-in embedding models: + # - BAAI/bge-large-zh-v1.5 + # - BAAI/bge-reranker-v2-m3 + # - maidalun1020/bce-embedding-base_v1 + # - maidalun1020/bce-reranker-base_v1 + # - Embedding models that will be downloaded once you select them in the RAGFlow UI: + # - BAAI/bge-base-en-v1.5 + # - BAAI/bge-large-en-v1.5 + # - BAAI/bge-small-en-v1.5 + # - BAAI/bge-small-zh-v1.5 + # - jinaai/jina-embeddings-v2-base-en + # - jinaai/jina-embeddings-v2-small-en + # - nomic-ai/nomic-embed-text-v1.5 + # - sentence-transformers/all-MiniLM-L6-v2 + # + # + + # The local time zone. + TIMEZONE: "Asia/Shanghai" + + # Uncomment the following line if you have limited access to huggingface.co: + # HF_ENDPOINT: https://hf-mirror.com + + # The maximum file size for each uploaded file, in bytes. + # You can uncomment this line and update the value if you wish to change 128M file size limit + # MAX_CONTENT_LENGTH: "134217728" + # After making the change, ensure you update `client_max_body_size` in nginx/nginx.conf correspondingly. + +ragflow: + deployment: + strategy: + resources: + service: + # Use LoadBalancer to expose the web interface externally + type: ClusterIP + api: + service: + enabled: true + type: ClusterIP + +infinity: + image: + repository: infiniflow/infinity + tag: v0.6.0-dev3 + storage: + className: + capacity: 5Gi + deployment: + strategy: + resources: + service: + type: ClusterIP + +elasticsearch: + storage: + className: + capacity: 20Gi + deployment: + strategy: + resources: + requests: + cpu: "4" + memory: "16Gi" + service: + type: ClusterIP + +minio: + image: + repository: quay.io/minio/minio + tag: RELEASE.2023-12-20T01-00-02Z + storage: + className: + capacity: 5Gi + deployment: + strategy: + resources: + service: + type: ClusterIP + +mysql: + image: + repository: mysql + tag: 8.0.39 + storage: + className: + capacity: 5Gi + deployment: + strategy: + resources: + service: + type: ClusterIP + +redis: + image: + repository: valkey/valkey + tag: 8 + storage: + className: + capacity: 5Gi + persistence: + enabled: true + deployment: + strategy: + resources: + service: + type: ClusterIP + + +# This block is for setting up web service ingress. For more information, see: +# https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local +oidc: + enable: false + display_name: "OAuth2" + client_id: "your_client_id" + client_secret: "your_client_secret" + authorization_url: "https://your-oauth-provider.com/oauth/authorize" + token_url: "https://your-oauth-provider.com/oauth/token" + userinfo_url: "https://your-oauth-provider.com/oauth/userinfo" + redirect_uri: "https://your-app.com/v1/user/oauth/callback/oauth2"