Todos os produtos
Search
Central de documentação

Elastic Container Instance:Executar jobs do Spark no ECI

Última atualização: Sep 11, 2026

Executar jobs do Spark no ECI em um cluster Kubernetes oferece dimensionamento automático, implantação automatizada e alta disponibilidade, o que aumenta a eficiência e a estabilidade. Instale o Spark Operator em um cluster ACK Serverless para executar e gerenciar jobs do Spark no ECI.

Contexto

O Apache Spark é um projeto open-source amplamente utilizado em análise de dados para cargas de trabalho de big data e machine learning. A partir da versão 2.3.0, é possível executar e gerenciar recursos do Spark no Kubernetes.

O Spark Operator, desenvolvido para o Spark no Kubernetes, permite enviar jobs do Spark para um cluster Kubernetes definindo-os como Custom Resource Definitions (CRDs). O Spark Operator oferece as seguintes vantagens:

  • Supera as limitações do suporte nativo do Spark ao Kubernetes.

  • Permite integração rápida com componentes do ecossistema Kubernetes, como armazenamento, monitoramento e logs.

  • Oferece suporte a recursos avançados do Kubernetes, como recuperação de falhas, dimensionamento automático e otimização de agendamento.

Pré-requisitos

  1. Crie um cluster ACK Serverless.

    Crie um cluster ACK Serverless no Container Service for Kubernetes console. Para mais informações, consulte Create an ACK Serverless cluster.

    Importante

    Se for necessário baixar imagens da internet ou se o job de treinamento exigir acesso à internet, configure um NAT Gateway.

    Use o kubectl para gerenciar e acessar o cluster ACK Serverless das seguintes formas:

  2. Crie um bucket do OSS.

    Crie um bucket do OSS para armazenar dados de teste, resultados e logs. Para mais informações, consulte Create a bucket.

