すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Simple Log Serviceを使用してSparkジョブのログを収集する

最終更新日:Dec 13, 2024

Container Service for Kubernetes (ACK) クラスターでSparkジョブを実行すると、多数のログが生成され、異なるポッドに分散されます。 これにより、ログ管理が複雑になります。 Simple Log Serviceを使用して、ログを収集、処理、クエリ、分析、視覚化し、アラートを生成できます。 これにより、Sparkログを効率的に管理できます。 このトピックでは、Simple Log Serviceを使用してACKクラスターのSparkジョブのログを管理する方法について説明します。

前提条件

手順の概要

このトピックでは、Sparkジョブによって生成されたシステムログとビジネスログを管理するSimple Log Serviceを設定する方法について説明します。

  1. Sparkコンテナイメージのビルド: log4j JSONテンプレートレイアウトの依存関係を含むSparkコンテナイメージをビルドし、イメージをイメージリポジトリにプッシュします。

  2. Log4j2ログの設定: Log4j2ログを設定するためのConfigMapを作成し、ログレベルをINFOに設定してから、ログ印刷形式をJSONLに設定します。

  3. Logtail設定の作成: AliyunConfigリソースを作成します。 Simple Log Serviceは、指定されたLogstoreにLogtail設定を作成し、Sparkオペレーターを使用して送信されたSparkジョブのログを収集します。

  4. サンプルSparkジョブを送信する: サンプルSparkジョブを作成して実行し、ポッドログ出力がJSONL形式であるかどうかを確認してから、特定のフィールドの意味を記述します。

  5. Sparkログの照会と分析: Simple Log Serviceコンソールにログインし、指定された期間内にSparkジョブログを照会して分析します。

  6. (オプション) 環境をクリアする: テストが完了したら、不要なSparkジョブとリソースを削除して、追加コストを防ぎます。

ステップ1: Sparkコンテナイメージのビルド

次のDockerfileを作成し、必要な依存関係をSparkのクラスパスに追加します。 この例では、Spark 3.5.3が使用されます。 イメージがビルドされたら、イメージをイメージリポジトリにプッシュします。 ログの収集と解析を容易にするため、ログはJSONL形式で出力されます。

ARG SPARK_IMAGE=<SPARK_IMAGE>  # Replace <SPARK_IMAGE> with your Spark base image. 

FROM ${SPARK_IMAGE}

# Add dependency for log4j-layout-template-json
ADD --chown=spark:spark --chmod=644 https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-layout-template-json/2.24.1/log4j-layout-template-json-2.24.1.jar ${SPARK_HOME}/jars

ステップ2: Log4jログの設定

次の内容を使用して、spark-log-conf.yamlという名前のファイルを作成し、ログレベルをINFOに設定し、ログ印刷形式をJSONL形式に設定します。 標準化されたログ形式であるログテンプレートとしてElastic Common Schema (ECS) を使用します。 詳細については、「Log4jログの収集」をご参照ください。

apiVersion: v1
kind: ConfigMap
metadata:
  name: spark-log-conf
  namespace: default
data:
  log4j2.properties: |
    # Set everything to be logged to the console and file
    rootLogger.level = info 
                                                   
    rootLogger.appenderRefs = console, file
    rootLogger.appenderRef.console.ref = STDOUT
    rootLogger.appenderRef.file.ref = FileAppender
    
    appender.console.name = STDOUT
    appender.console.type = Console
    appender.console.layout.type = JsonTemplateLayout
    appender.console.layout.eventTemplateUri = classpath:EcsLayout.json
    
    appender.file.name = FileAppender
    appender.file.type = File
    appender.file.fileName = /opt/spark/logs/spark.log   
    appender.file.layout.type = JsonTemplateLayout        
    appender.file.layout.eventTemplateUri = classpath:EcsLayout.json

次のコマンドを実行して、ConfigMapを作成します。

kubectl apply -f spark-log-conf.yaml

期待される出力:

configmap/spark-log-conf created

ステップ3: Logtail設定の作成

次の内容を使用して、aliyun-log-config.yamlという名前のAliyunLogConfigマニフェストファイルを作成します。 <SLS_PROJECT> をSimple Log Serviceプロジェクトの名前に置き換え、<SLS_LOGSTORE> をSimple Log Service Logstoreの名前に置き換えます。 設定の詳細については、「AliyunLogConfigを使用したLogtail設定の管理」をご参照ください。

