New to KubeDB? Please start here.

Configure TLS/SSL for Milvus

This guide will show you how to deploy a Milvus database with TLS/SSL enabled from the start, using cert-manager.

Before You Begin

  • Install cert-manager in your cluster.

  • You should be familiar with the following KubeDB concepts:

  • An object-storage secret named my-release-minio must exist in the demo namespace.

Note: The yaml files used in this tutorial are stored in docs/guides/milvus/tls/configure/yamls folder in GitHub repository kubedb/docs.

Create a cert-manager Issuer

KubeDB uses cert-manager to issue the Milvus certificates. First create a self-signed CA secret, then an Issuer (or ClusterIssuer) backed by it.

$ openssl genrsa -out ca.key 2048
$ openssl req -x509 -new -nodes -key ca.key -subj "/CN=milvus-ca/O=kubedb" -days 3650 -out ca.crt
$ kubectl create secret tls milvus-ca --cert=ca.crt --key=ca.key -n demo
secret/milvus-ca created

issuer.yaml

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: milvus-issuer
  namespace: demo
spec:
  ca:
    secretName: milvus-ca
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.6.19/docs/guides/milvus/tls/configure/yamls/issuer.yaml
issuer.cert-manager.io/milvus-issuer created

$ kubectl get issuer -n demo
NAME            READY   AGE
milvus-issuer   True    5s

A ClusterIssuer works the same way; a sample cluster-issuer.yaml (backed by secret milvus-cluster-ca) is included in the yamls folder. With a ClusterIssuer, set spec.tls.issuerRef.kind: ClusterIssuer.

Deploy a TLS-Secured Standalone Milvus

The standalone manifest enables TLS via spec.tls:

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
  tls:
    issuerRef:
      name: milvus-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"
    external:
      mode: mTLS
    internal:
      mode: TLS
  • spec.tls.external.mode: mTLS requires clients to present a certificate.
  • spec.tls.internal.mode: TLS encrypts inter-component traffic.
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.6.19/docs/guides/milvus/tls/configure/yamls/standalone.yaml
milvus.kubedb.com/milvus-standalone created

Wait until it is Ready.

Verify TLS

Certificate Secrets

KubeDB requests the server and client certificates and stores them in secrets:

$ kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert'
milvus-standalone-client-cert   kubernetes.io/tls   4   91s
milvus-standalone-server-cert   kubernetes.io/tls   3   91s

TLS Files Mounted in the Pod

The certificates and CA are mounted at /milvus/tls:

$ kubectl exec -n demo milvus-standalone-0 -c milvus -- ls -l /milvus/tls
ca.pem
client.key
client.pem
server.key
server.pem

Rendered Configuration

The rendered milvus.yaml wires the certificates into Milvus:

$ kubectl get secret <config-secret> -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A4 internaltls
internaltls:
    caPemPath: /milvus/tls/ca.pem
    serverKeyPath: /milvus/tls/server.key
    serverPemPath: /milvus/tls/server.pem
    sni: milvus-standalone

AppBinding Scheme

Because TLS is enabled, the AppBinding connection scheme is https:

$ kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}'
https

TLS-Secured Distributed Milvus

The distributed manifest enables TLS the same way. The server/client certificates are issued once and propagated to every distributed role (mixcoord, datanode, querynode, streamingnode, proxy).

apiVersion: kubedb.com/v1alpha2
kind: Milvus
metadata:
  name: milvus-cluster
  namespace: demo
spec:
  version: "2.6.11"
  objectStorage:
    configSecret:
      name: "my-release-minio"
  topology:
    mode: Distributed
    distributed:
      streamingnode:
        storageType: Durable
        storage:
          accessModes:
            - ReadWriteOnce
          storageClassName: local-path
          resources:
            requests:
              storage: 1Gi
  tls:
    issuerRef:
      name: milvus-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"
    external:
      mode: mTLS
    internal:
      mode: TLS

After it becomes Ready, the certificate secrets exist, the certificates are mounted into every role’s pods, and the AppBinding scheme is https:

$ kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert'
milvus-cluster-client-cert   kubernetes.io/tls   4   4m
milvus-cluster-server-cert   kubernetes.io/tls   3   4m

$ kubectl exec -n demo milvus-cluster-mixcoord-0 -c milvus -- ls /milvus/tls
ca.pem
client.key
client.pem
server.key
server.pem

$ kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}'
https

Cleaning up

$ kubectl delete milvus.kubedb.com -n demo milvus-standalone
$ kubectl delete issuer -n demo milvus-issuer
$ kubectl delete secret -n demo milvus-ca
$ kubectl delete ns demo

Next Steps