Kerberos и SSL для Trino в Kubernetes

В данной статье описан процесс подключения Kerberos-аутентификации и SSL для кластера Trino, развернутом в Kubernetes.

Описанный в статье сценарий настройки предполагает наличие чистого незащищенного Trino-кластера в Kubernetes, развернутого в соответствии с инструкциями из статьи Установка Trino в Kubernetes.

Требования

Процедура настройки

Шаг 1. Установка оператора Kerberos

Установите оператор Kerberos и Kerberos config с помощью Helm, как описано в статье Установка оператора Kerberos в Kubernetes. Ниже приведены примеры Helm values-файлов для установки оператора Kerberos и Kerberos config.

ko-values.yaml
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 URL хранилища образов.
2 Путь к репозиторию образа Kerberos-оператора в хранилище.
3 Версия образа, которая будет использована Kubernetes.
4 Список пространств имен, доступных для Kerberos-оператора.
5 Явное согласие на предоставление доступа ко всему кластеру. Когда значение параметра true, а payloadNamespaces.names пусто, чарт создает ClusterRole/ClusterRoleBinding для доступа ко всем пространствам имен.
6 Флаг, определяющий добавлять ли аннотацию helm.sh/resource-policy: keep к пространству имен, предотвращающую удаление командой helm uninstall.
7 Флаг, определяющий пропускать ли шаг создания пространства имен. Следует использовать только если заранее известно о наличии пространства имен (например, созданного оператором Kerberos).
kc-values.yaml
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 Тип провайдера Kerberos. Может быть одним из следующих значений: ad, samba, freeipa.
2 URL для подключения к LDAP.
3 Имя пользователя с правами администратора.
4 Пароль администратора.
5 База поиска.
6 CA-сертификат для доверия с TLS-сертификатом сервера LDAP.
7 Kerberos-реалм (realm).
8 Хост с доступным KDC.
9 Хост с доступным kadmin.

Команды для установки Helm-чартов:

$ 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

Для проверки установки используйте команды:

$ kubectl get secrets -n kerberos-operator
$ kubectl get configmaps -n kerberos-operator

Пример вывода:

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

Шаг 2. Создание keytab-ресурса и принципалов

  1. Создайте манифест-файл trino-keytab.yaml с принципалами Trino. Например:

    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: 1h
    1 Kerberos реалм (realm).
    2 Kerberos-принципалы для доступа к керберизированным сервисам ADH.
  2. Обновите конфигурацию:

    $ kubectl apply -f trino-keytab.yaml
  3. Проверьте создание keytab-ресурса с помощью команд:

    $ kubectl get keytab -n trino
    $ kubectl get secret trino-keytab -n trino

    Пример вывода:

    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

Шаг 3. Обновление секретов Kubernetes

Развернутый ранее кластер Trino использует секрет Kubernetes c конфигурационными файлами ADH для взаимодействия с незащищенными ADH-сервисами. Для включения Kerberos/SSL и обеспечения взаимодействия Trino с сервисами ADH, защищенными SSL, необходимо изменить конфигурационные файлы ADH в секретах Kubernetes.

  1. Измените файл iceberg.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=True
    1 Адрес Hive Metastore вашего ADH-кластера.
    2 Принципал Kerberos, использующийся Trino для подключения к Hive Metastore.
    3 Truststore-файл, использующийся для установки SSL/TLS соединения с Hive Metastore.
    4 Путь к Kerberos keytab-файлу, который используется Trino для аутентификации в HDFS.
  2. Измените файл core-site.xml. Файл должен содержать следующие свойства:

    <?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>

    где AD.RANGER-TEST — ваш Kerberos realm.

  3. Если вы используете Trino с Ranger, обновите настройки Ranger согласно инструкции.

  4. Пересоздайте секрет Kubernetes:

    $ 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.properties

    где:

    • <trino-config> — имя секрета с конфигурацией Hadoop/Trino.

    • <trino-cluster-ns> — пространство имен, используемое кластером Trino.

  5. Создайте JKS-файл хранилища сертификатов. Данный truststore-файл должен содержать все сертификаты вашего ADH-кластера. Создайте секрет для truststore-файла:

    $ kubectl create secret generic ca-certs --namespace <trino-cluster-ns> --from-file=truststore.jks=/etc/ssl/truststore.jks
  6. Сгенерируйте сертификат для 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"
  7. Создайте секрет для входящих JDBC-соединений:

    $ 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
  8. Настройте ваш Ingress-контроллер или балансировщик нагрузки для работы по протоколу HTTPS с использованием TLS-сертификата, хранящегося в секрете Kubernetes. Например, если используется Ingress-контроллер, добавьте следующие параметры в файл конфигурации Ingress:

    tls:
        - hosts:
          - trino-cloud.ru-central1.internal (1)
          secretName: trino-tls-secret
    1 TLS-настройки для запросов, приходящих с данного хоста.

    Затем примените обновленную конфигурацию Ingress, например:

    $ kubectl apply -f trino_ingress.yaml -n trino

Шаг 4. Обновление инсталляции Trino-кластера

  1. Обновите конфигурационный файл Trino-кластера (trino_cluster_values.yaml), добавив в него параметры Kerberos/SSL. Обновленный файл должен содержать следующие свойства:

    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.jks
    1 Параметры Kerberos, включая реалм, имя хоста, keytab-файлы, и так далее.
    2 Имя секрета для сертфиката Trino.
  2. Обновите инсталляцию кластера Trino:

    $ 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
  3. Удалите старые поды кластера, чтобы оператор Trino создал новые с обновленной конфигурацией:

    $ kubectl delete pods -n <trino-cluster-ns> -l app.kubernetes.io/instance=trino-cluster
  4. Когда Kubernetes создаст новые поды, проверьте, что все поды имеют состояние Running:

    $ kubectl get pods -n <trino-cluster-ns>

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

    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

Шаг 5. Подключение к Trino по JDBC

Для внешнего доступа к Trino Coordinator по JDBC необходимо настроить один из способов публикации сервиса, например, используя балансировщик нагрузки (load balancer) или Ingress-контроллер. Все настройки, связанные с публикацией сервиса, включая DNS, аннотации, параметры Ingress, TLS-сертификаты, правила балансировщика и прочие, должны быть указаны в соответствии с вашей инфраструктурой Kubernetes.

  1. Получите внешний IP-адрес балансировщика или Ingress-контроллера. Например:

    NAME            CLASS   HOSTS                              ADDRESS        PORTS     AGE
    trino-ingress   nginx   trino-cloud.ru-central1.internal   10.92.43.92   80, 443   1d7h

    Скопируйте внешний IP-адрес для дальнейших шагов (в данном примере это 10.92.43.92).

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

    jdbc:trino://<external-ip>:443?SSL=true&SSLTrustStorePath=<path>/truststore.jks&SSLTrustStorePassword=<password>&KerberosPrincipal=user&KerberosRemoteServiceName=HTTP&KerberosKeytabPath=<path>/user.keytab

    где:

    • <external-ip> — IP-адрес Ingress-контроллера или балансировщика.

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

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

    • KerberosPrincipal=user — принципал Kerberos, используемый DBeaver для подключения.

    • KerberosRemoteServiceName=HTTP — сервисное имя, используемое для подключения (указано в ресурсе Kubernetes keytab).

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