Instalar o Spark Operator

  1. Instale o Spark Operator.

    1. No painel de navegação à esquerda do ACK console, escolha Marketplace > Marketplace.

    2. Na aba App Catalog, localize e clique em ack-spark-operator.

    3. No canto superior direito, clique em Deploy.

    4. No painel exibido, selecione o cluster desejado e conclua a configuração conforme solicitado.

  2. Crie um ServiceAccount, Role e RoleBinding.

    Um job do Spark requer um ServiceAccount com permissões para criar pods. Crie um ServiceAccount, Role e RoleBinding usando o manifesto YAML a seguir. Modifique o namespace conforme necessário.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: spark
      namespace: default
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: spark-role
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["*"]
    - apiGroups: [""]
      resources: ["services"]
      verbs: ["*"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: spark-role-binding
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: spark
      namespace: default
    roleRef:
      kind: Role
      name: spark-role
      apiGroup: rbac.authorization.k8s.io

Criar uma imagem de job do Spark

Compile o pacote JAR do job do Spark e empacote-o em uma imagem usando um Dockerfile.

O Dockerfile a seguir tem como base a imagem do Spark fornecida pelo Alibaba Cloud Container Service:

FROM registry.aliyuncs.com/acs/spark:ack-2.4.5-latest
RUN mkdir -p /opt/spark/jars
# If you need to use OSS (for example, to read data from or write events to OSS), add the following JAR packages to the image.
ADD https://repo1.maven.org/maven2/com/aliyun/odps/hadoop-fs-oss/3.3.8-public/hadoop-fs-oss-3.3.8-public.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/com/aliyun/oss/aliyun-sdk-oss/3.8.1/aliyun-sdk-oss-3.8.1.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/org/aspectj/aspectjweaver/1.9.5/aspectjweaver-1.9.5.jar $SPARK_HOME/jars
ADD https://repo1.maven.org/maven2/org/jdom/jdom/1.1.3/jdom-1.1.3.jar $SPARK_HOME/jars
COPY SparkExampleScala-assembly-0.1.jar /opt/spark/jars
Importante

Baixar uma imagem grande do Spark pode ser demorado. Use o ImageCache para acelerar o download de imagens. Para mais informações, consulte Manage ImageCache e Use ImageCache to accelerate pod creation.

A Alibaba Cloud fornece uma imagem base para o Spark 2.4.5 otimizada para agendamento e elasticidade no Kubernetes, o que melhora significativamente as velocidades de agendamento e inicialização. Ative essa otimização definindo a variável enableAlibabaCloudFeatureGates: true no Helm chart. Para uma inicialização ainda mais rápida, defina enableWebhook: false.

operatorImageName: registry.aliyuncs.com/acs/spark-operator
operatorImageVersion: ack-2.4.5-latest
operatorVersion: v2.4.5-v1beta2
imagePullPolicy: IfNotPresent
rbac:
  create: true
serviceAccounts:
  spark:
    create: true
    name: spark
  sparkoperator:
    create: true
    name: ack-spark-operator
sparkJobNamespace: "default"
enableWebhook: false
enableMetrics: true
enableAlibabaCloudFeatureGates: false

Criar e enviar um manifesto de job

Crie um arquivo de configuração YAML para o job do Spark e implante-o.

  1. Crie um arquivo spark-pi.yaml.

    Veja abaixo um exemplo de manifesto de job. Para mais informações, consulte spark-on-k8s-operator.

    apiVersion: "sparkoperator.k8s.io/v1beta2"
    kind: SparkApplication
    metadata:
      name: spark-pi
      namespace: default
    spec:
      type: Scala
      mode: cluster
      image: "registry.aliyuncs.com/acs/spark:ack-2.4.5-latest"
      imagePullPolicy: Always
      mainClass: org.apache.spark.examples.SparkPi
      mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.5.jar"
      sparkVersion: "2.4.5"
      restartPolicy:
        type: Never
      driver:
        cores: 2
        coreLimit: "2"
        memory: "3g"
        memoryOverhead: "1g"
        labels:
          version: 2.4.5
        serviceAccount: spark
        annotations:
          k8s.aliyun.com/eci-kube-proxy-enabled: 'true'
          k8s.aliyun.com/eci-auto-imc: "true"
        tolerations:
        - key: "virtual-kubelet.io/provider"
          operator: "Exists"
      executor:
        cores: 2
        instances: 1
        memory: "3g"
        memoryOverhead: "1g"
        labels:
          version: 2.4.5
        annotations:
          k8s.aliyun.com/eci-kube-proxy-enabled: 'true'
          k8s.aliyun.com/eci-auto-imc: "true"
        tolerations:
        - key: "virtual-kubelet.io/provider"
          operator: "Exists"
  2. Implante um job de computação do Spark.

    kubectl apply -f spark-pi.yaml

Configurar a coleta de logs

Para coletar logs de saída padrão do driver e do executor do Spark, injete variáveis de ambiente no campo envVars correspondente. Para mais informações, consulte Customize log collection for ECI.

envVars:
   aliyun_logs_test-stdout_project: test-k8s-spark
   aliyun_logs_test-stdout_machinegroup: k8s-group-app-spark
   aliyun_logs_test-stdout: stdout

Defina essas variáveis de ambiente para o driver e o executor ao enviar o job. Após a configuração, visualize os logs coletados na aba Raw Logs do Project correspondente no console do Log Service. As entradas de log contêm campos como __source__, __tag__:__hostname__, __tag__:__path__, __tag__:__user_defined_id__ e __tag__:eci_id, além do conteúdo do log no campo content.

Configurar o history server

O history server rastreia e audita jobs do Spark. Adicione o campo SparkConf ao CRD SparkApplication para gravar eventos no OSS. O history server lê esses eventos para exibir informações sobre os jobs. Exemplo de configuração:

sparkConf:
   "spark.eventLog.enabled": "true"
   "spark.eventLog.dir": "oss://bigdatastore/spark-events"
   "spark.hadoop.fs.oss.impl": "org.apache.hadoop.fs.aliyun.oss.AliyunOSSFileSystem"
   # oss bucket endpoint such as oss-cn-beijing.aliyuncs.com
   "spark.hadoop.fs.oss.endpoint": "oss-cn-beijing.aliyuncs.com"
   "spark.hadoop.fs.oss.accessKeySecret": ""
   "spark.hadoop.fs.oss.accessKeyId": ""
        

A Alibaba Cloud também fornece um Helm chart spark-history-server. Pesquise por ack-spark-history-server na página Marketplace > Marketplace do console do ACK e instale-o. Durante a instalação, configure as informações relacionadas ao OSS na seção Parameters. Exemplo:

oss:
  enableOSS: true
  # Please input your accessKeyId
  alibabaCloudAccessKeyId: ""
  # Please input your accessKeySecret
  alibabaCloudAccessKeySecret: ""
  # oss bucket endpoint such as oss-cn-beijing.aliyuncs.com
  alibabaCloudOSSEndpoint: "oss-cn-beijing.aliyuncs.com"
  # oss file path such as oss://bucket-name/path
  eventsDir: "oss://bigdatastore/spark-events"

Após a instalação, localize o endpoint externo do ack-spark-history-server em Services, na página de detalhes do cluster. Acesse esse endpoint para visualizar jobs arquivados. A página do Spark History Server lista aplicações Spark concluídas com colunas como App ID, App Name, Started, Completed, Duration, Spark User, Last Updated e Event Log. Para baixar um log de eventos, clique em Download na linha correspondente.

Visualizar o resultado do job

  1. Verifique o status de execução dos pods.

    kubectl get pods

    Saída esperada:

    NAME                            READY      STATUS     RESTARTS   AGE
    spark-pi-1547981232122-driver   1/1       Running    0          12s
    spark-pi-1547981232122-exec-1   1/1       Running    0          3s
  2. Visualize a interface do Spark UI em tempo real.

    kubectl port-forward spark-pi-1547981232122-driver 4040:4040
  3. Verifique o status do SparkApplication.

    kubectl describe sparkapplication spark-pi

    Saída esperada:

    Name:         spark-pi
    Namespace:    default
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"sparkoperator.k8s.io/v1alpha1","kind":"SparkApplication","metadata":{"annotations":{},"name":"spark-pi","namespace":"default"...}}
    API Version:  sparkoperator.k8s.io/v1alpha1
    Kind:         SparkApplication
    Metadata:
      Creation Timestamp:  2019-01-20T10:47:08Z
      Generation:          1
      Resource Version:    4923532
      Self Link:           /apis/sparkoperator.k8s.io/v1alpha1/namespaces/default/sparkapplications/spark-pi
      UID:                 bbe7445c-1ca0-11e9-9ad4-062fd7c19a7b
    Spec:
      Deps:
      Driver:
        Core Limit:  200m
        Cores:       0.1
        Labels:
          Version:        2.4.0
        Memory:           512m
        Service Account:  spark
        Volume Mounts:
          Mount Path:  /tmp
          Name:        test-volume
      Executor:
        Cores:      1
        Instances:  1
        Labels:
          Version:  2.4.0
        Memory:     512m
        Volume Mounts:
          Mount Path:         /tmp
          Name:               test-volume
      Image:                  gcr.io/spark-operator/spark:v2.4.0
      Image Pull Policy:      Always
      Main Application File:  local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar
      Main Class:             org.apache.spark.examples.SparkPi
      Mode:                   cluster
      Restart Policy:
        Type:  Never
      Type:    Scala
      Volumes:
        Host Path:
          Path:  /tmp
          Type:  Directory
        Name:    test-volume
    Status:
      Application State:
        Error Message:
        State:          COMPLETED
      Driver Info:
        Pod Name:             spark-pi-driver
        Web UI Port:          31182
        Web UI Service Name:  spark-pi-ui-svc
      Execution Attempts:     1
      Executor State:
        Spark - Pi - 1547981232122 - Exec - 1:  COMPLETED
      Last Submission Attempt Time:             2019-01-20T10:47:14Z
      Spark Application Id:                     spark-application-1547981285779
      Submission Attempts:                      1
      Termination Time:                         2019-01-20T10:48:56Z
    Events:
      Type    Reason                     Age                 From            Message
      ----    ------                     ----                ----            -------
      Normal  SparkApplicationAdded      55m                 spark-operator  SparkApplication spark-pi was added, Enqueuing it for submission
      Normal  SparkApplicationSubmitted  55m                 spark-operator  SparkApplication spark-pi was submitted successfully
      Normal  SparkDriverPending         55m (x2 over 55m)   spark-operator  Driver spark-pi-driver is pending
      Normal  SparkExecutorPending       54m (x3 over 54m)   spark-operator  Executor spark-pi-1547981232122-exec-1 is pending
      Normal  SparkExecutorRunning       53m (x4 over 54m)   spark-operator  Executor spark-pi-1547981232122-exec-1 is running
      Normal  SparkDriverRunning         53m (x12 over 55m)  spark-operator  Driver spark-pi-driver is running
      Normal  SparkExecutorCompleted     53m (x2 over 53m)   spark-operator  Executor spark-pi-1547981232122-exec-1 completed
  4. Visualize os logs para verificar o resultado.

    NAME                                      READY     STATUS      RESTARTS   AGE
    spark-pi-1547981232122-driver   0/1       Completed   0          1m

    Quando o status do SparkApplication for COMPLETED ou o status do pod driver do Spark for Completed, visualize os logs para conferir o resultado.

    kubectl logs spark-pi-1547981232122-driver
    Pi is roughly 3.152155760778804