Настройка LDAP и SSL для Trino в Kubernetes с помощью CLI

Требования

  • Установленный кластер ADH версии 4.2.0 или более поздней.

  • Кластер Trino, развернутый в Kubernetes согласно инструкции.

  • SSL активирован для кластера ADH. Данный шаг не является обязательным, но рекомендуется в целях безопасности. Дальнейшие шаги предполагают выполнение данного этапа.

Для доступа к веб-интерфейсу Trino и JDBC-соединений сгенерируйте сертификат для Ingress:

$ 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"

Для web TLS необходимо создать keystore со сгенерированным сертификатом и приватным ключом:

$ openssl pkcs12 -export -in trino-cloud.ru-central1.internal.crt -inkey trino-cloud.ru-central1.internal.key -out keystore.p12 -name trino-cloud.ru-central1.internal
ПРИМЕЧАНИЕ
Методы аутентификации Kerberos и LDAP являются взаимоисключающими.

Шаг 1. Обновление конфигурации кластера Trino

  1. Подготовьте новую версию файла hadoop_conf.yaml с активированным SSL:

    hadoop_conf.yaml
    • HDFS

    • S3

    sites:
      core:
        fs.defaultFS: hdfs://adh
        hadoop.security.authentication: simple
        dfs.client.failover.proxy.provider.adh: org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider
        dfs.ha.namenodes.adh: nn_tsn-adh-k8s-1,nn_tsn-adh-k8s-3
        dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-1: tsn-adh-k8s-1.ru-central1.internal:8020
        dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-3: tsn-adh-k8s-3.ru-central1.internal:8020
        dfs.nameservices: adh
        hadoop.ssl.enabled: true
      hdfs:
        dfs.client.read.shortcircuit: false
      ozone:
        ozone.om.address.adh.om_tsn-adh-k8s-1: tsn-adh-k8s-1.ru-central1.internal:9862
        ozone.om.address.adh.om_tsn-adh-k8s-2: tsn-adh-k8s-2.ru-central1.internal:9862
        ozone.om.address.adh.om_tsn-adh-k8s-3: tsn-adh-k8s-3.ru-central1.internal:9862
        ozone.om.nodes.adh: om_tsn-adh-k8s-1,om_tsn-adh-k8s-2,om_tsn-adh-k8s-3
        ozone.om.service.ids: adhom
      hive:
        hive.metastore.sasl.enabled: false
        hive.metastore.uris: thrift://tsn-adh-k8s-1.ru-central1.internal:9083
        metastore.use.SSL: true
    sites:
      core:
        fs.defaultFS: s3a://demo-s3
        fs.s3a.impl: org.apache.hadoop.fs.s3a.S3AFileSystem
        fs.s3a.access.key: p.petrov@RU-CENTRAL1.INTERNAL
        fs.s3a.secret.key: 3ab197f82fac43374519b4ad3015a76c778acf51897cf73f409ecba827e64255
      hive:
        hive.metastore.uris: thrift://hms-adh-nia-01.ru-central1.internal:9083
        metastore.use.SSL: true
        fs.s3a.endpoint: http://adh-ctrl-nia-02.ru-central1.internal:9879
        fs.s3a.path.style.access: true
        hive.metastore.warehouse.dir: s3a://demo-s3/apps/hive/warehouse
  2. Инициализируйте кластер Trino:

    $ ./adc init --trino-cluster --hadoop-file hadoop_conf.yaml -o trino-cluster.yaml

    Данная операция создаст файл trino-cluster.yaml с шаблоном конфигурации.

  3. Отредактируйте конфигурационный файл, добавив блоки настроек LDAP, SSL и web TLS:

    trino-cluster.yaml
    • HDFS

    • S3

    apiVersion: adc.arenadata.io/v1alpha1
    kind: TrinoCluster
    metadata:
      name: trino
      namespace: trino (1)
    spec:
      image: hub.arenadata.io/adc-enterprise/trino:<tag> (2)
    
      ## Image pull secret for a private registry.
      ## Set 'externalSecretName' to reference an existing Secret,
      ## or set 'credentials' and optionally 'secretName' to let the CLI create one.
      #imagePullSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-registry-secret
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-registry-secret
      #
      #  #credentials:
      #  #  registry: registry.example.com
      #  #  username: user
      #  #  password: pass
    
      hadoop: (3)
        core:
          dfs.client.failover.proxy.provider.adh: org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider
          dfs.ha.namenodes.adh: nn_tsn-adh-k8s-1,nn_tsn-adh-k8s-3
          dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-1: tsn-adh-k8s-1.ru-central1.internal:8020
          dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-3: tsn-adh-k8s-3.ru-central1.internal:8020
          dfs.nameservices: adh
          fs.defaultFS: hdfs://adh
          fs.s3a.aws.credentials.provider: org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
          hadoop.proxyuser.trino.groups: '*'
          hadoop.proxyuser.trino.hosts: '*'
          hadoop.security.authentication: simple
          hadoop.ssl.enabled: "true"
        hdfs:
          dfs.client.read.shortcircuit: "false"
        hive:
          hive.metastore.sasl.enabled: "false"
          hive.metastore.uris: thrift://tsn-adh-k8s-1.ru-central1.internal:9083
          metastore.use.SSL: "true"
        ozone:
          ozone.om.address.adh.om_tsn-adh-k8s-1: tsn-adh-k8s-1.ru-central1.internal:9862
          ozone.om.address.adh.om_tsn-adh-k8s-2: tsn-adh-k8s-2.ru-central1.internal:9862
          ozone.om.address.adh.om_tsn-adh-k8s-3: tsn-adh-k8s-3.ru-central1.internal:9862
          ozone.om.nodes.adh: om_tsn-adh-k8s-1,om_tsn-adh-k8s-2,om_tsn-adh-k8s-3
          ozone.om.service.ids: adhom
    
      ## Kerberos configuration for authentication.
      #kerberos:
      #  realm: EXAMPLE.COM
      #
      #  # Service name in the Kerberos principal. Defaults to the product name.
      #  service: trino
      #
      #  # Hostname in the Kerberos principal.
      #  # Required for a fixed service principal; leave it empty only to derive one principal per pod from the cluster domain.
      #  hostname: kerberos.example.com
      #  keytab:
      #    # true - kerberos-operator creates the keytab Secret.
      #    # false (default) - reference an existing keytab Secret with name keytab.secretName.
      #    create: false
      #
      #    # Name of the keytab Secret.
      #    # Optional when create: true - names the generated Secret (default: <name>-keytab).
      #    # Required when create: false - must reference an existing Secret.
      #    secretName: kerberos-secret
      #
      #    # Label selector for the Pod that generates the keytab.
      #    # Required when create: true; ignored when create: false.
      #    labelSelector:
      #      env: prod
      #    #additionalPrincipals:
      #    #  - HTTP/kerberos.example.com
      #
      #    rotation:
      #      interval: 24h
      #      checkInterval: 1h
    
      ## LDAP authentication configuration.
      ## Uncomment and fill url and userBindPattern.
      ## For ldaps:// URLs the ssl: or ca: section must also be configured (depends on product)
      ldap:
      #  # LDAP service url.
        url: ldaps://ad01.adsw.io:636 (4)
      #
      #  # LDAP user Bind pattern.
        userBindPattern: CN=${USER},OU=kerberos,OU=adh,DC=ad,DC=ranger-test (5)
    
      ## Ranger plugin configuration.
      ## Uncomment and fill the lines below. adc apply derives the rest.
      #ranger:
      #  # fill ranger.plugin.trino.policy.rest.url below with Ranger endpoint, e.g. https://adps-adc.ru-central1.internal:6182
      #  # fill ranger.plugin.trino.service.name below with Ranger service name you want to use for product, e.g. adc_trino_id_1
      #  security:
      #    ranger.plugin.trino.policy.rest.url: ""
      #    ranger.plugin.trino.service.name: ""
      #
      #  # fill xasecure.audit.destination.solr.zookeepers below with Zookeepers endpoints to resolve solr service, e.g. adps-adc.ru-central1.internal:2181/Arenadata.Hadoop-2.solr.server
      #  audit:
      #    xasecure.audit.destination.solr.zookeepers: ""
      #
      #  # Local Ranger files 'adc apply' writes into the configs Secret.
      #  # Relative paths are resolved against the config file.
      #  files:
      #    jceksStorePath: /path/to/ranger.jceks
    
      ## Java KeyStore/TrustStore certificate configuration.
      ## Set externalSecretName to reference an existing Secret,
      ## or set files and optional secretName to have ADC create it.
      ssl: (6)
      #  ## Name of the Secret containing Java keystores.
        secretName: ssl-secret
      #  externalSecretName: existing-ssl-secret
      #
      #  # Key in the Secret containing the truststore file.
        trustStoreKey: truststore.jks
      #
      #  ## Password for the truststore (optional).
        trustStorePassword: bigdata
      #
      #  ## Key in the Secret containing the keystore file (optional).
      #  #keyStoreKey: keystore.jks
      #
      #  ## Password for the keystore (optional).
      #  #keyStorePassword: bigdata
      #
      #  ## Alias of the key entry inside the keystore. Required by the Trino JMX exporter when scrape TLS is enabled.
      #  #keyStoreAlias: trino
      #
      #  ## Local files 'adc apply' puts into the Secret named by ssl.secretName.
      #  ## Relative paths are resolved against the config file.
        files:
          trustStorePath: /etc/ssl/truststore.jks
      #  #  #keyStorePath: /path/to/keystore.jks
    
      ## Use an external complete configs Secret instead of the one rendered by ADC.
      #configsSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-trino-configs
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-trino-configs
    
      coordinator:
        replicas: 1
        #resources:
        #  limits:
        #    cpu: 500m
        #    memory: 4Gi
        #  requests:
        #    cpu: 250m
        #    memory: 512Mi
    
        ## Component arguments. Key-value pairs passed to the component configuration.
        #args:
        #  http-server.http.port: "8080"
    
        ## Environment variables passed to the component container.
        #envs:
        #  - name: JAVA_TOOL_OPTIONS
        #    value: |-
        #      -Djavax.net.ssl.trustStore=/etc/ssl/truststore.jks
        #      -Djavax.net.ssl.trustStorePassword=bigdata
      worker:
        replicas: 1
        #resources:
        #  limits:
        #    cpu: 500m
        #    memory: 4Gi
        #  requests:
        #    cpu: 250m
        #    memory: 512Mi
    
        ## Component arguments. Key-value pairs passed to the component configuration.
        #args:
        #  http-server.http.port: "8080"
    
        ## Environment variables passed to the component container.
        #envs:
        #  - name: JAVA_TOOL_OPTIONS
        #    value: |-
        #      -Djavax.net.ssl.trustStore=/etc/ssl/truststore.jks
        #      -Djavax.net.ssl.trustStorePassword=bigdata
    
      ## Trino catalogs (one entry per .properties file).
      ## adc apply derives Kerberos/SSL fields for iceberg catalogs from the surrounding cluster config.
      catalogs: (7)
        iceberg.properties:
          connector.name: iceberg
          fs.hadoop.enabled: "true"
          hive.config.resources: /opt/trino-server/etc/catalog/core-site.xml
          hive.hdfs.impersonation.enabled: "true"
          hive.metastore.thrift.client.ssl.enabled: "true"
          hive.metastore.thrift.client.ssl.trust-certificate: /etc/ssl/truststore.jks
          hive.metastore.thrift.client.ssl.trust-certificate-password: bigdata
          hive.metastore.thrift.impersonation.enabled: "true"
          hive.metastore.uri: thrift://tsn-adh-k8s-1.ru-central1.internal:9083
    
      ## Monitoring configuration.
      #monitoring:
      #  # Enables Prometheus metrics export from this product's pods.
      #  exportMetrics: true
    
      ## HTTPS on the Trino coordinator web endpoint.
      ## Set externalSecretName to reference a keystore Secret,
      ## or set files and optional secretName to have ADC create it.
      webTLS: (8)
        secretName: trino-web-tls
      #  externalSecretName: existing-trino-web-tls
        keystoreKey: keystore.p12
        keystorePassword: bigdata
      #
      #  ## Local keystore 'adc apply' puts into the Secret named by webTLS.secretName.
      #  ## A relative path is resolved against the config file.
        files:
          keystorePath: ./keystore.p12
    
      ## Controls whether Secret/ConfigMap changes restart pods.
      ## Set enabled: false to update referenced Secrets without restarting
      ## the workload; pods keep running the previous configuration until
      ## the policy is re-enabled. Defaults to enabled.
      #configurationRollout:
      #  enabled: false
    1 Пространство имен, используемое кластером Trino.
    2 Настройки для загрузки образа кластера Trino.
    3 Настройки Hadoop, взятые из ранее созданного файла hadoop_conf.yaml.
    4 URL для подключения к LDAP.
    5 Шаблон имени пользователя для поиска.
    6 Настройки SSL.
    7 Настройки каталога.
    8 Настройки web TLS.
    apiVersion: adc.arenadata.io/v1alpha1
    kind: TrinoCluster
    metadata:
      name: trino
      namespace: trino (1)
    spec:
      image: hub.arenadata.io/adc-enterprise/trino:<tag> (2)
    
      ## Image pull secret for a private registry.
      ## Set 'externalSecretName' to reference an existing Secret,
      ## or set 'credentials' and optionally 'secretName' to let the CLI create one.
      #imagePullSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-registry-secret
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-registry-secret
      #
      #  #credentials:
      #  #  registry: registry.example.com
      #  #  username: user
      #  #  password: pass
    
      hadoop: (3)
        core:
          fs.defaultFS: s3a://demo-s3
          fs.s3a.access.key: p.petrov@RU-CENTRAL1.INTERNAL
          fs.s3a.aws.credentials.provider: org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
          fs.s3a.impl: org.apache.hadoop.fs.s3a.S3AFileSystem
          fs.s3a.secret.key: 3ab197f82fac43374519b4ad3015a76c778acf51897cf73f409ecba827e64255
          hadoop.proxyuser.trino.groups: '*'
          hadoop.proxyuser.trino.hosts: '*'
        hive:
          fs.s3a.endpoint: http://adh-ctrl-nia-02.ru-central1.internal:9879
          fs.s3a.path.style.access: "true"
          hive.metastore.uris: thrift://hms-adh-nia-01.ru-central1.internal:9083
          hive.metastore.warehouse.dir: s3a://demo-s3/apps/hive/warehouse
          metastore.use.SSL: "true"
    
      ## Kerberos configuration for authentication.
      #kerberos:
      #  realm: EXAMPLE.COM
      #
      #  # Service name in the Kerberos principal. Defaults to the product name.
      #  service: trino
      #
      #  # Hostname in the Kerberos principal.
      #  # Required for a fixed service principal; leave it empty only to derive one principal per pod from the cluster domain.
      #  hostname: kerberos.example.com
      #  keytab:
      #    # true - kerberos-operator creates the keytab Secret.
      #    # false (default) - reference an existing keytab Secret with name keytab.secretName.
      #    create: false
      #
      #    # Name of the keytab Secret.
      #    # Optional when create: true - names the generated Secret (default: <name>-keytab).
      #    # Required when create: false - must reference an existing Secret.
      #    secretName: kerberos-secret
      #
      #    # Label selector for the Pod that generates the keytab.
      #    # Required when create: true; ignored when create: false.
      #    labelSelector:
      #      env: prod
      #    #additionalPrincipals:
      #    #  - HTTP/kerberos.example.com
      #
      #    rotation:
      #      interval: 24h
      #      checkInterval: 1h
    
      ## LDAP authentication configuration.
      ## Uncomment and fill url and userBindPattern.
      ## For ldaps:// URLs the ssl: or ca: section must also be configured (depends on product)
      ldap:
      #  # LDAP service url.
        url: ldaps://ad01.adsw.io:636 (4)
      #
      #  # LDAP user Bind pattern.
        userBindPattern: CN=${USER},OU=kerberos,OU=adh,DC=ad,DC=ranger-test (5)
    
      ## Ranger plugin configuration.
      ## Uncomment and fill the lines below. adc apply derives the rest.
      #ranger:
      #  # fill ranger.plugin.trino.policy.rest.url below with Ranger endpoint, e.g. https://adps-adc.ru-central1.internal:6182
      #  # fill ranger.plugin.trino.service.name below with Ranger service name you want to use for product, e.g. adc_trino_id_1
      #  security:
      #    ranger.plugin.trino.policy.rest.url: ""
      #    ranger.plugin.trino.service.name: ""
      #
      #  # fill xasecure.audit.destination.solr.zookeepers below with Zookeepers endpoints to resolve solr service, e.g. adps-adc.ru-central1.internal:2181/Arenadata.Hadoop-2.solr.server
      #  audit:
      #    xasecure.audit.destination.solr.zookeepers: ""
      #
      #  # Local Ranger files 'adc apply' writes into the configs Secret.
      #  # Relative paths are resolved against the config file.
      #  files:
      #    jceksStorePath: /path/to/ranger.jceks
    
      ## Java KeyStore/TrustStore certificate configuration.
      ## Set externalSecretName to reference an existing Secret,
      ## or set files and optional secretName to have ADC create it.
      ssl: (6)
      #  ## Name of the Secret containing Java keystores.
        secretName: ssl-secret
      #  externalSecretName: existing-ssl-secret
      #
      #  # Key in the Secret containing the truststore file.
        trustStoreKey: truststore.jks
      #
      #  ## Password for the truststore (optional).
        trustStorePassword: bigdata
      #
      #  ## Key in the Secret containing the keystore file (optional).
      #  #keyStoreKey: keystore.jks
      #
      #  ## Password for the keystore (optional).
      #  #keyStorePassword: bigdata
      #
      #  ## Alias of the key entry inside the keystore. Required by the Trino JMX exporter when scrape TLS is enabled.
      #  #keyStoreAlias: trino
      #
      #  ## Local files 'adc apply' puts into the Secret named by ssl.secretName.
      #  ## Relative paths are resolved against the config file.
        files:
          trustStorePath: /etc/ssl/truststore.jks
      #  #  #keyStorePath: /path/to/keystore.jks
    
      ## Use an external complete configs Secret instead of the one rendered by ADC.
      #configsSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-trino-configs
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-trino-configs
    
      coordinator:
        replicas: 1
        #resources:
        #  limits:
        #    cpu: 500m
        #    memory: 4Gi
        #  requests:
        #    cpu: 250m
        #    memory: 512Mi
    
        ## Component arguments. Key-value pairs passed to the component configuration.
        #args:
        #  http-server.http.port: "8080"
    
        ## Environment variables passed to the component container.
        #envs:
        #  - name: JAVA_TOOL_OPTIONS
        #    value: |-
        #      -Djavax.net.ssl.trustStore=/etc/ssl/truststore.jks
        #      -Djavax.net.ssl.trustStorePassword=bigdata
      worker:
        replicas: 1
        #resources:
        #  limits:
        #    cpu: 500m
        #    memory: 4Gi
        #  requests:
        #    cpu: 250m
        #    memory: 512Mi
    
        ## Component arguments. Key-value pairs passed to the component configuration.
        #args:
        #  http-server.http.port: "8080"
    
        ## Environment variables passed to the component container.
        #envs:
        #  - name: JAVA_TOOL_OPTIONS
        #    value: |-
        #      -Djavax.net.ssl.trustStore=/etc/ssl/truststore.jks
        #      -Djavax.net.ssl.trustStorePassword=bigdata
    
      ## Trino catalogs (one entry per .properties file).
      ## adc apply derives Kerberos/SSL fields for iceberg catalogs from the surrounding cluster config.
      catalogs: (7)
        iceberg.properties:
          connector.name: iceberg
          fs.hadoop.enabled: "true"
          hive.config.resources: /opt/trino-server/etc/catalog/core-site.xml
          hive.hdfs.impersonation.enabled: "true"
          hive.metastore.thrift.client.ssl.enabled: "true"
          hive.metastore.thrift.client.ssl.trust-certificate: /etc/ssl/truststore.jks
          hive.metastore.thrift.client.ssl.trust-certificate-password: bigdata
          hive.metastore.thrift.impersonation.enabled: "true"
          hive.metastore.uri: thrift://hms-adh-nia-01.ru-central1.internal:9083
    
      ## Monitoring configuration.
      #monitoring:
      #  # Enables Prometheus metrics export from this product's pods.
      #  exportMetrics: true
    
      ## HTTPS on the Trino coordinator web endpoint.
      ## Set externalSecretName to reference a keystore Secret,
      ## or set files and optional secretName to have ADC create it.
      webTLS: (8)
        secretName: trino-web-tls
      #  externalSecretName: existing-trino-web-tls
        keystoreKey: keystore.p12
        keystorePassword: bigdata
      #
      #  ## Local keystore 'adc apply' puts into the Secret named by webTLS.secretName.
      #  ## A relative path is resolved against the config file.
        files:
          keystorePath: ./keystore.p12
    
      ## Controls whether Secret/ConfigMap changes restart pods.
      ## Set enabled: false to update referenced Secrets without restarting
      ## the workload; pods keep running the previous configuration until
      ## the policy is re-enabled. Defaults to enabled.
      #configurationRollout:
      #  enabled: false
    1 Пространство имен, используемое кластером Trino.
    2 Настройки для загрузки образа кластера Trino.
    3 Настройки Hadoop, взятые из ранее созданного файла hadoop_conf.yaml.
    4 URL для подключения к LDAP.
    5 Шаблон имени пользователя для поиска.
    6 Настройки SSL.
    7 Настройки каталога.
    8 Настройки web TLS.
  4. Если вы используете Trino с Ranger, обновите настройки Ranger согласно инструкции.

  5. Примените конфигурацию и разверните кластер Trino:

    $ ./adc apply -f trino-cluster.yaml

    Ожидаемый вывод содержит сообщение с подтверждением успеха:

    time="20260518133858UTC" level="info" msg="cluster trino applied to namespace trino"
  6. Удалите старые поды кластера, чтобы оператор Trino создал новые с обновленной конфигурацией:

    $ kubectl delete pods -n <trino-cluster-ns> -l app.kubernetes.io/instance=trino-cluster
  7. Проверьте работоспособность подов кластера Trino:

    $ kubectl get pods -n trino

    Ожидаемый вывод должен быть похож на следующий:

    trino-cluster-coordinator-0   1/1     Running   0          5s
    trino-cluster-worker-0        1/1     Running   0          5s

Шаг 2. Проверка JDBC-соединения

  1. Подключитесь к кластеру Trino через JDBC, например, с помощью DBeaver. После активации LDAP и SSL строка подключения JDBC имеет следующий вид:

    jdbc:trino://trino-cloud.ru-central1.internal:443?SSL=true&SSLTrustStorePath=<SSLTrustStorePath>&SSLTrustStorePassword=<SSLTrustStorePassword>&user=<USER>&password=<PWD>

    где:

    • <USER> — имя пользователя в LDAP.

    • <PWD> — пароль пользователя в LDAP.

    • <SSLTrustStorePath> — путь к truststore-файлу с сертификатами, который использует DBeaver.

    • <SSLTrustStorePassword> — пароль для доступа к truststore-файлу.

  2. Установив подключение, выполните тестовую команду для проверки работоспособности кластера:

    SHOW CATALOGS;

    Ожидаемый вывод:

    Catalog   |
    ----------+
    iceberg   |
    system    |
Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней