Skip to main content
These instructions explain how to deploy Milvus, an open source vector database built for GenAI applications, on CoreWeave Kubernetes Service (CKS). By the end of this tutorial, you’ll have a running Milvus cluster backed by CoreWeave AI Object Storage, with optional GPU-based indexing and scheduled backups. This tutorial is intended for platform engineers and ML practitioners who want to run a managed Milvus deployment on CKS to support similarity search and other vector workloads.

Prerequisites

Before you start, you need:
  • A working CKS cluster with at least one CPU Node. GPU Nodes are also supported, but CPU Nodes are preferred unless you plan to use GPU-based indexing.
  • Access Key and Secret Key with permissions to use a CoreWeave AI Object Storage bucket.
You’ll need the following tools on your local machine:
  • kubectl installed and configured for your cluster.
  • helm version 3.8 or later.
  • Git.
It’s also helpful to have an Object Storage command-line tool such as the AWS CLI to access your bucket when testing.

Step 1. Verify your system configuration

Before installing Milvus, confirm that your cluster is reachable and has the Node types required for the deployment.
  1. Verify that you can access your cluster with kubectl. For example:
    kubectl cluster-info
    
    You should see something similar to:
    Kubernetes control plane is running at...
    CoreDNS is running at...
    node-local-dns is running at...
    
  2. Verify your cluster has at least one CPU Node. GPU Nodes are also supported, but CPU Nodes are preferred unless you plan to use GPU-based indexing. For example:
    kubectl get nodes -o=custom-columns="NAME:metadata.name,CLASS:metadata.labels['node\.coreweave\.cloud\/class']"
    
    You should see something similar to the following:
    NAME      CLASS
    g137a10   gpu
    g5424e0   cpu
    g77575e   cpu
    gd926d4   gpu
    

Step 2. Deploy Milvus

In this step, you install the Milvus Operator and prepare the CoreWeave Milvus Helm chart with your Object Storage and indexing settings.
  1. Install the Milvus Operator. See the Operator installation guide for more details.
    helm install milvus-operator \
      -n milvus-operator --create-namespace \
      --wait --wait-for-jobs \
      https://github.com/zilliztech/milvus-operator/releases/download/v1.3.0/milvus-operator-1.3.0.tgz
    
    This installs the Milvus Custom Resource Definition (CRD), which defines Milvus clusters, along with the Operator that manages them. It creates a new namespace called milvus-operator for the Operator itself. You can add milvus-operator as a dependency to the CoreWeave chart (which you’ll download in the next step), but installing it in a separate namespace from the database is preferred. The Operator can manage multiple Milvus clusters in different namespaces.
  2. Clone the CoreWeave Milvus chart repository at: https://github.com/coreweave/reference-architecture/tree/main/tooling/vector_dbs/cw-milvus
  3. Edit the chart’s values.yaml with your details: Replace [BUCKET-NAME] with the name of your Object Storage bucket, and replace [ACCESS-KEY] and [SECRET-KEY] with your Object Storage credentials.
    caiosBucketName: [BUCKET-NAME]
    caiosAccessKey: [ACCESS-KEY]
    caiosSecretKey: [SECRET-KEY]
    
    Check the deleteDependencies policyThis chart automatically deletes dependencies like etcd and kafka by default. This makes it easier to clean up after an experiment is complete.You should set deleteDependencies to false if you want to retain these dependencies after deleting the Milvus custom resource.
  4. If you plan to use GPU-based indexing, set the gpuIndexing value to true in values.yaml. This schedules the relevant components on GPU Nodes as shown.
    dataNode:
      affinity:
        nodeAffinity:
          # override global component affinity when using GPU indexing
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node.coreweave.cloud/class
                operator: In
                values:
                - gpu
    queryNode:
      affinity:
        nodeAffinity:
          # override global component affinity when using GPU indexing
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node.coreweave.cloud/class
                operator: In
                values:
                - gpu
    

Chart defaults

