Enable TLS in Vertica on Kubernetes
To protect database communications and enforce certificate verification, the VerticaDB operator supports Transport Layer Security (TLS) for the following:
- HTTPS/NMA service: Secures the REST interface used by
vclusteropsand the Node Management Agent (NMA). - Client-Server authentication: Secures connections between external client applications (vsql, JDBC, ODBC, ADO.NET) and Vertica server nodes.
- Internode traffic: Encrypts and validates communications between database cluster nodes.
The Vertica database server does not store private keys or certificates in its catalog or on local disk. Instead, it dynamically reads TLS credentials from Kubernetes secrets or AWS Secrets Manager.
TLS configuration modes and parameters
The following table describes the TLS configuration parameters and their supported modes:
| Parameter | Description | Supported modes | Default mode |
|---|---|---|---|
httpsNMATLS |
TLS for the HTTPS service and Node Management Agent (NMA). |
DISABLE, ENABLE, TRY_VERIFY, VERIFY_CA, VERIFY_FULL |
TRY_VERIFY |
clientServerTLS |
TLS for SQL client connections (vsql, drivers). |
DISABLE, ENABLE, TRY_VERIFY, VERIFY_CA, VERIFY_FULL |
TRY_VERIFY |
interNodeTLS |
TLS for internal cluster communication (version 26.1.0-0 and higher). |
DISABLE, ENABLE, VERIFY_CA |
VERIFY_CA |
Note
- Automatic secret generation: If you enable TLS and omit the
secretfield, the VerticaDB operator automatically generates self-signed TLS certificates in Kubernetes secrets named<vdb-name>-https-tls-<hash>,<vdb-name>-clientserver-tls-<hash>, and<vdb-name>-internode-tls-<hash>. - Custom certificates: If you supply your own certificates, they must be stored in a Kubernetes secret of type
kubernetes.io/tlsthat contains the keystls.key,tls.crt, andca.crt. You can also store custom certificates in an AWS Secrets Manager secret. - Irreversibility: After TLS is enabled on a database, it cannot be disabled.
You can enable TLS when you:
- Create the database
- Revive the database
- Update a database that was created or revived without TLS
- Upgrade the operator or database server
Enable TLS when creating the database
When you initialize a new database (initPolicy: Create), you can configure TLS parameters directly in the initial VerticaDB custom resource (CR) manifest. The operator provisions the cluster with TLS configured and enabled from the start.
-
(Optional) If you are using custom certificates instead of operator-generated certificates, you can create your own in AWS Secrets Manager or create the Kubernetes secrets in the same namespace where the VerticaDB CR is deployed:
# Create custom secret for HTTPS/NMA $ kubectl create secret generic custom-https-tls \ --from-file=tls.key=/path/to/https.key \ --from-file=tls.crt=/path/to/https.crt \ --from-file=ca.crt=/path/to/ca.crt # Create custom secret for Client-Server TLS $ kubectl create secret generic custom-client-tls \ --from-file=tls.key=/path/to/client.key \ --from-file=tls.crt=/path/to/client.crt \ --from-file=ca.crt=/path/to/ca.crt # Create custom secret for Internode TLS $ kubectl create secret generic custom-internode-tls \ --from-file=tls.key=/path/to/internode.key \ --from-file=tls.crt=/path/to/internode.crt \ --from-file=ca.crt=/path/to/ca.crt -
Define the initial VerticaDB CR manifest. Include the TLS annotations and specifications in
metadata.annotationsandspec:apiVersion: vertica.com/v1 kind: VerticaDB metadata: name: vertica-db annotations: vertica.com/tls-cache-duration: "86400" vertica.com/remove-tls-secret-on-vdb-delete: "false" spec: initPolicy: Create dbName: vertdb licenseSecret: vertica-license passwordSecret: su-passwd communal: path: "s3://vertica-communal-storage/vertdb" endpoint: "https://s3.amazonaws.com" credentialSecret: s3-creds region: us-east-1 subclusters: - name: primary size: 3 serviceType: ClusterIP shardCount: 6 httpsNMATLS: enabled: true mode: TRY_VERIFY secret: custom-https-tls # Omit to allow the operator to auto-generate clientServerTLS: enabled: true mode: TRY_VERIFY secret: custom-client-tls # Omit to allow the operator to auto-generate interNodeTLS: enabled: true mode: VERIFY_CA secret: custom-internode-tls # Omit to allow the operator to auto-generate dbTlsConfig: tlsVersion: 2 # 2 for TLS 1.2, 3 for TLS 1.3 cipherSuites: "" -
Apply the manifest:
$ kubectl apply -f verticadb-initial.yaml -
Monitor the operator reconciliation events:
$ kubectl describe vdb vertica-dbExpected events include:
Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for httpsNMA Normal TLSConfigurationSucceeded 3m verticadb-operator Successfully set HTTP tls config Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for clientServer Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Server tls config Normal TLSConfigurationStarted 2m verticadb-operator Starting to configure TLS for interNode Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Internode tls config -
Verify the generated Kubernetes secrets (if auto-generated):
$ kubectl get secrets -l app.kubernetes.io/name=vertica -
Verify the TLS authentication records created in the database:
=> SELECT auth_name, auth_host_type, auth_method, is_fallthrough_enabled FROM client_auth WHERE auth_name LIKE '%k8s%'; auth_name | auth_host_type | auth_method | is_fallthrough_enabled ----------------------------------------------+----------------+-------------+------------------------ k8s_remote_ipv4_tls_builtin_auth | HOSTSSL | TLS | False k8s_remote_ipv6_tls_builtin_auth | HOSTSSL | TLS | False k8s_local_tls_builtin_auth | LOCALSSL | TLS | False k8s_remote_ipv4_reject_non_tls_builtin_auth | HOSTNOSSL | REJECT | False k8s_remote_ipv6_reject_non_tls_builtin_auth | HOSTNOSSL | REJECT | False (5 rows)Note
From version 26.2.0-2 and higher, theis_fallthrough_enabledflag is set toFalseby default. If you need to set it totrue, use thevertica.com/enable-fallthrough: "true"annotation.
Enable TLS when reviving the database
When you revive an existing database (initPolicy: Revive) from data files on communal storage, the database catalog already contains references to the TLS configuration established when the database was running.
Important
The catalog stored in communal storage expects the specific certificate authorities and TLS certificates previously used. You must provide the original TLS private key (tls.key), certificate (tls.crt), and CA certificate (ca.crt) as Kubernetes secrets or AWS Secrets Manager's secrets before you apply the revive CR. If the secrets or keys do not match, the database revive or node synchronization fails.
-
Ensure the original TLS secrets exist in the cluster, based on how the original database stored its certificates:
-
If the original VerticaDB CR used auto-generated secrets and
vertica.com/remove-tls-secret-on-vdb-delete: "false"(the default), the auto-generated secrets are preserved and can be referenced directly when reviving in the same Kubernetes namespace. If you are reviving to a different namespace, copy the secrets to the new namespace. -
If the original cluster used custom certificates in Kubernetes secrets, reference the secrets if reviving in the same namespace, or recreate the original TLS secrets from backup files if reviving on a new cluster or namespace:
# Recreate the original HTTPS TLS secret $ kubectl create secret generic vertica-db-https-tls-original \ --from-file=tls.key=./backup/https.key \ --from-file=tls.crt=./backup/https.crt \ --from-file=ca.crt=./backup/ca.crt # Recreate the original Client-Server TLS secret $ kubectl create secret generic vertica-db-clientserver-tls-original \ --from-file=tls.key=./backup/clientserver.key \ --from-file=tls.crt=./backup/clientserver.crt \ --from-file=ca.crt=./backup/ca.crt # Recreate the original Internode TLS secret $ kubectl create secret generic vertica-db-internode-tls-original \ --from-file=tls.key=./backup/internode.key \ --from-file=tls.crt=./backup/internode.crt \ --from-file=ca.crt=./backup/ca.crt -
If the original secrets were stored in AWS Secrets Manager, no extra steps are required; reuse them directly.
-
-
Define the revive VerticaDB CR manifest with
initPolicy: Revive, and reference the communal storage path and the original secrets:apiVersion: vertica.com/v1 kind: VerticaDB metadata: name: vertica-db annotations: vertica.com/tls-cache-duration: "86400" vertica.com/remove-tls-secret-on-vdb-delete: "false" vertica.com/ignore-cluster-lease: "true" spec: initPolicy: Revive dbName: vertdb # Must match the name of the database being revived licenseSecret: vertica-license passwordSecret: su-passwd communal: path: "s3://vertica-communal-storage/vertdb" # Existing non-empty communal path endpoint: "https://s3.amazonaws.com" credentialSecret: s3-creds region: us-east-1 subclusters: - name: primary size: 3 httpsNMATLS: enabled: true mode: TRY_VERIFY secret: vertica-db-https-tls-original clientServerTLS: enabled: true mode: TRY_VERIFY secret: vertica-db-clientserver-tls-original interNodeTLS: enabled: true mode: VERIFY_CA secret: vertica-db-internode-tls-original -
Apply the manifest:
$ kubectl apply -f verticadb-revive.yaml -
Monitor the operator reconciliation events:
$ kubectl describe vdb vertica-dbExpected events include:
Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for httpsNMA Normal TLSConfigurationSucceeded 3m verticadb-operator Successfully set HTTP tls config Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for clientServer Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Server tls config Normal TLSConfigurationStarted 2m verticadb-operator Starting to configure TLS for interNode Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Internode tls config -
Verify the generated Kubernetes secrets (if auto-generated):
$ kubectl get secrets -l app.kubernetes.io/name=verticaEnsure the revive operation completes and the database pod status transitions to
Ready.
Enable TLS after the database is created or revived
If a database was initialized or revived without TLS enabled (or TLS was disabled), you can enable TLS in place by updating the existing VerticaDB custom resource. The operator configures TLS and updates the NMA and HTTPS services without requiring a full cluster restart.
-
Edit the deployed custom resource:
$ kubectl edit vdb vertica-dbModify or add the TLS annotations and specification blocks, then save and exit the editor:
apiVersion: vertica.com/v1 kind: VerticaDB metadata: name: vertica-db ... spec: # ... existing database spec ... # Add TLS configurations (provide custom secrets or omit secret for auto-generation) clientServerTLS: enabled: true mode: TRY_VERIFY secret: custom-client-tls httpsNMATLS: enabled: true mode: TRY_VERIFY secret: custom-https-tls interNodeTLS: enabled: true mode: VERIFY_CA secret: custom-internode-tls -
Check the operator progress:
$ kubectl describe vdb vertica-dbYou will observe events confirming TLS configuration across components:
Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for httpsNMA Normal TLSConfigurationSucceeded 3m verticadb-operator Successfully set HTTP tls config Normal TLSConfigurationStarted 3m verticadb-operator Starting to configure TLS for clientServer Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Server tls config Normal TLSConfigurationStarted 2m verticadb-operator Starting to configure TLS for interNode Normal TLSConfigurationSucceeded 2m verticadb-operator Successfully set Internode tls config
Upgrade scenarios and considerations for TLS
When you upgrade your environment, special considerations apply depending on whether you are upgrading the VerticaDB operator or the database server.
VerticaDB operator upgrade
Upgrading from operator v2.2.0 or earlier
In VerticaDB operator version 2.2.0, the selector labels for StatefulSets were modified. Kubernetes selector labels are immutable, so the operator reconciler automatically deletes existing StatefulSets and recreates them with updated labels, which triggers a rolling restart of all database pods.
Important
If you are upgrading from operator version v2.2.0 or earlier, you must wait for the rolling restart of all database pods to finish before you configure or modify TLS settings. Attempting to configure TLS during an active rolling restart might cause reconciliation conflicts.After the rolling restart is complete, you can configure TLS as described in Enable TLS after the database is created or revived.
Upgrading from operator versions prior to v25.3.0 (pre-operator TLS support)
Operator-managed TLS (through CR parameters and Kubernetes secrets) was introduced in version 25.3.0-0. If you are upgrading from an operator version earlier than v25.3.0, consider the following scenarios:
Scenario 1: TLS was previously enabled manually in Vertica
If TLS was configured manually inside the database (for example, through ALTER TLS CONFIGURATION or custom SQL commands), existing TLS configurations remain active and untouched after the operator upgrade.
To manage TLS through the VerticaDB operator going forward, export your existing database certificate, private key, and CA certificate into Kubernetes secrets, and then edit the VerticaDB CR to reference them:
# 1. Create a Kubernetes secret with existing certificates
$ kubectl create secret generic existing-db-tls \
--from-file=tls.key=/path/to/existing.key \
--from-file=tls.crt=/path/to/existing.crt \
--from-file=ca.crt=/path/to/existing_ca.crt
# 2. Update the existing VerticaDB CR
...
spec:
clientServerTLS:
enabled: true
mode: TRY_VERIFY
secret: existing-db-tls
httpsNMATLS:
enabled: true
mode: TRY_VERIFY
secret: existing-db-tls
Scenario 2: TLS was not enabled
If TLS was not previously enabled, upgrade the operator to the latest version and configure TLS as described in Enable TLS after the database is created or revived.
Automated TLS spec migration in operator v25.4.0 and higher
Beginning in operator version 25.4.0, the operator automatically backfills and sets the explicit enabled boolean flags in spec.httpsNMATLS.enabled and spec.clientServerTLS.enabled during reconciliation.
If you are upgrading from an operator version earlier than 25.4.0 where the enabled fields are nil in the CR spec, the operator checks the vertica.com/enable-tls-auth annotation and automatically updates the CR spec to match:
- If
vertica.com/enable-tls-auth: "true"is set, the operator setsspec.httpsNMATLS.enabled: trueandspec.clientServerTLS.enabled: true. - If
vertica.com/enable-tls-auth: "false"(or not set), the operator sets both fields tofalse.
Vertica database server upgrade
When you upgrade the database server image (for example, updating spec.image in the VerticaDB CR), consider the following:
Configuration retention
All database configurations, catalog objects, and TLS settings configured in previous versions are preserved as is.
Automatic TLS fallthrough migration (upgrading from v26.2.0-1 or earlier to v26.2.0-2 or higher)
Database server version 26.2.0-2 introduced stricter built-in client authentication rules (HOSTNOSSL rejections) along with the vertica.com/enable-fallthrough annotation.
Note
If you have TLS configured through the VerticaDB operator for database server version 26.2.0-1 or earlier, the operator automatically sets the following:
...
metadata:
annotations:
vertica.com/enable-fallthrough: "true"
This ensures that existing client applications that rely on fallback or password authentication continue to connect without disruption.
Post-upgrade verification
After you complete the database upgrade, verify that the client authentication rules remain the same as they were before the upgrade:
=> SELECT auth_name, auth_host_type, auth_method, is_fallthrough_enabled
FROM client_auth
WHERE auth_name LIKE '%k8s%';
auth_name | auth_host_type | auth_method | is_fallthrough_enabled
----------------------------------+----------------+-------------+------------------------
k8s_remote_ipv4_tls_builtin_auth | HOSTSSL | TLS | True
k8s_remote_ipv6_tls_builtin_auth | HOSTSSL | TLS | True
k8s_local_tls_builtin_auth | LOCALSSL | TLS | True
(3 rows)
If you want to enforce strict TLS authentication (disallowing fallthrough to password authentication), edit the CR and set vertica.com/enable-fallthrough: "false".
Verify and validate
After TLS is configured using any of the use cases, verify the TLS status inside the database.
-
Connect to the database using SSL/TLS through vsql. The initial banner displays the negotiated SSL/TLS cipher and protocol:
$ vsql -h <VERTICA_SERVICE_IP_OR_HOST> -U dbadmin -w <PASSWORD>Example output:
Welcome to vsql, the Vertica Analytic Database interactive terminal. SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, protocol: TLSv1.2) -
Verify the database TLS configurations by querying the
tls_configurationssystem table:=> SELECT name, owner, certificate, ca_certificate, cipher_suites, mode FROM tls_configurations; name | owner | certificate | ca_certificate | cipher_suites | mode --------------+---------+---------------------+------------------------+---------------+------------ https | dbadmin | https_cert_0 | https_ca_cert_0 | | TRY_VERIFY server | dbadmin | server_cert_0 | server_ca_cert_0 | | TRY_VERIFY data_channel | dbadmin | data_channel_cert_0 | data_channel_ca_cert_0 | | VERIFY_CA LDAPLink | dbadmin | | | | DISABLE LDAPAuth | dbadmin | | | | DISABLE (5 rows) -
Verify the built-in client authentication rules. The operator automatically configures these TLS client authentication records:
=> SELECT auth_name, auth_host_type, auth_method, is_fallthrough_enabled FROM client_auth WHERE auth_name LIKE '%k8s%'; auth_name | auth_host_type | auth_method | is_fallthrough_enabled ----------------------------------------------+----------------+-------------+------------------------ k8s_remote_ipv4_tls_builtin_auth | HOSTSSL | TLS | False k8s_remote_ipv6_tls_builtin_auth | HOSTSSL | TLS | False k8s_local_tls_builtin_auth | LOCALSSL | TLS | False k8s_remote_ipv4_reject_non_tls_builtin_auth | HOSTNOSSL | REJECT | False k8s_remote_ipv6_reject_non_tls_builtin_auth | HOSTNOSSL | REJECT | False (5 rows) -
Verify the active secret mapping and cache duration to confirm that the database references the expected Kubernetes secret and cache configuration:
=> SELECT name, secret_name, secret_manager_config FROM certificates;Example output:
name | secret_name | secret_manager_config ------------------------+-----------------------------------+--------------------------------------------------------------------- https_ca_cert_0 | vertica-db-https-tls-lhj82 | {"data-key":"ca.crt","namespace":"vertica","cache-duration":86400} server_ca_cert_0 | vertica-db-clientserver-tls-j86v9 | {"data-key":"ca.crt","namespace":"vertica","cache-duration":86400} data_channel_ca_cert_0 | vertica-db-internode-tls-gbcx8 | {"data-key":"ca.crt","namespace":"vertica","cache-duration":86400} https_cert_0 | vertica-db-https-tls-lhj82 | {"data-key":"tls.crt","namespace":"vertica","cache-duration":86400} server_cert_0 | vertica-db-clientserver-tls-j86v9 | {"data-key":"tls.crt","namespace":"vertica","cache-duration":86400} data_channel_cert_0 | vertica-db-internode-tls-gbcx8 | {"data-key":"tls.crt","namespace":"vertica","cache-duration":86400} (6 rows)