New to KubeDB? Please start here.

Reconfigure Weaviate TLS (Transport Encryption)

This guide will show you how to use the KubeDB Ops Manager to add TLS to a running Weaviate cluster, rotate its certificates, update its issuer, and finally remove TLS.

Before You Begin

  • At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster.

  • Install KubeDB in your cluster following the steps here.

  • Install cert-manager in your cluster — Weaviate TLS is issued through cert-manager.

  • You should be familiar with the following KubeDB concepts:

To keep things isolated, this tutorial uses a separate namespace called demo throughout this tutorial.

$ kubectl create ns demo
namespace/demo created

Note: YAML files used in this tutorial are stored in docs/examples/weaviate/reconfigure-tls folder in GitHub repository kubedb/docs.

Deploy Weaviate without TLS

Deploy a Weaviate cluster without TLS and wait for it to become Ready. The REST service is served over plain HTTP on port 8080:

$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}'
http=8080 grpc=50051 gossip=7102 data=7103 raft=8300

Create an Issuer

Weaviate TLS is issued through cert-manager. First, create a CA secret and an Issuer named weaviate-issuer in the demo namespace:

$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
    -keyout weaviate-ca.key -out weaviate-ca.crt -subj "/CN=weaviate-ca"

$ kubectl create secret tls weaviate-ca \
    --cert=weaviate-ca.crt --key=weaviate-ca.key -n demo
secret/weaviate-ca created
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: weaviate-issuer
  namespace: demo
spec:
  ca:
    secretName: weaviate-ca
$ kubectl apply -f issuer.yaml
issuer.cert-manager.io/weaviate-issuer created

$ kubectl get issuer -n demo
NAME              READY   AGE
weaviate-issuer   True    3s

Add TLS to the Cluster

Now, create a ReconfigureTLS OpsRequest that points at the issuer:

apiVersion: ops.kubedb.com/v1alpha1
kind: WeaviateOpsRequest
metadata:
  name: weaviate-add-tls
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: weaviate-sample
  tls:
    issuerRef:
      name: weaviate-issuer
      kind: Issuer
      apiGroup: cert-manager.io
  timeout: 5m
  apply: IfReady
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/weaviate/reconfigure-tls/add-tls.yaml
weaviateopsrequest.ops.kubedb.com/weaviate-add-tls created

The Ops Manager issues the certificates and restarts the pods.

$ kubectl get weaviateopsrequest -n demo weaviate-add-tls
NAME               TYPE             STATUS       AGE
weaviate-add-tls   ReconfigureTLS   Successful   2m

The status.conditions show the certificates being synced and the pods restarted:

$ kubectl get weaviateopsrequest -n demo weaviate-add-tls -o yaml
...
status:
  conditions:
  - message: Weaviate ops-request has started to reconfigure tls for Weaviate nodes
    reason: ReconfigureTLS
    status: "True"
    type: ReconfigureTLS
  - message: get certificate; ConditionStatus:True
    status: "True"
    type: GetCertificate
  - message: Successfully synced all certificates
    reason: CertificateSynced
    status: "True"
    type: CertificateSynced
  - message: successfully reconciled the Weaviate with tls configuration
    reason: UpdatePetSets
    status: "True"
    type: UpdatePetSets
  - message: Successfully restarted all nodes
    reason: RestartNodes
    status: "True"
    type: RestartNodes
  - message: Successfully completed reconfigureTLS for Weaviate.
    reason: Successful
    status: "True"
    type: Successful
  observedGeneration: 1
  phase: Successful

Verify that the REST service now serves HTTPS on port 8443 and the certificates were created:

$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}'
https=8443 grpc=50051 gossip=7102 data=7103 raft=8300

$ kubectl get certificate -n demo
NAME                          READY   SECRET                        AGE
weaviate-sample-client-cert   True    weaviate-sample-client-cert   84s
weaviate-sample-server-cert   True    weaviate-sample-server-cert   84s

The cluster requires client certificate authentication (mTLS) by default. You can connect like this:

$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.ca\.crt}'  | base64 -d > ca.crt
$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt
$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key

