Kerberos and SSL for Trino on Kubernetes
This article shows how to enable Kerberos authentication and SSL for a Trino cluster running in Kubernetes.
The configuration scenario provided below assumes that you have deployed a clean, non-secured Trino cluster on Kubernetes as described in the Install Trino on Kubernetes article.
Prerequisites
-
An ADH cluster (4.2.0 or later) is installed and kerberized.
-
Trino is deployed in Kubernetes according to the instruction.
-
SSL is enabled for the ADH cluster.
Configurations steps
Step 1. Install Kerberos operator
Install Kerberos operator and Kerberos config using Helm as described in the Install Kerberos operator on Kubernetes article. Sample Helm values files for installing Kerberos operator and Kerberos config are below.
replicas: 1
image:
registry: hub.arenadata.io (1)
repository: adc-enterprise/kerberos-operator (2)
pullPolicy: IfNotPresent
tag: <tag> (3)
serviceAccount:
create: true
automount: true
service:
type: ClusterIP
port: 8443
payloadNamespaces:
names: (4)
- kerberos-prod
- kerberos-staging
allowClusterRole: false (5)
deleteProtection: true (6)
avoidCreation: false (7)
terminationGracePeriodSeconds: 10
| 1 | Your image storage URL. |
| 2 | Path to the Kerberos operator image repository within your storage. |
| 3 | Version of the image that Kubernetes will use. |
| 4 | List of namespaces the operator manages. |
| 5 | Explicit opt-in for cluster-wide access. When true and payloadNamespaces.names is empty, the chart creates ClusterRole/ClusterRoleBinding for access to all namespaces. |
| 6 | Add the helm.sh/resource-policy: keep annotation to payload namespaces to prevent deletion on helm uninstall. |
| 7 | Skip creating namespace resources. Use only when namespaces already exist (e.g. created by Kerberos operator). |
ldapSecret:
enabled: true
provider: freeipa (1)
address: ldap://tsn-freeipa.ru-central1.internal (2)
adminUser: uid=admin,cn=users,cn=accounts,dc=ru-central1,dc=internal (3)
adminPassword: bigdata (4)
baseDN: cn=services,cn=accounts,dc=ru-central1,dc=internal (5)
ca: | <pem-certificate> (6)
kdcConfig:
labelSelector:
env: prod
libdefaults:
debug: 'false'
default_realm: RU-CENTRAL1.INTERNAL
dns_lookup_kdc: 'false'
dns_lookup_realm: 'false'
udp_preference_limit: '1'
realm: RU-CENTRAL1.INTERNAL (7)
domainRealm:
ru-central1.internal: RU-CENTRAL1.INTERNAL
realms:
RU-CENTRAL1.INTERNAL: |
kdc = tsn-freeipa.ru-central1.internal (8)
admin_server = tsn-freeipa.ru-central1.internal (9)
| 1 | Type of Kerberos provider. Can be one of the following: ad, samba, freeipa. |
| 2 | LDAP connection URL. |
| 3 | Administrator username. |
| 4 | Administrator password. |
| 5 | Search base. |
| 6 | CA certificate used to trust the LDAP server’s TLS certificate. |
| 7 | Kerberos realm. |
| 8 | Host with KDC available. |
| 9 | Host with kadmin available. |
The commands for installing Helm charts:
$ helm upgrade --install kerberos-operator oci://"$PRIVATE_REGISTRY"/adc-enterprise/charts/kerberos-operator --version <chart_version> -f ko-values.yaml --namespace kerberos-operator --create-namespace
$ helm upgrade --install kerberos-config oci://"$PRIVATE_REGISTRY"/adc-enterprise/charts/kerberos-config --version <chart_version> -f kc-values.yaml --namespace kerberos-operator --create-namespace
To verify the installation, use the commands:
$ kubectl get secrets -n kerberos-operator
$ kubectl get configmaps -n kerberos-operator
Sample output:
konstantin@ka-impala-k8s-1:~/trino/trino_kerberos$ kubectl get secrets -n kerberos-operator NAME TYPE DATA AGE kerberos-config-ldap-credentials krb5.arenadata.io/ldap-credentials 5 7s sh.helm.release.v1.kerberos-config.v1 helm.sh/release.v1 1 7s sh.helm.release.v1.kerberos-operator.v1 helm.sh/release.v1 1 48m konstantin@ka-impala-k8s-1:~/trino/trino_kerberos$ kubectl get configmaps -n kerberos-operator NAME DATA AGE kube-root-ca.crt 1 50m
Step 2. Create keytab and principals
-
Create the trino-keytab.yaml manifest file with Trino principals. For example:
apiVersion: krb5.arenadata.io/v1alpha1 kind: Keytab metadata: name: trino-keytab namespace: trino spec: items: - realm: RU-CENTRAL1.INTERNAL (1) labelSelector: env: prod principals: (2) - HTTP/trino-cloud.ru-central1.internal - trino/trino-cloud.ru-central1.internal rotation: interval: 720h checkInterval: 1h1 Kerberos realm. 2 Kerberos principals for accessing kerberized ADH services. -
Apply the configuration:
$ kubectl apply -f trino-keytab.yaml -
Verify the keytab creation using the commands:
$ kubectl get keytab -n trino $ kubectl get secret trino-keytab -n trinoSample output:
NAME ROTATION READY AGE NEXTROTATION trino-keytab RotationScheduled SecretGenerated 2d6h Next rotation required 2026-05-22T08:31:55Z
NAME TYPE DATA AGE trino-keytab krb5.arenadata.io/bundle 2 2d6h
Step 3. Update Kubernetes secrets
Your Trino installation already uses a Kubernetes secret with ADH configuration files to work with unprotected ADH services. To enable Kerberos/SSL and allow Trino to work with SSL-protected ADH services, adjust the ADH configuration files within the secret.
-
Adjust the iceberg.properties file. The updated file should include the following properties:
connector.name=iceberg hive.metastore.uri=thrift://ka-adh-2.ru-central1.internal:9083 (1) hive.metastore.authentication.type=KERBEROS hive.metastore.client.principal=trino/trino-cloud.ru-central1.internal@RU-CENTRAL1.INTERNAL (2) hive.metastore.client.keytab=/opt/trino-server/kerberos/keytab hive.metastore.service.principal=hive/_HOST@RU-CENTRAL1.INTERNAL hive.metastore.thrift.client.ssl.trust-certificate=/etc/ssl/truststore.jks (3) hive.metastore.thrift.client.ssl.trust-certificate-password=<password> (4) hive.metastore.thrift.impersonation.enabled=true fs.hadoop.enabled=True hive.hdfs.authentication.type=KERBEROS hive.hdfs.trino.principal=trino/trino-cloud.ru-central1.internal@RU-CENTRAL1.INTERNAL hive.hdfs.trino.keytab=/opt/trino-server/kerberos/keytab (4) hive.hdfs.wire-encryption.enabled=true hive.hdfs.impersonation.enabled=True hive.config.resources=/opt/trino-server/etc/catalog/core-site.xml hive.metastore.thrift.client.ssl.enabled=True1 Hive Metastore address in your ADH cluster. 2 Kerberos principal used by Trino when connecting to Hive Metastore. 3 The truststore to use when establishing an SSL/TLS connection to Hive Metastore. 4 Path to the Kerberos keytab file that Trino uses to authenticate to HDFS. -
Adjust the core-site.xml file. The updated file should include the following properties:
<?xml version="1.0"?> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://adh</value> </property> <property> <name>dfs.ha.namenodes.adh</name> <value>nn_ka-adh-1,nn_ka-adh-2</value> </property> <property> <name>dfs.namenode.rpc-address.adh.nn_ka-adh-1</name> <value>ka-adh-1.ru-central1.internal:8020</value> </property> <property> <name>dfs.namenode.rpc-address.adh.nn_ka-adh-2</name> <value>ka-adh-2.ru-central1.internal:8020</value> </property> <property> <name>dfs.nameservices</name> <value>adh</value> </property> <property> <name>dfs.client.failover.proxy.provider.adh</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider</value> </property> <property> <name>hadoop.proxyuser.trino.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.trino.hosts</name> <value>*</value> </property> <property> <name>hadoop.security.authentication</name> <value>kerberos</value> </property> <property> <name>dfs.datanode.kerberos.principal</name> <value>hdfs-datanode/_HOST@AD.RANGER-TEST</value> </property> <property> <name>dfs.journalnode.kerberos.principal</name> <value>hdfs-journalnode/_HOST@AD.RANGER-TEST</value> </property> <property> <name>dfs.namenode.kerberos.principal</name> <value>hdfs-namenode/_HOST@AD.RANGER-TEST</value> </property> <property> <name>dfs.web.authentication.kerberos.principal</name> <value>HTTP/_HOST@AD.RANGER-TEST</value> </property> </configuration>where
AD.RANGER-TESTis your Kerberos realm. -
If you use Trino with Ranger, update the Ranger configuration according to the instruction.
-
Re-create the Kubernetes secret:
$ kubectl delete secret <trino-config> -n <trino-cluster-ns> $ kubectl -n trino create secret generic <trino-config> --from-file=core-site.xml --from-file=iceberg.propertieswhere:
-
<trino-config>— name of the secret with Hadoop/Trino configs. -
<trino-cluster-ns>— namespace used by the Trino cluster.
-
-
Create a JKS truststore. This truststore should include all certificates from your ADH cluster. Create a secret for the truststore:
$ kubectl create secret generic ca-certs --namespace <trino-cluster-ns> --from-file=truststore.jks=/etc/ssl/truststore.jks -
Generate a certificate for Trino:
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout trino-cloud.ru-central1.internal.key \ -out trino-cloud.ru-central1.internal.crt \ -subj "/CN=trino-cloud.ru-central1.internal" -
Create a secret for incoming JDBC connections:
$ kubectl -n <trino-cluster-ns> create secret tls trino-tls-secret --cert=trino-cloud.ru-central1.internal.crt --key=trino-cloud.ru-central1.internal.key -
Configure your Ingress controller or load balancer to serve HTTPS using the TLS certificate stored in Kubernetes secret. For example, if Ingress is used, append the following parameters to your Ingress configuration file:
tls: - hosts: - trino-cloud.ru-central1.internal (1) secretName: trino-tls-secret1 TLS settings for requests arriving from the given host name. Then, apply the updated Ingress configuration, for example:
$ kubectl apply -f trino_ingress.yaml -n trino
Step 4. Update Trino cluster installation
-
Modify your Trino cluster configuration file (trino_cluster_values.yaml) by adding Kerberos/SSL parameters. The updated file should look as follows:
image: registry: "<registry>" repository: "<image>" tag: "<tag>" pullPolicy: Always useRanger: false configsSecretName: "trino-configs" kerberos: (1) realm: RU-CENTRAL1.INTERNAL hostname: "trino-cloud.ru-central1.internal" service: trino keytab: create: false secretName: "trino-keytab" labelSelector: env: prod worker: replicas: 2 resources: requests: cpu: 500m memory: 1Gi limits: cpu: "2" memory: 4Gi coordinator: replicas: 1 resources: requests: cpu: 500m memory: 1Gi limits: cpu: "2" memory: 4Gi ssl: (2) secretName: ca-certs trustStoreKey: truststore.jks1 Kerberos settings, including realm, hostname, and keytabs. 2 Trino certificate secret name. -
Update your Trino cluster installation:
$ helm upgrade --install trino-cluster oci://"$PRIVATE_REGISTRY"/adc-enterprise/charts/trino-cluster --version <version> -f trino_cluster_values.yaml --namespace <trino-cluster-ns> --create-namespace -
Delete old pods so that Trino operator creates new ones from an updated config:
$ kubectl delete pods --all -n <trino-cluster-ns> -
When Kubernetes creates new pods, check that all the pods are in the
Runningstate:$ kubectl delete pods -n <trino-cluster-ns> -l app.kubernetes.io/instance=trino-clusterThe expected output is:
NAME READY STATUS RESTARTS AGE ad-trino-cluster-coordinator-0 1/1 Running 0 4s ad-trino-cluster-worker-0 1/1 Running 0 17s ad-trino-cluster-worker-1 1/1 Running 0 4s
Step 5. Connect to Trino via JDBC
For external JDBC access to the Trino Coordinator, you need to expose the service using one of the supported publication methods, for example, through a load balancer or Ingress controller. All configurations related to exposing a service, including DNS, annotations, Ingress settings, TLS certificates, load balancing rules, and other platform-specific settings, should be specified according to your Kubernetes environment.
-
Get the external IP address of your load balancer or Ingress controller. For example:
NAME CLASS HOSTS ADDRESS PORTS AGE trino-ingress nginx trino-cloud.ru-central1.internal 10.92.43.92 80, 443 1d7h
Copy the external IP address (
10.92.43.92in this example) for the next steps. -
Connect to the Trino cluster over JDBC, for example, using DBeaver. For this, the JDBC connection string looks as follows:
jdbc:trino://<external-ip>:443?SSL=true&SSLTrustStorePath=<path>/truststore.jks&SSLTrustStorePassword=<password>&KerberosPrincipal=user&KerberosRemoteServiceName=HTTP&KerberosKeytabPath=<path>/user.keytab
where:
-
<external-ip>— Ingress/load balancer IP address. -
SSLTrustStorePath=<path>/truststore.jks— path to the truststore with certificates used by DBeaver. -
SSLTrustStorePassword=<password>— password for accessing the truststore. -
KerberosPrincipal=user— Kerberos principal used by DBeaver for the connection. -
KerberosRemoteServiceName=HTTP— service name used for the connection (specified in the Kubernetes keytab).
-