Configuração de permissões de acesso ao cluster com perfis do IAM para contas de serviço (IRSA) - Amazon EMR

Configuração de permissões de acesso ao cluster com perfis do IAM para contas de serviço (IRSA)

Esta seção usa um exemplo para demonstrar como configurar uma conta de serviço do Kubernetes para assumir um perfil do AWS Identity and Access Management. Os pods que usam a conta de serviço podem acessar qualquer serviço da AWS ao qual o perfil tenha permissões de acesso.

O exemplo apresentado a seguir executa uma aplicação do Spark para contar as palavras de um arquivo no Amazon S3. Para fazer isso, você pode configurar perfis do IAM para contas de serviço (IRSA) com a finalidade de autenticar e autorizar as contas de serviço do Kubernetes.

nota

Este exemplo usa o namespace “spark-operator” para o operador do Spark e para o namespace no qual a aplicação do Spark é enviada.

Pré-requisitos

Antes de testar o exemplo apresentado nesta página, complete os seguintes pré-requisitos:

Configuração de uma conta de serviço do Kubernetes para assumir um perfil do IAM

Use as etapas apresentadas a seguir para configurar uma conta de serviço do Kubernetes para assumir um perfil do IAM que os pods poderão usar para acessar os serviços da AWS aos quais o perfil tem permissões de acesso.

  1. Após concluir os Pré-requisitos, use a AWS Command Line Interface para criar um arquivo example-policy.json que permita acesso somente leitura ao arquivo que você fez upload no Amazon S3:

    cat >example-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-pod-bucket", "arn:aws:s3:::my-pod-bucket/*" ] } ] } EOF
  2. Em seguida, crie uma política do IAM example-policy:

    aws iam create-policy --policy-name example-policy --policy-document file://example-policy.json
  3. Depois disso, crie um perfil do IAM example-role e associe-o a uma conta de serviço do Kubernetes para o driver do Spark:

    eksctl create iamserviceaccount --name driver-account-sa --namespace spark-operator \ --cluster my-cluster --role-name "example-role" \ --attach-policy-arn arn:aws:iam::111122223333:policy/example-policy --approve
  4. Crie um arquivo em YAML com as associações de perfil do cluster que são obrigatórias para a conta de serviço do driver do Spark:

    cat >spark-rbac.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: driver-account-sa --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: spark-role roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: edit subjects: - kind: ServiceAccount name: driver-account-sa namespace: spark-operator EOF
  5. Aplique as configurações de associação de perfil do cluster:

    kubectl apply -f spark-rbac.yaml

O comando kubectl deve confirmar a criação com êxito da conta:

serviceaccount/driver-account-sa created clusterrolebinding.rbac.authorization.k8s.io/spark-role configured

Execução de uma aplicação do operador do Spark

Após configurar a conta de serviço do Kubernetes, você poderá executar uma aplicação do Spark que conta o número de palavras no arquivo de texto carregado como parte dos Pré-requisitos.

  1. Crie um novo arquivo word-count.yaml, com uma definição SparkApplication para sua aplicação de contagem de palavras.

    cat >word-count.yaml <<EOF apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: word-count namespace: spark-operator spec: type: Java mode: cluster image: "895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.10.0:latest" imagePullPolicy: Always mainClass: org.apache.spark.examples.JavaWordCount mainApplicationFile: local:///usr/lib/spark/examples/jars/spark-examples.jar arguments: - s3://my-pod-bucket/poem.txt hadoopConf: # EMRFS filesystem fs.s3.customAWSCredentialsProvider: com.amazonaws.auth.WebIdentityTokenCredentialsProvider fs.s3.impl: com.amazon.ws.emr.hadoop.fs.EmrFileSystem fs.AbstractFileSystem.s3.impl: org.apache.hadoop.fs.s3.EMRFSDelegate fs.s3.buffer.dir: /mnt/s3 fs.s3.getObject.initialSocketTimeoutMilliseconds: "2000" mapreduce.fileoutputcommitter.algorithm.version.emr_internal_use_only.EmrFileSystem: "2" mapreduce.fileoutputcommitter.cleanup-failures.ignored.emr_internal_use_only.EmrFileSystem: "true" sparkConf: # Required for EMR Runtime spark.driver.extraClassPath: /usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/* spark.driver.extraLibraryPath: /usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native spark.executor.extraClassPath: /usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*:/usr/share/aws/hmclient/lib/aws-glue-datacatalog-spark-client.jar:/usr/share/java/Hive-JSON-Serde/hive-openx-serde.jar:/usr/share/aws/sagemaker-spark-sdk/lib/sagemaker-spark-sdk.jar:/home/hadoop/extrajars/* spark.executor.extraLibraryPath: /usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native sparkVersion: "3.3.1" restartPolicy: type: Never driver: cores: 1 coreLimit: "1200m" memory: "512m" labels: version: 3.3.1 serviceAccount: my-spark-driver-sa executor: cores: 1 instances: 1 memory: "512m" labels: version: 3.3.1 EOF
  2. Envie a aplicação do Spark.

    kubectl apply -f word-count.yaml

    O comando kubectl deve retornar a confirmação de que você criou com êxito um objeto SparkApplication chamado word-count.

    sparkapplication.sparkoperator.k8s.io/word-count configured
  3. Para verificar os eventos do objeto SparkApplication, execute o seguinte comando:

    kubectl describe sparkapplication word-count -n spark-operator

    O comando kubectl deve retornar a descrição da SparkApplication com os eventos:

    Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SparkApplicationSpecUpdateProcessed 3m2s (x2 over 17h) spark-operator Successfully processed spec update for SparkApplication word-count Warning SparkApplicationPendingRerun 3m2s (x2 over 17h) spark-operator SparkApplication word-count is pending rerun Normal SparkApplicationSubmitted 2m58s (x2 over 17h) spark-operator SparkApplication word-count was submitted successfully Normal SparkDriverRunning 2m56s (x2 over 17h) spark-operator Driver word-count-driver is running Normal SparkExecutorPending 2m50s spark-operator Executor [javawordcount-fdd1698807392c66-exec-1] is pending Normal SparkExecutorRunning 2m48s spark-operator Executor [javawordcount-fdd1698807392c66-exec-1] is running Normal SparkDriverCompleted 2m31s (x2 over 17h) spark-operator Driver word-count-driver completed Normal SparkApplicationCompleted 2m31s (x2 over 17h) spark-operator SparkApplication word-count completed Normal SparkExecutorCompleted 2m31s (x2 over 2m31s) spark-operator Executor [javawordcount-fdd1698807392c66-exec-1] completed

Agora, a aplicação está realizando a contagem das palavras em seu arquivo do S3. Para localizar a contagem de palavras, consulte os arquivos de log do seu driver:

kubectl logs pod/word-count-driver -n spark-operator

O comando kubectl deve retornar o conteúdo do arquivo de log com os resultados da sua aplicação de contagem de palavras.

INFO DAGScheduler: Job 0 finished: collect at JavaWordCount.java:53, took 5.146519 s Software: 1

Para obter mais informações sobre como enviar aplicações ao Spark usando o operador do Spark, consulte Using a SparkApplication na documentação Kubernetes Operator for Apache Spark (spark-on-k8s-operator) no GitHub.