Install Trino on Kubernetes
This article describes how to deploy the ADH Trino service in Kubernetes.
Prerequisites
To deploy Trino on Kubernetes, you need:
-
A Kubernetes cluster 1.32 or later with access configured through
kubectl. -
Helm (3.8.0 or higher) — a package manager for Kubernetes that allows quick deployment of Docker images in Kubernetes.
-
Trino artifacts (Docker images and Helm charts) loaded to your private OCI registry. These artifacts can be found in offline packages, which can be requested from the Arenadata support team. To deploy Trino components on Kubernetes, you need to unpack the following images:
-
hub.arenadata.io/adh-enterprise/trino-docker:<version>
-
hub.arenadata.io/adc-enterprise/trino-operator:<version>
-
hub.arenadata.io/adc-enterprise/charts/trino-cluster:<version>
-
hub.arenadata.io/adc-enterprise/charts/trino-operator:<version>
-
-
An up-and-running ADH cluster (4.2.0 or later) with the following services:
-
Core configuration
-
ADPG
-
Zookeeper
-
HDFS
-
YARN
-
Hive
Trino runs outside the ADH cluster — in Kubernetes pods, and communicates with ADH over the network.
-
Deployment steps
The steps below describe how to install and configure Trino components on Kubernetes. Configurations related to providing external access, Ingress controllers, load balancers, DNS, and cloud annotations should be performed with respect to your Kubernetes infrastructure.
Step 1. Install Trino operator
-
Create trino_operator_values.yaml:
# Default values for ad-trino-operator. # This is a YAML-formatted file. # Declare variables to be passed into your templates. # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ replicas: 1 payloadNamespaces: (1) # Managed namespaces for Trino payload resources. names: - trino # Explicit opt-in for cluster-wide RBAC when payloadNamespaces.names is empty. # When false, chart rendering fails until namespaces are specified. allowClusterRole: false deleteProtection: false avoidCreation: false # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ image: registry: "<registry>" (2) repository: "<image>" (3) # This sets the pull policy for images. pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "<tag>" # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ pullSecret: (4) name: "" ## List of secrets to create for image pulling in all product namespaces credentials: {} # registry: private-docker-registry # username: user # password: pass # This is to override the chart name. nameOverride: "" fullnameOverride: "" # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ serviceAccount: # Automatically mount a ServiceAccount's API credentials? automount: true # Annotations to add to the service account annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: "" # This is for setting Kubernetes Annotations to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ podAnnotations: {} # This is for setting Kubernetes Labels to a Pod. # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ podLabels: {} podSecurityContext: {} # fsGroup: 2000 securityContext: readOnlyRootFilesystem: true privileged: false allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 65532 capabilities: drop: - ALL seccompProfile: type: RuntimeDefault # This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ service: # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types type: ClusterIP # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports port: 8443 resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi nodeSelector: {} tolerations: [] affinity: {} terminationGracePeriodSeconds: 101 List of namespaces for the operator to manage resources. 2 The address of your OCI registry to pull images from. 3 The name of repository in your registry. 4 Provide credentials to access your private Docker registry. -
Install Trino operator:
$ helm upgrade --install trino-operator oci://<registry-address>/adc-enterprise/charts/trino-operator:<version> --version <version> -f trino_operator_values.yaml --namespace trino-operator --create-namespacewhere
<registry-address>is the address of your OCI registry with loaded Trino Helm charts.Example output:
Release "trino-operator" does not exist. Installing it now. Pulled: hub.arenadata.io/adc-enterprise/charts/trino-operator:<version> Digest: sha256:0ad904dadfe7d8120864445e3f780f331061a7b66383aede35ca5db28a471a8a NAME: trino-operator LAST DEPLOYED: Wed May 6 14:06:11 2026 NAMESPACE: trino-operator STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES:
-
Verify the Trino operator installation using the command below:
$ kubectl get pods -n trino-operatorThe output:
NAME READY STATUS RESTARTS AGE trino-operator-7698f97987-ff6kz 1/1 Running 0 78s
Step 2. Create Kubernetes secrets with ADH configurations
To allow Trino in Kubernetes to communicate with your ADH cluster, it is necessary to provide ADH configurations to every Kubernetes pod. A way to do this is through Kubernetes secrets. In this case, ADH configuration files will be available in every pod at /opt/trino-server/etc/catalog/.
For this:
-
Create the core-site.xml and iceberg.properties configuration files, using the following templates. Use configuration values from your ADH cluster.
core-site.xml<?xml version="1.0"?> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://adh</value> (1) </property> <property> <name>hadoop.security.authentication</name> <value>simple</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> </configuration>1 Replace with a value from your ADH cluster’s /etc/hadoop/conf/core-site.xml. iceberg.propertiesconnector.name=iceberg hive.metastore.uri=thrift://ka-adh-2.ru-central1.internal:9083 (1) hive.metastore.authentication.type=NONE hive.metastore.thrift.impersonation.enabled=true fs.hadoop.enabled=True hive.hdfs.authentication.type=NONE 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=False1 Specify your Hive Metastore address. For this, use the hive.metastore.urisproperty from your ADH cluster’s /etc/hive/conf/hive-site.xml.TIPYour ADH cluster’s configuration files can be found on cluster hosts at /etc/hadoop/conf/ and /etc/trino/conf/catalog/. -
Create secrets:
$ kubectl -n trino create secret generic trino-configs --from-file=core-site.xml --from-file=iceberg.propertiesVerify the secrets:
$ kubectl get secrets -n trinoThe output:
NAME TYPE DATA AGE trino-configs Opaque 2 16m
Step 3. Install Trino cluster
-
Create trino_cluster_values.yaml:
image: registry: "<registry>" (1) repository: "<image>" (2) tag: "<tag>" pullPolicy: Always pullSecret: (3) name: "" ## List of secrets to create for image pulling in all product namespaces credentials: {} # registry: private-docker-registry # username: user # password: pass useRanger: false configsSecretName: "trino-configs" securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000 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: 4Gi1 The address of your OCI registry to pull images from. 2 The name of repository in your registry. 3 Provide credentials to access your private Docker registry. -
Install Trino cluster:
$ helm upgrade --install trino-cluster oci://<registry-address>/adc-enterprise/charts/trino-cluster:<version> --version <version> -f trino_cluster_values.yaml --namespace trino --create-namespacewhere
<registry-address>is the address of your registry with Helm charts for Trino.Example output:
Release "trino-cluster" does not exist. Installing it now. Pulled: hub.arenadata.io/adc-enterprise/charts/trino-cluster:<version> Digest: sha256:bb3a10be127d8c9937d615f41f31393251d59753480f2a02ec6d874200c0a354 NAME: trino-cluster LAST DEPLOYED: Fri May 8 15:06:24 2026 NAMESPACE: trino STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None
-
Verify the installation using the commands below:
$ kubectl get clusters.trino.arenadata.io -n trino $ kubectl get pods -n trinoThe output:
kubectl get clusters.trino.arenadata.io -n trino NAME READY AGE trino-cluster True 4m41s konstantin@ka-trino-k8s-1:~/trino$ kubectl get pods -n trino NAME READY STATUS RESTARTS AGE trino-cluster-coordinator-0 1/1 Running 0 4m49s trino-cluster-worker-0 1/1 Running 0 4m49s trino-cluster-worker-1 1/1 Running 0 4m20s
Ensure that the Trino cluster pods are in the
Runningstate.
|
To inspect Trino logs within a pod, use the following command:
|
Step 4. Allow JDBC connection to Trino
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, must 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 ka-trino-k8s-1.ru-central1.internal 10.92.41.95 80 57s
Copy the external IP address (
10.92.41.95in 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>:80
where
<external-ip>is the Ingress/load balancer IP address from the previous step. -
Once connected, verify the Trino cluster operability:
SHOW CATALOGS;The output:
Catalog | ----------+ iceberg | system |
Step 5. Provide access to Trino web UI
To access Trino web interface, 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, load balancing rules, and other platform-specific settings, must 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 ka-trino-k8s-1.ru-central1.internal 10.92.41.95 80 42m
Copy the external IP address for the next steps.
-
Add a line to your /etc/hosts:
<external-ip> ka-trino-k8s-1.ru-central1.internalwhere
<external-ip>is the Ingress/load balancer IP address from the previous step. -
Open Trino Coordinator web UI in your browser, using the URL: http://ka-trino-k8s-1.ru-central1.internal:80.
Trino web UI
Delete instances
|
IMPORTANT
Delete the operator only after all the resources it manages have been deleted. |
To delete the Trino cluster, run the command below:
$ helm uninstall trino-cluster --namespace trino
To delete the Trino operator, run the command below:
$ helm uninstall trino-operator --namespace trino-operator
To delete the Trino cluster CRD, run the command below:
$ kubectl delete crd clusters.trino.arenadata.io