This commit is contained in:
Sense T
2026-05-26 09:14:29 +00:00
parent 7e49df1726
commit 9dc0113b56
18 changed files with 1568 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
Qdrant {{ .Chart.AppVersion }} has been deployed successfully.
The full Qdrant documentation is available at https://qdrant.tech/documentation/.
To forward Qdrant's ports execute one of the following commands:
export POD_NAME=$(kubectl get pods --namespace {{ $.Release.Namespace }} -l "app.kubernetes.io/name={{ include "qdrant.name" . }},app.kubernetes.io/instance={{ $.Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
{{- if contains "ClusterIP" .Values.service.type }}
{{- range .Values.service.ports }}
If you want to use Qdrant via {{ .name }} execute the following commands
kubectl --namespace {{ $.Release.Namespace }} port-forward $POD_NAME {{ .targetPort }}:{{ .targetPort }}
{{- end }}
{{- end }}
{{- if .Values.ingress.enabled }}
If you want to access Qdrant through the ingress controller
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- end }}
+145
View File
@@ -0,0 +1,145 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "qdrant.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 "qdrant.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 "qdrant.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "qdrant.labels" -}}
helm.sh/chart: {{ include "qdrant.chart" . }}
{{ include "qdrant.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "qdrant.selectorLabels" -}}
app: {{ include "qdrant.name" . }}
app.kubernetes.io/name: {{ include "qdrant.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Additional (global) labels
*/}}
{{- define "qdrant.additionalLabels" -}}
{{- with .Values.additionalLabels }}
{{- range $key, $value := . }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "qdrant.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "qdrant.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create secret
*/}}
{{- define "qdrant.secret" -}}
{{- $readOnlyApiKey := false }}
{{- $apiKey := false }}
{{- if kindIs "map" .Values.apiKey -}}
{{- if .Values.apiKey.valueFrom -}}
{{- /* Retrieve the value from the secret as specified in valueFrom */ -}}
{{- $secretName := .Values.apiKey.valueFrom.secretKeyRef.name -}}
{{- $secretKey := .Values.apiKey.valueFrom.secretKeyRef.key -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $apiKey = (get $secretData $secretKey | b64dec) -}}
{{- end -}}
{{- else if .Values.apiKey | toJson | eq "true" -}}
{{- /* Retrieve existing randomly generated api key or create a new one */ -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace (printf "%s-apikey" (include "qdrant.fullname" . ))) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $apiKey = (get $secretData "api-key" | b64dec) | default (randAlphaNum 32) -}}
{{- else if .Values.apiKey -}}
{{- $apiKey = .Values.apiKey -}}
{{- end -}}
{{- if kindIs "map" .Values.readOnlyApiKey -}}
{{- if .Values.readOnlyApiKey.valueFrom -}}
{{- /* Retrieve the value from the secret as specified in valueFrom */ -}}
{{- $secretName := .Values.readOnlyApiKey.valueFrom.secretKeyRef.name -}}
{{- $secretKey := .Values.readOnlyApiKey.valueFrom.secretKeyRef.key -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $readOnlyApiKey = (get $secretData $secretKey | b64dec) -}}
{{- end -}}
{{- else if eq (.Values.readOnlyApiKey | toJson) "true" -}}
{{- /* retrieve existing randomly generated api key or create new one */ -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace (printf "%s-apikey" (include "qdrant.fullname" . ))) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $readOnlyApiKey = (get $secretData "read-only-api-key" | b64dec) | default (randAlphaNum 32) -}}
{{- else if .Values.readOnlyApiKey -}}
{{- $readOnlyApiKey = .Values.readOnlyApiKey -}}
{{- end -}}
{{- if and $apiKey $readOnlyApiKey -}}
api-key: {{ $apiKey | b64enc }}
read-only-api-key: {{ $readOnlyApiKey | b64enc }}
local.yaml: {{ printf "service:\n api_key: %s\n read_only_api_key: %s" $apiKey $readOnlyApiKey | b64enc }}
{{- else if $apiKey -}}
api-key: {{ $apiKey | b64enc }}
local.yaml: {{ printf "service:\n api_key: %s" $apiKey | b64enc }}
{{- else if $readOnlyApiKey -}}
read-only-api-key: {{ $readOnlyApiKey | b64enc }}
local.yaml: {{ printf "service:\n read_only_api_key: %s" $readOnlyApiKey | b64enc }}
{{- end -}}
{{- end -}}
{{/*
Protocol to use for inter cluster communication
*/}}
{{- define "qdrant.p2p.protocol" -}}
{{ if eq (.Values.config.cluster.p2p.enable_tls | toJson) "true" -}}
https
{{- else -}}
http
{{- end -}}
{{- end -}}
{{/*
Port to use for inter cluster communication
*/}}
{{- define "qdrant.p2p.port" -}}
{{- default 6335 .Values.config.cluster.p2p.port -}}
{{- end -}}
+33
View File
@@ -0,0 +1,33 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
initialize.sh: |
#!/bin/sh
echo "Soft limits"
ulimit -a -S
echo "Hard limits"
ulimit -a -H
ulimit -n $(ulimit -Hn)
SET_INDEX=${HOSTNAME##*-}
{{- if and (.Values.snapshotRestoration.enabled) (eq (.Values.replicaCount | quote) (1 | quote)) }}
echo "Starting initializing for pod $SET_INDEX and snapshots restoration"
exec ./entrypoint.sh --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}' {{ range .Values.snapshotRestoration.snapshots }} --snapshot {{ . }} {{ end }}
{{- else }}
echo "Starting initializing for pod $SET_INDEX"
if [ "$SET_INDEX" = "0" ]; then
exec ./entrypoint.sh --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}'
else
exec ./entrypoint.sh --bootstrap '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}' --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-'"$SET_INDEX"'.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}'
fi
{{ end }}
production.yaml: |
{{- tpl (toYaml .Values.config) . | nindent 4 }}
+53
View File
@@ -0,0 +1,53 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.ingress.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.ingress.annotations .Values.additionalAnnotations }}
annotations:
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.ingress.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
spec:
{{- if .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- end }}
{{- with .Values.ingress.hosts }}
rules:
{{- range . }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path | quote }}
pathType: {{ .pathType | default "Prefix" | quote }}
backend:
service:
name: {{ default .serviceName (include "qdrant.fullname" $) }}
port:
number: {{ .servicePort }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls}}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName | quote }}
{{- end }}
{{- end }}
{{- end }}
+26
View File
@@ -0,0 +1,26 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable}}
maxUnavailable: {{ . }}
{{- end }}
{{- with .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ . }}
{{- end }}
{{- with .Values.podDisruptionBudget.unhealthyPodEvictionPolicy }}
unhealthyPodEvictionPolicy: {{ . }}
{{- end }}
selector:
matchLabels:
{{- include "qdrant.selectorLabels" . | nindent 6 }}
{{- end }}
+15
View File
@@ -0,0 +1,15 @@
{{- if or .Values.apiKey .Values.readOnlyApiKey }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "qdrant.fullname" . }}-apikey
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
{{ include "qdrant.secret" . | indent 2}}
{{- end }}
+35
View File
@@ -0,0 +1,35 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "qdrant.fullname" . }}-headless
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
app.kubernetes.io/component: cluster-discovery
{{- with .Values.service.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.service.annotations .Values.additionalAnnotations }}
annotations:
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.service.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
spec:
clusterIP: None
publishNotReadyAddresses: true
ports:
{{- range .Values.service.ports }}
- name: {{ .name }}
port: {{ .port }}
targetPort: {{ .targetPort }}
protocol: {{ .protocol | default "TCP" }}
{{- if .appProtocol }}
appProtocol: {{ .appProtocol }}
{{- end }}
{{- end }}
selector:
{{- include "qdrant.selectorLabels" . | nindent 4 }}
+39
View File
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.service.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.service.annotations .Values.additionalAnnotations }}
annotations:
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.service.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
spec:
type: {{ .Values.service.type | default "ClusterIP" }}
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
ports:
{{- range .Values.service.ports }}
- name: {{ .name }}
port: {{ .port }}
targetPort: {{ .targetPort }}
{{- if and (or (eq $.Values.service.type "NodePort") (eq $.Values.service.type "LoadBalancer")) (not (empty .nodePort)) }}
nodePort: {{ .nodePort }}
{{- end }}
protocol: {{ .protocol | default "TCP" }}
{{- if .appProtocol }}
appProtocol: {{ .appProtocol }}
{{- end }}
{{- end }}
selector:
{{- include "qdrant.selectorLabels" . | nindent 4 }}
+16
View File
@@ -0,0 +1,16 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "qdrant.fullname" . }}
{{- if or .Values.serviceAccount.annotations .Values.additionalAnnotations }}
annotations:
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.serviceAccount.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
+52
View File
@@ -0,0 +1,52 @@
{{- if .Values.metrics.serviceMonitor.enabled }}
kind: ServiceMonitor
apiVersion: monitoring.coreos.com/v1
metadata:
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.metrics.serviceMonitor.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
name: {{ include "qdrant.fullname" . }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:
- honorLabels: true
interval: {{ .Values.metrics.serviceMonitor.scrapeInterval }}
path: {{ .Values.metrics.serviceMonitor.targetPath }}
port: {{ .Values.metrics.serviceMonitor.targetPort }}
scheme: http
scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }}
{{- if .Values.metrics.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{ tpl (toYaml .Values.metrics.serviceMonitor.metricRelabelings | indent 8) . }}
{{- end }}
{{- if .Values.metrics.serviceMonitor.relabelings }}
relabelings:
{{ tpl (toYaml .Values.metrics.serviceMonitor.relabelings | indent 8) . }}
{{- end }}
{{- if .Values.metrics.serviceMonitor.authorization }}
authorization:
{{ tpl (toYaml .Values.metrics.serviceMonitor.authorization | indent 8) . }}
{{- else if .Values.readOnlyApiKey }}
authorization:
type: Bearer
credentials:
name: {{ include "qdrant.fullname" . }}-apikey
key: read-only-api-key
{{- else if .Values.apiKey }}
authorization:
type: Bearer
credentials:
name: {{ include "qdrant.fullname" . }}-apikey
key: api-key
{{- end }}
selector:
matchLabels:
{{- include "qdrant.labels" . | nindent 6 }}
app.kubernetes.io/component: cluster-discovery
{{- end }}
+315
View File
@@ -0,0 +1,315 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
podManagementPolicy: {{ .Values.podManagementPolicy }}
{{- if .Values.minReadySeconds }}
minReadySeconds: {{ .Values.minReadySeconds }}
{{- end }}
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0
selector:
matchLabels:
{{- include "qdrant.selectorLabels" . | nindent 6 }}
serviceName: {{ include "qdrant.fullname" . }}-headless
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- if or .Values.apiKey .Values.readOnlyApiKey }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "qdrant.selectorLabels" . | nindent 8 }}
{{- include "qdrant.additionalLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.priorityClassName }}
priorityClassName: "{{ .Values.priorityClassName }}"
{{- end }}
{{- if .Values.shareProcessNamespace }}
shareProcessNamespace: {{ .Values.shareProcessNamespace }}
{{- end }}
{{- if hasKey .Values "terminationGracePeriodSeconds" }}
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
{{- end }}
initContainers:
{{- if and .Values.updateVolumeFsOwnership (not .Values.image.useUnprivilegedImage) }}
{{- if and .Values.containerSecurityContext .Values.containerSecurityContext.runAsUser }}
- name: ensure-dir-ownership
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
command:
- chown
- -R
- {{ int64 .Values.containerSecurityContext.runAsUser }}:{{ int64 .Values.podSecurityContext.fsGroup }}
- /qdrant/storage
- /qdrant/snapshots
{{- if and .Values.snapshotRestoration.enabled .Values.snapshotRestoration.pvcName }}
- {{ .Values.snapshotRestoration.mountPath }}
{{- end }}
volumeMounts:
- name: {{ .Values.persistence.storageVolumeName | default "qdrant-storage" }}
mountPath: /qdrant/storage
{{- if .Values.persistence.storageSubPath }}
subPath: "{{ .Values.persistence.storageSubPath }}"
{{- end }}
- name: {{ .Values.snapshotPersistence.snapshotsVolumeName | default "qdrant-snapshots" }}
mountPath: /qdrant/snapshots
{{- if .Values.snapshotPersistence.snapshotsSubPath }}
subPath: "{{ .Values.snapshotPersistence.snapshotsSubPath }}"
{{- end }}
{{- if and .Values.snapshotRestoration.enabled .Values.snapshotRestoration.pvcName }}
- name: qdrant-snapshot-restoration
mountPath: {{ .Values.snapshotRestoration.mountPath }}
{{- end }}
{{- end }}
{{- end }}
containers:
{{- if .Values.sidecarContainers -}}
{{- toYaml .Values.sidecarContainers | trim | nindent 8 }}
{{- end}}
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}{{ .Values.image.useUnprivilegedImage | ternary "-unprivileged" "" }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: QDRANT_INIT_FILE_PATH
value: /qdrant/init/.qdrant-initialized
{{- range .Values.env }}
- name: {{ .name }}
{{- if .valueFrom }}
valueFrom: {{- toYaml .valueFrom | nindent 16 }}
{{- else }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
command: ["/bin/bash", "-c"]
{{- with .Values.args }}
args:
{{- toYaml . | nindent 10 }}
{{- end }}
ports:
{{- range .Values.service.ports }}
- name: {{ .name }}
containerPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- $values := .Values -}}
{{- range .Values.service.ports }}
{{- if and $values.livenessProbe.enabled .checksEnabled }}
livenessProbe:
{{- if eq .name "grpc"}}
grpc:
port: {{ .targetPort }}
{{- end }}
{{- if eq .name "http"}}
httpGet:
path: /
port: {{ .targetPort }}
{{- if and $values.config.service $values.config.service.enable_tls }}
scheme: HTTPS
{{- end }}
{{- end }}
initialDelaySeconds: {{ $values.livenessProbe.initialDelaySeconds }}
timeoutSeconds: {{ $values.livenessProbe.timeoutSeconds }}
periodSeconds: {{ $values.livenessProbe.periodSeconds }}
successThreshold: {{ $values.livenessProbe.successThreshold }}
failureThreshold: {{ $values.livenessProbe.failureThreshold }}
{{- end }}
{{- if and $values.readinessProbe.enabled .checksEnabled }}
readinessProbe:
{{- if eq .name "grpc"}}
grpc:
port: {{ .targetPort }}
{{- end }}
{{- if eq .name "http"}}
httpGet:
path: "{{- if semverCompare ">=1.7.3" ($.Values.image.tag | default $.Chart.AppVersion) -}}/readyz{{else}}/{{end}}"
port: {{ .targetPort }}
{{- if and $values.config.service $values.config.service.enable_tls }}
scheme: HTTPS
{{- end }}
{{- end }}
initialDelaySeconds: {{ $values.readinessProbe.initialDelaySeconds }}
timeoutSeconds: {{ $values.readinessProbe.timeoutSeconds }}
periodSeconds: {{ $values.readinessProbe.periodSeconds }}
successThreshold: {{ $values.readinessProbe.successThreshold }}
failureThreshold: {{ $values.readinessProbe.failureThreshold }}
{{- end }}
{{- if and $values.startupProbe.enabled .checksEnabled }}
startupProbe:
{{- if eq .name "grpc"}}
grpc:
port: {{ .targetPort }}
{{- end }}
{{- if eq .name "http"}}
httpGet:
path: /
port: {{ .targetPort }}
{{- if and $values.config.service $values.config.service.enable_tls }}
scheme: HTTPS
{{- end }}
{{- end }}
initialDelaySeconds: {{ $values.startupProbe.initialDelaySeconds }}
timeoutSeconds: {{ $values.startupProbe.timeoutSeconds }}
periodSeconds: {{ $values.startupProbe.periodSeconds }}
successThreshold: {{ $values.startupProbe.successThreshold }}
failureThreshold: {{ $values.startupProbe.failureThreshold }}
{{- end }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.containerSecurityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.lifecycle }}
lifecycle:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: {{ .Values.persistence.storageVolumeName | default "qdrant-storage" }}
mountPath: /qdrant/storage
{{- if .Values.persistence.storageSubPath }}
subPath: "{{ .Values.persistence.storageSubPath }}"
{{- end }}
- name: qdrant-config
mountPath: /qdrant/config/initialize.sh
subPath: initialize.sh
- name: qdrant-config
mountPath: /qdrant/config/production.yaml
subPath: production.yaml
{{- if or .Values.apiKey .Values.readOnlyApiKey }}
- name: qdrant-secret
mountPath: /qdrant/config/local.yaml
subPath: local.yaml
{{- end }}
{{- if and .Values.snapshotRestoration.enabled .Values.snapshotRestoration.pvcName }}
- name: qdrant-snapshot-restoration
mountPath: {{ .Values.snapshotRestoration.mountPath }}
{{- end }}
- name: {{ .Values.snapshotPersistence.snapshotsVolumeName | default "qdrant-snapshots" }}
mountPath: /qdrant/snapshots
{{- if .Values.snapshotPersistence.snapshotsSubPath }}
subPath: "{{ .Values.snapshotPersistence.snapshotsSubPath }}"
{{- end }}
- name: qdrant-init
mountPath: /qdrant/init
{{- if .Values.additionalVolumeMounts }}
{{- toYaml .Values.additionalVolumeMounts | default "" | nindent 10 }}
{{- end}}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.topologySpreadConstraints}}
topologySpreadConstraints:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "qdrant.fullname" . }}
volumes:
- name: qdrant-config
configMap:
name: {{ include "qdrant.fullname" . }}
defaultMode: 0755
{{- if and .Values.snapshotRestoration.enabled .Values.snapshotRestoration.pvcName }}
- name: qdrant-snapshot-restoration
persistentVolumeClaim:
claimName: {{ .Values.snapshotRestoration.pvcName }}
{{- end }}
{{- if not .Values.snapshotPersistence.enabled }}
- name: {{ .Values.snapshotPersistence.snapshotsVolumeName | default "qdrant-snapshots" }}
emptyDir: {}
{{- end }}
- name: qdrant-init
emptyDir: {}
{{- if or .Values.apiKey .Values.readOnlyApiKey }}
- name: qdrant-secret
secret:
secretName: {{ include "qdrant.fullname" . }}-apikey
defaultMode: 0600
{{- end }}
{{- if .Values.additionalVolumes }}
{{- toYaml .Values.additionalVolumes | default "" | nindent 8 }}
{{- end}}
volumeClaimTemplates:
- metadata:
name: {{ .Values.persistence.storageVolumeName | default "qdrant-storage" }}
labels:
app: {{ template "qdrant.name" . }}
{{- with .Values.persistence.additionalLabels }}
{{- toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.persistence.annotations }}
annotations:
{{- toYaml . | nindent 10 }}
{{- end }}
spec:
storageClassName: {{ .Values.persistence.storageClassName }}
{{- if .Values.persistence.volumeAttributesClassName }}
volumeAttributesClassName: {{ .Values.persistence.volumeAttributesClassName }}
{{- end }}
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.snapshotPersistence.enabled }}
- metadata:
name: {{ .Values.snapshotPersistence.snapshotsVolumeName | default "qdrant-snapshots" }}
labels:
app: {{ template "qdrant.name" . }}
{{- with .Values.snapshotPersistence.additionalLabels }}
{{- toYaml . | nindent 10 }}
{{- end }}
{{- with .Values.snapshotPersistence.annotations }}
annotations:
{{- toYaml . | nindent 10 }}
{{- end }}
spec:
storageClassName: {{ .Values.snapshotPersistence.storageClassName }}
{{- if .Values.snapshotPersistence.volumeAttributesClassName }}
volumeAttributesClassName: {{ .Values.snapshotPersistence.volumeAttributesClassName }}
{{- end }}
accessModes:
{{- range .Values.snapshotPersistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.snapshotPersistence.size | quote }}
{{- end }}
@@ -0,0 +1,128 @@
{{- $root := . }}
{{- $namespace := .Release.Namespace }}
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "qdrant.fullname" . }}-test-db-interaction"
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
containers:
- name: test-script
image: {{ .Values.chartTests.dbInteraction.image | quote }}
args: ['bash', '/app/entrypoint.sh']
volumeMounts:
- mountPath: /app
name: test-script
{{- if .Values.additionalVolumeMounts }}
{{- toYaml .Values.additionalVolumeMounts | default "" | nindent 8 }}
{{- end}}
resources:
{{- toYaml .Values.chartTests.dbInteraction.resources | nindent 8 }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 4 }}
{{- end }}
volumes:
- name: test-script
configMap:
name: "{{ include "qdrant.fullname" . }}-test-db-interaction"
{{- if .Values.additionalVolumes }}
{{- toYaml .Values.additionalVolumes | default "" | nindent 4 }}
{{- end}}
restartPolicy: Never
serviceAccountName: {{ include "qdrant.fullname" . }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ include "qdrant.fullname" . }}-test-db-interaction"
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- include "qdrant.additionalLabels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
data:
entrypoint.sh: |
#!/bin/bash
set -xe
# Kind's networking is very flaky
echo 'connect-timeout = 5' > $HOME/.curlrc
echo 'retry = 60' >> $HOME/.curlrc
echo 'retry-delay = 5' >> $HOME/.curlrc
echo 'retry-all-errors' >> $HOME/.curlrc
# Don't clutter the logs with progress bars
echo 'no-progress-meter' >> $HOME/.curlrc
# Ensure errors cause the script to fail, but show the response body
echo 'fail-with-body' >> $HOME/.curlrc
if [ -d /mnt/secrets/certs ]; then
cp /mnt/secrets/certs/ca.pem /usr/share/pki/trust/anchors/private-ca.pem
update-ca-certificates
fi
QDRANT_COLLECTION="test_collection"
{{- range .Values.service.ports }}
{{- if eq .name "http" }}
echo "Connecting to {{ include "qdrant.fullname" $root }}.{{ $namespace }}:{{ .port }}"
QDRANT_URL="http://{{ include "qdrant.fullname" $root }}.{{ $namespace }}:{{ .port }}"
{{- if and $root.Values.config.service $root.Values.config.service.enable_tls }}
echo "Using https"
QDRANT_URL="https://{{ include "qdrant.fullname" $root }}.{{ $namespace }}:{{ .port }}"
{{- end }}
{{- end }}
{{- end }}
API_KEY_HEADER=""
{{- if .Values.apiKey }}
API_KEY_HEADER="Api-key: {{ .Values.apiKey }}"
{{- else if .Values.readOnlyApiKey }}
API_KEY_HEADER="Api-key: {{ .Values.readOnlyApiKey }}"
{{- end }}
# Delete collection if exists
curl -X DELETE -H "${API_KEY_HEADER}" $QDRANT_URL/collections/${QDRANT_COLLECTION}
# Create collection
curl -X PUT \
-H 'Content-Type: application-json' \
-d '{"vectors":{"size":4,"distance":"Dot"}}' \
-H "${API_KEY_HEADER}" \
$QDRANT_URL/collections/${QDRANT_COLLECTION}
# Insert points
curl -X PUT \
-H 'Content-Type: application-json' \
-d '{"points":[
{"id":1,"vector":[0.05, 0.61, 0.76, 0.74],"payload":{"city":"Berlin"}},
{"id":2,"vector":[0.19, 0.81, 0.75, 0.11],"payload":{"city":"London"}},
{"id":3,"vector":[0.36, 0.55, 0.47, 0.94],"payload":{"city":"Moscow"}},
{"id":4,"vector":[0.18, 0.01, 0.85, 0.80],"payload":{"city":"New York"}},
{"id":5,"vector":[0.24, 0.18, 0.22, 0.44],"payload":{"city":"Beijing"}},
{"id":6,"vector":[0.35, 0.08, 0.11, 0.44],"payload":{"city":"Mumbai"}}
]}' \
-H "${API_KEY_HEADER}" \
$QDRANT_URL/collections/${QDRANT_COLLECTION}/points
# Run query
curl -X POST \
-H 'Content-Type: application-json' \
-d '{"vector":[0.2, 0.1, 0.9, 0.7],"limit":3}' \
-H "${API_KEY_HEADER}" \
$QDRANT_URL/collections/${QDRANT_COLLECTION}/points/search