apiVersion: log.alibabacloud.com/v1alpha1
kind: AliyunLogConfig
metadata:
  name: spark
  namespace: default
spec:
  # (Optional) The name of the project. Default value: k8s-log-<Your_Cluster_ID>.
  project: <SLS_PROJECT>

  # The name of the Logstore. If the Logstore that you specify does not exist, Simple Log Service automatically creates a Logstore. 
  logstore: <SLS_LOGSTORE>
  
  # The Logtail configuration. 
  logtailConfig:
    # The name of the Logtail configuration. 
    configName: spark

    # The type of the data source. The value file specifies text logs.
    inputType: file

    # The configurations of the log input. 
    inputDetail:
      # The directory in which the log file is located. 
      logPath: /opt/spark/logs

      # The name of a log file. Wildcard characters are supported. 
      filePattern: '*.log'

      # The encoding of the log file. 
      fileEncoding: utf8

      # The log type. 
      logType: json_log
      localStorage: true
      key:
      - content
      logBeginRegex: .*
      logTimezone: ''
      discardNonUtf8: false
      discardUnmatch: true
      preserve: true
      preserveDepth: 0
      regex: (.*)
      outputType: LogService
      topicFormat: none
      adjustTimezone: false
      enableRawLog: false

      # Collect text logs from containers. 
      dockerFile: true

      # Advanced configurations. 
      advanced:
        # Preview the container metadata. 
        collect_containers_flag: true

        # Logtail configurations in Kubernetes. 
        k8s:
          # Filter pods based on the tag. 
          IncludeK8sLabel:
            sparkoperator.k8s.io/launched-by-spark-operator: "true"

          # Filter containers based on the container name. 
          K8sContainerRegex: "^spark-kubernetes-(driver|executor)$"

          # Additional log tag configurations. 
          ExternalK8sLabelTag:
            spark-app-name: spark-app-name
            spark-version: spark-version
            spark-role: spark-role
            spark-app-selector: spark-app-selector
            sparkoperator.k8s.io/submission-id: sparkoperator.k8s.io/submission-id

      # The log processing plug-in. 
      plugin:
        processors:
        # Log isolation. 
        - type: processor_split_log_string
          detail:
            SplitKey: content
            SplitSep: ''

        # Parse the JSON field. 
        - type: processor_json
          detail:
            ExpandArray: false
            ExpandConnector: ''
            ExpandDepth: 0
            IgnoreFirstConnector: false
            SourceKey: content
            KeepSource: false
            KeepSourceIfParseError: true
            NoKeyError: false
            UseSourceKeyAsPrefix: false

        # Extract the log timestamp. 
        - type: processor_strptime
          detail:
            SourceKey: '@timestamp'
            Format: '%Y-%m-%dT%H:%M:%S.%fZ'
            KeepSource: false
            AdjustUTCOffset: true
            UTCOffset: 0
            AlarmIfFail: false

次のコマンドを実行してLogtail設定を作成します。

kubectl apply -f aliyun-log-config.yaml

新しいLogstoreおよびLogtail設定を表示するには、次の手順を実行します。

  1. にログインします。Simple Log Serviceコンソール.

  2. [プロジェクト] セクションで、目的のプロジェクトをクリックします。

    image

  3. [ログストレージ] > [ログストア] を選択します。 対象のLogtail設定の > アイコンをクリックします。 [データインポート] > [Logtail設定] を選択します。

    image

  4. 対象のLogtail設定をクリックして、設定の詳細を表示します。

ステップ4: サンプルSparkジョブを送信する

次のコンテンツを使用して、spark-pi.yamlという名前のSparkApplicationマニフェストファイルを作成します。

apiVersion: sparkoperator.k8s.io/v1beta2
kind: SparkApplication
metadata:
  name: spark-pi
  namespace: default
spec:
  type: Scala
  mode: cluster
  image: <SPARK_IMAGE>
  mainClass: org.apache.spark.examples.SparkPi
  mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.5.3.jar
  arguments: 
  - "5000"
  sparkVersion: 3.5.3
  sparkConfigMap: spark-log-conf
  driver:
    cores: 1
    memory: 512m
    serviceAccount: spark-operator-spark
  executor:
    instances: 1
    cores: 1
    memory: 4g

