You are looking at the documentation of a prior release. To read the documentation of the latest release, please
visit here.
New to KubeDB? Please start here.
KubeDB - Milvus Standalone
This tutorial shows how to use KubeDB to provision a standalone Milvus database.
Before You Begin
- You need a Kubernetes cluster and
kubectlconfigured to talk to it. - Install KubeDB with
--set global.featureGates.Milvus=true. - Complete the dependency setup from Prepare Dependencies. That guide installs MinIO, creates the
my-release-miniosecret, and installs the etcd operator required by Milvus. - This quickstart intentionally uses the smallest working manifest. It does not require Prometheus Operator or cert-manager.
Note: The yaml files used in this tutorial are stored in docs/guides/milvus/quickstart/yamls folder in GitHub repository kubedb/docs.
Find Available Milvus Versions
When you install the KubeDB operator, it registers a CRD named MilvusVersion. The installation comes with a set of built-in MilvusVersion objects:
$ kubectl get milvusversions
NAME VERSION DB_IMAGE DEPRECATED AGE
2.6.11 2.6.11 ghcr.io/appscode-images/milvus:2.6.11 11h
2.6.7 2.6.7 ghcr.io/appscode-images/milvus:2.6.7 11h
2.6.9 2.6.9 ghcr.io/appscode-images/milvus:2.6.9 11h
Create a Standalone Milvus
The following manifest is the smallest durable standalone deployment:
standalone.yaml
apiVersion: kubedb.com/v1alpha2
kind: Milvus
metadata:
name: milvus-standalone
namespace: demo
spec:
version: "2.6.11"
topology:
mode: Standalone
objectStorage:
configSecret:
name: "my-release-minio"
storageType: Durable
storage:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 1Gi
Here,
spec.versionis the name of aMilvusVersionobject.spec.topology.mode: Standalonedeploys Milvus as a single all-in-one workload.spec.objectStorage.configSecretpoints to the required MinIO/object-storage secret.spec.metaStorageis omitted, so KubeDB creates and manages an internal etcd cluster through the installed etcd operator.spec.storageType: Durabletells KubeDB to provision persistent storage for the standalone workload.
Create the database:
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/guides/milvus/quickstart/yamls/standalone.yaml
milvus.kubedb.com/milvus-standalone created
Wait for the Database to be Ready
Watch the Milvus object until its STATUS becomes Ready:
Because both
milvuses.kubedb.comandmilvuses.gitops.kubedb.comare registered, the short namemilvusis ambiguous. Usemilvuses.kubedb.com.
$ kubectl get milvuses.kubedb.com -n demo -w
NAME VERSION STATUS AGE
milvus-standalone 2.6.11 Provisioning 24s
milvus-standalone 2.6.11 Ready 39s
Standalone Milvus typically becomes ready within a few minutes.
Verify the Created Resources
PetSet and Pod
$ kubectl get petset -n demo -l app.kubernetes.io/instance=milvus-standalone
NAME AGE
milvus-standalone 88s
$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-standalone
NAME READY STATUS RESTARTS AGE
milvus-standalone-0 1/1 Running 0 88s
Service
KubeDB creates a primary client service named after the database. It exposes:
- gRPC on
19530 - metrics on
9091 - REST on
8080
$ kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-standalone
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
milvus-standalone ClusterIP 10.43.144.154 <none> 19530/TCP,9091/TCP,8080/TCP 91s
If you later enable Prometheus Operator monitoring, KubeDB also creates a dedicated milvus-standalone-stats service on port 9091 for scraping.
Storage
The standalone workload mounts a single persistent volume created from spec.storage:
$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-milvus-standalone-0 Bound pvc-a6333ee2-f0ab-4ec2-8437-599d270b9ed0 1Gi RWO local-path 90s
The internal etcd metadata store provisions its own PVCs (etcd-data-<milvus-name>-etcd-*), and MinIO has separate PVCs as well.
Auth Secret
Milvus authentication is enabled by default. Because spec.authSecret was not provided, KubeDB auto-generates a basic-auth secret named <db-name>-auth with a root user and a random password:
$ kubectl get secret -n demo | grep milvus-standalone
milvus-standalone-42559a Opaque 2 92s
milvus-standalone-auth kubernetes.io/basic-auth 2 92s
$ kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d
root
$ kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d
<generated-password>
The other secret (milvus-standalone-42559a) is the rendered configuration secret holding milvus.yaml and glog.conf.
AppBinding
KubeDB also creates an AppBinding pointing at the primary service and the auth secret. Because this quickstart does not enable TLS, the connection scheme is http:
$ kubectl get appbinding milvus-standalone -n demo -o yaml
...
spec:
clientConfig:
service:
name: milvus-standalone
path: /
port: 19530
scheme: http
secret:
kind: Secret
name: milvus-standalone-auth
type: kubedb.com/milvus
version: 2.6.11
Connect and Run Basic Operations
Once the database is Ready, you can verify it by creating a collection and running a simple vector search through the REST API.
Port-forward the REST port
Run this in a separate terminal:
$ kubectl port-forward svc/milvus-standalone -n demo 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Get the root password
$ PASSWORD=$(kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d)
The auth secret lives in the same namespace as the database. If the database is in
demo, use-n demohere too.
Create a collection
$ curl -s -X POST "http://localhost:8080/v2/vectordb/collections/create" \
-H "Authorization: Bearer root:${PASSWORD}" \
-H "Content-Type: application/json" \
-d '{
"collectionName": "health_check_collection",
"dbName": "default",
"dimension": 4,
"metricType": "L2"
}' | jq .
{
"code": 0,
"data": {}
}
Load the collection
$ curl -s -X POST "http://localhost:8080/v2/vectordb/collections/load" \
-H "Authorization: Bearer root:${PASSWORD}" \
-H "Content-Type: application/json" \
-d '{
"collectionName": "health_check_collection",
"dbName": "default"
}' | jq .
{
"code": 0,
"data": {}
}
Insert sample vectors
$ curl -s -X POST "http://localhost:8080/v2/vectordb/entities/insert" \
-H "Authorization: Bearer root:${PASSWORD}" \
-H "Content-Type: application/json" \
-d '{
"collectionName": "health_check_collection",
"dbName": "default",
"data": [
{"id": 1, "vector": [0.9, 0.8, 0.7, 0.6]},
{"id": 2, "vector": [0.5, 0.4, 0.3, 0.2]}
]
}' | jq .
{
"code": 0,
"cost": 0,
"data": {
"insertCount": 2,
"insertIds": [1, 2]
}
}
Search the vectors
$ curl -s -X POST "http://localhost:8080/v2/vectordb/entities/search" \
-H "Authorization: Bearer root:${PASSWORD}" \
-H "Content-Type: application/json" \
-d '{
"collectionName": "health_check_collection",
"dbName": "default",
"data": [[0.5, 0.4, 0.3, 0.2]],
"topK": 2,
"metricType": "L2",
"params": {"nprobe": 10}
}' | jq .
{
"code": 0,
"cost": 0,
"data": [
{
"distance": 0,
"id": 2
},
{
"distance": 0.64,
"id": 1
}
],
"topks": [2]
}
Use an External etcd Cluster Instead
The default quickstart omits spec.metaStorage, so KubeDB manages etcd for you. If you want Milvus to use an external etcd cluster instead:
- Install the etcd operator.
- Manage your etcd cluster yourself.
- Add
spec.metaStorage.externallyManaged: trueand the external endpoints to yourMilvusmanifest as shown in Prepare Dependencies.
Cleaning up
$ kubectl patch -n demo milvus.kubedb.com milvus-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge"
$ kubectl delete milvus.kubedb.com milvus-standalone -n demo
If you want to remove the dependencies too, either delete the whole demo namespace or follow the cleanup steps in Prepare Dependencies.
Next Steps
- Prepare Dependencies for another cluster.
- Deploy a Distributed Milvus.
- Enable Prometheus Operator monitoring.
- Enable TLS.
- Detail concepts of Milvus object.
- Want to hack on KubeDB? Check our contribution guidelines.