The CoreWeave chart handles the following items:
  • It provisions a secret with the Object Storage credentials you specified in values.yaml.
  • It configures the Object Storage bucket you specified, with aliyun as the provider. This ensures that Milvus uses virtual-host style addressing.
    config:
      minio:
        # Use "aliyun" as cloud provider, as that enables virtual host style bucket requests
        cloudProvider: aliyun
        useVirtualHost: true
        bucketName: {{ .Values.caiosBucketName }}
        # Optional, config the prefix of the bucket milvus will use
        rootPath: {{ include "cw-milvus.name" . }}
        useSSL: true
    
  • It sets the storage type to S3 and uses the CoreWeave AI Object Storage endpoint (cwobject.com:443).
    dependencies:
      storage:
      # enable external object storage
      external: true
      type: S3 # MinIO | S3
      # the endpoint of AWS S3
      endpoint: cwobject.com:443
      # the secret storing the access key and secret key
      secretRef: '{{ include "cw-milvus.name" . }}-caios-secret'
    
  • It configures Kafka as the message storage service and overrides the default image.
    kafka:
      inCluster:
        deletionPolicy: Delete
        pvcDeletion: true
        values:
        image:
          repository: bitnami/kafka
          tag: 3.7.0-debian-12-r6
    
  • It sets Node affinities for the Milvus components to CPU Nodes. However, scheduling onto GPU Nodes is also possible when using GPU-based indexing as described in Step 2.
    affinity:
      nodeAffinity:
        # prefer running on CPU nodes, if available
        # see also queryNode and dataNode affinities for GPU-based indexing
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            preference:
              matchExpressions:
              - key: node.coreweave.cloud/class
                operator: In
                values:
                - cpu
    
  • It configures a CronJob for backup using milvus-backup. You can control the cron expression for scheduling the job, as well as settings for the backup bucket through values in values.yaml. If you don’t specify a bucket name and credentials for backups, the ones specified for the database are used. Replace [BACKUP-BUCKET-NAME] with the name of your backup bucket, and replace [BACKUP-ACCESS-KEY] and [BACKUP-SECRET-KEY] with the credentials for that bucket.
    backupCaiosBucketName: [BACKUP-BUCKET-NAME]
    backupCaiosAccessKey: [BACKUP-ACCESS-KEY]
    backupCaiosSecretKey: [BACKUP-SECRET-KEY]
    # defaults to "backup"
    backupCaiosBucketRootPath:
    backupCronExpression: "30 7 * * *"
    
    Backups accumulate over timeBackup names are based on timestamps, so they’re unique. Backups accumulate in your bucket unless you periodically clean out unneeded ones.

Step 3. Install the chart

With the Operator running and values.yaml configured, install the CoreWeave Milvus chart to create the Milvus custom resource and provision the database.
  1. Change to the chart directory:
    cd reference-architecture/tooling/vector_dbs/cw-milvus
    
  2. Install the chart in a new namespace, for example milvus:
    helm install -n milvus cw-milvus .
    
  3. Check the status of the custom resource. This might take several minutes to complete, as the Operator sets up the database and its dependencies.
    kubectl -n milvus describe milvus cw-milvus
    
    The Conditions block shows the status of individual components. After everything is set up, that block should look like this:
    Conditions:
        Last Transition Time:  2025-09-22T21:47:24Z
        Message:               All Milvus components are healthy
        Reason:                ReasonMilvusHealthy
        Status:                True
        Type:                  MilvusReady
        Last Transition Time:  2025-09-18T23:14:29Z
        Message:               Milvus components are all updated
        Reason:                MilvusComponentsUpdated
        Status:                True
        Type:                  MilvusUpdated
        Last Transition Time:  2025-09-18T23:12:32Z
        Message:               Etcd endpoints is healthy
        Reason:                EtcdReady
        Status:                True
        Type:                  EtcdReady
        Last Transition Time:  2025-09-18T23:12:32Z
        Reason:                StorageReady
        Status:                True
        Type:                  StorageReady
        Last Transition Time:  2025-09-18T23:13:29Z
        Reason:                MsgStreamReady
        Status:                True
        Type:                  MsgStreamReady
    

Step 4. Access the database

After the database is ready, the web UI service is available on port 9091, and the database service is available on port 19530. To access these, forward local ports from your machine to the service.
  1. Forward a local port to the database service.
    kubectl port-forward --address 0.0.0.0 service/cw-milvus-milvus 27017:19530
    Forwarding from 0.0.0.0:27017 -> 19530
    
  2. Forward a local port to the web UI service.
    kubectl port-forward --address 0.0.0.0 service/cw-milvus-milvus 27018:9091
    Forwarding from 0.0.0.0:27018 -> 9091
    
You can now access the web UI at http://localhost:27018 and connect to the database at localhost:27017. At this point, your Milvus cluster is deployed on CKS, backed by CoreWeave AI Object Storage, and ready for you to create collections and load data.

Additional resources

See the Milvus documentation to learn more.
Last modified on June 10, 2026