$ kubectl port-forward -n demo svc/weaviate-sample 8443:8443
# in another terminal
$ curl -s -o /dev/null -w "%{http_code}\n" --cacert ca.crt --cert client.crt --key client.key \
    https://localhost:8443/v1/.well-known/ready -H "Authorization: Bearer <api-key>"
200

Rotate Certificates

To re-issue the certificates (for example, before they expire), create a ReconfigureTLS OpsRequest with rotateCertificates: true. This example also disables client-certificate authentication by setting clientAuth: false:

apiVersion: ops.kubedb.com/v1alpha1
kind: WeaviateOpsRequest
metadata:
  name: wvops-rotate
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: weaviate-sample
  tls:
    clientAuth: false
    rotateCertificates: true
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/weaviate/reconfigure-tls/rotate-certificate.yaml
weaviateopsrequest.ops.kubedb.com/wvops-rotate created

$ kubectl get weaviateopsrequest -n demo wvops-rotate
NAME           TYPE             STATUS       AGE
wvops-rotate   ReconfigureTLS   Successful   2m

Verify that the server certificate has a newer validity window:

$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -dates
subject=CN=weaviate-sample
notBefore=Jun 30 17:52:42 2026 GMT
notAfter=Sep 28 17:52:42 2026 GMT

Update the Issuer

You can switch the cluster to a different cert-manager issuer. First, create the new CA secret and the weaviate-new-issuer:

$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
    -keyout weaviate-new-ca.key -out weaviate-new-ca.crt -subj "/CN=weaviate-new-ca"

$ kubectl create secret tls weaviate-new-ca \
    --cert=weaviate-new-ca.crt --key=weaviate-new-ca.key -n demo
secret/weaviate-new-ca created
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: weaviate-new-issuer
  namespace: demo
spec:
  ca:
    secretName: weaviate-new-ca
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/weaviate/reconfigure-tls/weaviate-new-issuer.yaml
issuer.cert-manager.io/weaviate-new-issuer created

Now, create a ReconfigureTLS OpsRequest that points at the new issuer:

apiVersion: ops.kubedb.com/v1alpha1
kind: WeaviateOpsRequest
metadata:
  name: wvops-update-issuer
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: weaviate-sample
  tls:
    issuerRef:
      name: weaviate-new-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/weaviate/reconfigure-tls/update-issuer.yaml
weaviateopsrequest.ops.kubedb.com/wvops-update-issuer created

$ kubectl get weaviateopsrequest -n demo wvops-update-issuer
NAME                  TYPE             STATUS       AGE
wvops-update-issuer   ReconfigureTLS   Successful   2m

Verify that the server certificate is now signed by the new CA:

$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls.issuerRef.name}'
weaviate-new-issuer

$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -issuer
issuer=CN=weaviate-new-ca

Remove TLS

Finally, to disable TLS, create a ReconfigureTLS OpsRequest with remove: true:

apiVersion: ops.kubedb.com/v1alpha1
kind: WeaviateOpsRequest
metadata:
  name: wvops-remove
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: weaviate-sample
  tls:
    remove: true
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/weaviate/reconfigure-tls/remove-tls.yaml
weaviateopsrequest.ops.kubedb.com/wvops-remove created

$ kubectl get weaviateopsrequest -n demo wvops-remove
NAME           TYPE             STATUS       AGE
wvops-remove   ReconfigureTLS   Successful   2m

Verify that the service is back to plain HTTP on port 8080, the spec.tls field is cleared, and the certificate secrets are gone:

$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}'
http=8080 grpc=50051 gossip=7102 data=7103 raft=8300

$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}'

$ kubectl get secret -n demo | grep weaviate-sample-.*cert
# (no cert secrets)

TLS has been added, rotated, re-issued with a new CA, and finally removed — all without recreating the database.

Next Steps

Cleaning up

To cleanup the Kubernetes resources created by this tutorial, run:

$ kubectl delete weaviateopsrequest -n demo weaviate-add-tls wvops-rotate wvops-update-issuer wvops-remove
$ kubectl delete weaviate -n demo weaviate-sample
$ kubectl delete issuer -n demo weaviate-issuer weaviate-new-issuer
$ kubectl delete ns demo