New to KubeDB? Please start here.
Configure TLS for Weaviate
This tutorial will show you how to provision a Weaviate cluster with TLS enabled from the start, using KubeDB and cert-manager.
Before You Begin
At first, you need to have a Kubernetes cluster, and the
kubectlcommand-line tool must be configured to communicate with your cluster.Install
KubeDBin 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
KubeDBconcepts:
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/tls folder in GitHub repository kubedb/docs.
Create an Issuer
Weaviate TLS is issued through cert-manager. First, create a self-signed CA and a Secret that holds it:
$ 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
Now, create an Issuer named weaviate-issuer that references this CA secret:
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
Deploy Weaviate with TLS
Now, create a Weaviate CR with spec.tls referencing the issuer. Setting clientAuth: true requires clients to present a valid client certificate (mutual TLS):
apiVersion: kubedb.com/v1alpha2
kind: Weaviate
metadata:
name: weaviate-sample
namespace: demo
spec:
version: 1.33.1
replicas: 3
storageType: Durable
storage:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
tls:
issuerRef:
apiGroup: cert-manager.io
kind: Issuer
name: weaviate-issuer
clientAuth: true
deletionPolicy: WipeOut
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.6.19/docs/examples/weaviate/tls/tls.yaml
weaviate.kubedb.com/weaviate-sample created
Wait until the cluster becomes Ready:
$ kubectl get weaviate -n demo
NAME TYPE VERSION STATUS AGE
weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 73s
$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample
NAME READY STATUS RESTARTS AGE
weaviate-sample-0 1/1 Running 0 71s
weaviate-sample-1 1/1 Running 0 59s
weaviate-sample-2 1/1 Running 0 45s
Verify TLS Resources
KubeDB created cert-manager Certificate resources and the corresponding TLS secrets (a server and a client certificate):
$ kubectl get certificate -n demo
NAME READY SECRET AGE
weaviate-sample-client-cert True weaviate-sample-client-cert 73s
weaviate-sample-server-cert True weaviate-sample-server-cert 73s
$ kubectl get secret -n demo | grep weaviate-sample
weaviate-sample-auth Opaque 3 73s
weaviate-sample-client-cert kubernetes.io/tls 4 73s
weaviate-sample-d25c86 Opaque 1 73s
weaviate-sample-server-cert kubernetes.io/tls 3 73s
The spec.tls block on the Weaviate object reflects the TLS configuration:
$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' | jq
{
"certificates": [
{"alias": "server", "secretName": "weaviate-sample-server-cert"},
{"alias": "client", "secretName": "weaviate-sample-client-cert"}
],
"clientAuth": true,
"issuerRef": {
"apiGroup": "cert-manager.io",
"kind": "Issuer",
"name": "weaviate-issuer"
}
}
With TLS enabled, the REST service is served over HTTPS on port 8443 instead of plain HTTP on 8080:
$ 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
You can inspect the issued server certificate:
$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -issuer -dates
subject=CN=weaviate-sample
issuer=CN=weaviate-ca
notBefore=Jun 30 18:07:40 2026 GMT
notAfter=Sep 28 18:07:40 2026 GMT
Connect over TLS
Because clientAuth is enabled, clients must present the client certificate. Extract the certificates from the client secret and connect through a port-forward:
$ 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
$ export WEAVIATE_API_KEY=$(kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d)
$ 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 $WEAVIATE_API_KEY"
200
$ curl -s --cacert ca.crt --cert client.crt --key client.key \
https://localhost:8443/v1/nodes \
-H "Authorization: Bearer $WEAVIATE_API_KEY" | jq '.nodes[] | {name, status}'
{"name": "weaviate-sample-0", "status": "HEALTHY"}
{"name": "weaviate-sample-1", "status": "HEALTHY"}
{"name": "weaviate-sample-2", "status": "HEALTHY"}
All three nodes are reachable over the TLS-encrypted, mutually-authenticated REST endpoint.
Next Steps
- Detail concepts of Weaviate object.
- Add, rotate, or remove TLS on a running cluster: Reconfigure TLS.
- Want to hack on KubeDB? Check our contribution guidelines.
Cleaning up
To clean up the Kubernetes resources created by this tutorial, run:
$ kubectl delete weaviate -n demo weaviate-sample
$ kubectl delete issuer -n demo weaviate-issuer
$ kubectl delete secret -n demo weaviate-ca
$ kubectl delete ns demo