次のコマンドを実行して、ジョブを送信します。

kubectl apply -f spark-pi.yaml

ジョブの実行が完了するまで待ち、ドライバポッドログの最後の10行を確認します。

kubectl logs  --tail=10 spark-pi-driver  

期待される出力:

{"@timestamp":"2024-11-20T11:45:48.487Z","ecs.version":"1.2.0","log.level":"WARN","message":"Kubernetes client has been closed.","process.thread.name":"-937428334-pool-19-thread-1","log.logger":"org.apache.spark.scheduler.cluster.k8s.ExecutorPodsWatchSnapshotSource"}
{"@timestamp":"2024-11-20T11:45:48.585Z","ecs.version":"1.2.0","log.level":"INFO","message":"MapOutputTrackerMasterEndpoint stopped!","process.thread.name":"dispatcher-event-loop-7","log.logger":"org.apache.spark.MapOutputTrackerMasterEndpoint"}
{"@timestamp":"2024-11-20T11:45:48.592Z","ecs.version":"1.2.0","log.level":"INFO","message":"MemoryStore cleared","process.thread.name":"main","log.logger":"org.apache.spark.storage.memory.MemoryStore"}
{"@timestamp":"2024-11-20T11:45:48.592Z","ecs.version":"1.2.0","log.level":"INFO","message":"BlockManager stopped","process.thread.name":"main","log.logger":"org.apache.spark.storage.BlockManager"}
{"@timestamp":"2024-11-20T11:45:48.596Z","ecs.version":"1.2.0","log.level":"INFO","message":"BlockManagerMaster stopped","process.thread.name":"main","log.logger":"org.apache.spark.storage.BlockManagerMaster"}
{"@timestamp":"2024-11-20T11:45:48.598Z","ecs.version":"1.2.0","log.level":"INFO","message":"OutputCommitCoordinator stopped!","process.thread.name":"dispatcher-event-loop-1","log.logger":"org.apache.spark.scheduler.OutputCommitCoordinator$OutputCommitCoordinatorEndpoint"}
{"@timestamp":"2024-11-20T11:45:48.602Z","ecs.version":"1.2.0","log.level":"INFO","message":"Successfully stopped SparkContext","process.thread.name":"main","log.logger":"org.apache.spark.SparkContext"}
{"@timestamp":"2024-11-20T11:45:48.604Z","ecs.version":"1.2.0","log.level":"INFO","message":"Shutdown hook called","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}
{"@timestamp":"2024-11-20T11:45:48.604Z","ecs.version":"1.2.0","log.level":"INFO","message":"Deleting directory /var/data/spark-f783cf2e-44db-452c-83c9-738f9c894ef9/spark-2caa5814-bd32-431c-a9f9-a32208b34fbb","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}
{"@timestamp":"2024-11-20T11:45:48.606Z","ecs.version":"1.2.0","log.level":"INFO","message":"Deleting directory /tmp/spark-dacdfd95-f166-4b23-9312-af9052730417","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}

出力されたログはJSONL形式で出力されます。 次のセクションでは、各フィールドの意味について説明します。

  • @ timestamp: ログが生成された時刻。

  • ecs.version: ECSのバージョン番号。

  • log.level: ログのレベル。

  • message: ログメッセージ。

  • process.thread.name: ログを生成するスレッドの名前。

  • log.logger: ログを記録するロガーの名前。

ステップ5: Sparkログの照会と分析

ログの照会と分析を行って、ジョブ実行の時間範囲を指定し、ログが収集されているかどうかを確認できます。

image

(オプション) ステップ6: 環境をクリアする

このトピックのすべての手順を実行したら、次のコマンドを実行してSparkジョブを削除し、不要になったリソースを解放します。

次のコマンドを実行して、Sparkジョブを削除します。

kubectl delete -f spark-pi.yaml

次のコマンドを実行して、Logtail設定を削除します。

kubectl delete -f aliyun-log-config.yaml

次のコマンドを実行して、Log4j2ログ設定を削除します。

kubectl delete -f spark-log-conf.yaml