Установка Spark History Server в Kubernetes с помощью CLI
Требования
-
Установленный и функционирующий кластер ADH совместимой версии (требуется, только если логи событий будут сохраняться в HDFS или Ozone).
-
Извлеченный и загруженный в ваш репозиторий образ
hub.arenadata.io/adc-enterprise/spark3:<version>. -
Оператор Spark, установленный согласно инструкции. Убедитесь, что пространство имен Spark History Server включено в
payloadNamespacesоператора Spark.
Шаг 1. Установка Spark History Server
-
Подготовьте файл hadoop_conf.yaml с настройками Hadoop (необходимо, только если используются S3 или сервисы Hadoop):
hadoop_conf.yamlsites: 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 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: false -
Инициализируйте Spark History Server:
$ ./adc init --spark-history-server --hadoop-file=hadoop_conf.yaml -o spark-history-server.yamlДанная команда создаст файл spark-history-server.yaml с шаблоном конфигурации.
-
Отредактируйте конфигурационный файл:
spark-history-server.yamlapiVersion: adc.arenadata.io/v1alpha1 kind: SparkHistoryServer metadata: name: spark-history-server namespace: spark-history-server (1) spec: image: hub.arenadata.io/adc-enterprise/spark3:<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 hadoop.security.authentication: simple 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: "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 ## Kerberos configuration for authentication. #kerberos: # realm: EXAMPLE.COM # # # Service name in the Kerberos principal. Defaults to the product name. # service: spark-history # # # 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: history.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: spark-history-keytab # # # Label selector for the Pod that generates the keytab. # # Required when create: true; ignored when create: false. # labelSelector: # env: prod # #additionalPrincipals: # # - HTTP/history-lb.example.com # # rotation: # interval: 720h # checkInterval: 1h # spnego: true ## Java KeyStore/TrustStore certificate configuration. ## Set externalSecretName to reference an existing Secret, ## or set files and optional secretName to have ADC create it. #ssl: # ## Name of the Secret containing Java keystores. # #secretName: custom-spark-history-ssl # externalSecretName: existing-spark-history-ssl # # # 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 # # ## Local files 'adc apply' puts into the Secret named by ssl.secretName. # ## Relative paths are resolved against the config file. # #files: # # trustStorePath: /path/to/truststore.jks # # #keyStorePath: /path/to/keystore.jks ## Use an external Hadoop configs Secret instead of the one rendered by ADC. #hadoopConfigsSecret: # # Use a Secret managed outside ADC. # externalSecretName: existing-history-hadoop-configs # # ## Or let ADC create the Secret. # #secretName: custom-history-hadoop-configs ## Use an external Spark History properties Secret instead of the one rendered by ADC. #historyPropertiesSecret: # # Use a Secret managed outside ADC. # externalSecretName: existing-history-properties # # ## Or let ADC create the Secret. # #secretName: custom-history-properties eventLogDir: "hdfs:///logs/spark/apps" (4) store: path: /var/log/spark/history (5) emptyDir: {} #pvc: (6) # size: 10Gi # storageClassName: my-storage-class # accessModes: # - ReadWriteOnce ## Monitoring configuration. #monitoring: # # Enables Prometheus metrics export from this product's pods. # exportMetrics: true #properties: # spark.history.store.maxDiskUsage: 16g server: replicas: 1 #resources: # limits: # cpu: "1" # memory: 1Gi # requests: # cpu: 400m # memory: 256Mi #extraMountSecrets: # - mountPath: /etc/spark/extra-secret # options: # containerName: app # secretName: extra-secret ## 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: false1 Пространство имен, используемое Spark History Server. 2 URL образа Spark в вашем репозитории. 3 Настройки Hadoop, взятые из ранее созданного файла hadoop_conf.yaml. 4 URI директории в файловой системе, из которой History Server будет считывать данные (например, hdfs:///var/log/spark/apps,ofs://vol.bucket/spark/apps,s3a://bucket/spark/apps). Директория должна уже существовать. Приложения Spark должны записывать логи в эту же директорию.5 Локальный путь хранения логов событий. 6 Запрос на хранилище PVC. Должен быть установлен либо параметр pvc, либо параметрemptyDir. -
Вы можете проверить конфигурацию перед ее применением, выполнив команду
applyс флагом--dry-run:$ ./adc apply -f spark-history-server.yaml --dry-run > spark-history-server-render.yamlspark-history-server-render.yaml--- apiVersion: v1 kind: Secret metadata: name: spark-history-server-configs namespace: spark-history-server stringData: core-site.xml: |- <configuration> <property> <name>dfs.client.failover.proxy.provider.adh</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ObserverReadProxyProvider</value> </property> <property> <name>dfs.client.read.shortcircuit</name> <value>false</value> </property> <property> <name>dfs.ha.namenodes.adh</name> <value>nn_tsn-adh-k8s-1,nn_tsn-adh-k8s-3</value> </property> <property> <name>dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-1</name> <value>tsn-adh-k8s-1.ru-central1.internal:8020</value> </property> <property> <name>dfs.namenode.rpc-address.adh.nn_tsn-adh-k8s-3</name> <value>tsn-adh-k8s-3.ru-central1.internal:8020</value> </property> <property> <name>dfs.nameservices</name> <value>adh</value> </property> <property> <name>fs.defaultFS</name> <value>hdfs://adh</value> </property> <property> <name>hadoop.security.authentication</name> <value>simple</value> </property> <property> <name>ozone.om.address.adh.om_tsn-adh-k8s-1</name> <value>tsn-adh-k8s-1.ru-central1.internal:9862</value> </property> <property> <name>ozone.om.address.adh.om_tsn-adh-k8s-2</name> <value>tsn-adh-k8s-2.ru-central1.internal:9862</value> </property> <property> <name>ozone.om.address.adh.om_tsn-adh-k8s-3</name> <value>tsn-adh-k8s-3.ru-central1.internal:9862</value> </property> <property> <name>ozone.om.nodes.adh</name> <value>om_tsn-adh-k8s-1,om_tsn-adh-k8s-2,om_tsn-adh-k8s-3</value> </property> <property> <name>ozone.om.service.ids</name> <value>adhom</value> </property> </configuration> hive-site.xml: |- <configuration> <property> <name>hive.metastore.sasl.enabled</name> <value>false</value> </property> <property> <name>hive.metastore.uris</name> <value>thrift://tsn-adh-k8s-1.ru-central1.internal:9083</value> </property> <property> <name>metastore.use.SSL</name> <value>false</value> </property> </configuration> type: Opaque --- apiVersion: v1 kind: Secret metadata: name: spark-history-server-spark-history-properties namespace: spark-history-server stringData: history-server.properties: | spark.eventLog.dir hdfs:///logs/spark/apps spark.eventLog.enabled true spark.history.fs.logDirectory hdfs:///logs/spark/apps spark.history.provider org.apache.spark.deploy.history.FsHistoryProvider spark.history.store.path /var/log/spark/history spark.history.ui.port 18080 type: Opaque --- apiVersion: spark.arenadata.io/v1alpha1 kind: SparkHistoryServer metadata: name: spark-history-server namespace: spark-history-server spec: properties: secretKey: history-server.properties secretName: spark-history-server-spark-history-properties server: metadata: {} replicas: 1 spec: emptyDirs: - /var/log/spark/history image: hub.arenadata.io/adc-enterprise/spark3:<tag> imagePullPolicy: Always mountSecrets: - mountPath: /etc/hadoop/conf options: containerName: app secretName: spark-history-server-configs ports: - containerPort: 18080 name: http servicePort: 18080 status: {} -
Если манифест корректный, примените конфигурацию Spark History Server:
$ ./adc apply -f spark-history-server.yamlОжидаемый вывод содержит сообщение с подтверждением успеха:
time="20260827095515UTC" level="info" msg="cluster spark-history-server applied to namespace spark-history-server"
-
Проверьте работоспособность подов Spark History Server:
$ kubectl get pods -n spark-history-serverОжидаемый вывод должен быть похож на следующий:
NAME READY STATUS RESTARTS AGE spark-history-server-spark-history-server-0 1/1 Running 0 9s
Шаг 2. Предоставление доступа к веб-интерфейсу Spark History Server
Для доступа к веб-интерфейсу Spark History Server необходимо настроить один из способов публикации сервиса, например, используя балансировщик нагрузки (load balancer) или Ingress-контроллер. Все настройки, связанные с публикацией сервиса, включая DNS, аннотации, параметры Ingress, правила балансировщика и прочие, должны быть указаны в соответствии с вашей инфраструктурой Kubernetes.
-
Получите внешний адрес балансировщика или Ingress-контроллера. Например:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE spark-lb LoadBalancer 10.85.56.180 10.92.40.88 18080:30930/TCP 119s
-
Откройте веб-интерфейс Spark History Server в браузере, используя URL http://10.92.40.88:18080.
Веб-интерфейс Spark History Server
Веб-интерфейс Spark History Server
Шаг 3. Проверка запуском приложения Spark
-
Создайте приложение Spark согласно инструкции.
-
Измените в конфигурации приложения параметр
spec.eventLogDir. Значение этого параметра и значение параметраspec.eventLogDirв конфигурации Spark History Server должны совпадать:eventLogDir: "hdfs:///logs/spark/apps" -
Запустите приложение Spark:
$ ./adc apply -f spark-application.yaml -
Проверьте, что логи доступны в веб-интерфейсе Spark History Server.
Завершенная задача в веб-интерфейсе Spark History Server
Завершенная задача в веб-интерфейсе Spark History Server