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:
-
Salve seu poema favorito em um arquivo de texto chamado
poem.txt
e faça o upload do arquivo em seu bucket do S3. A aplicação do Spark criada nesta página realizará a leitura do conteúdo do arquivo de texto. Para obter mais informações sobre como fazer o upload de arquivos para o S3, consulte Fazer upload de um objeto para o seu bucket no Guia do usuário do Amazon Simple Storage Service.
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.
-
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 -
Em seguida, crie uma política do IAM
example-policy
:aws iam create-policy --policy-name example-policy --policy-document file://example-policy.json
-
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 -
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
-
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.
-
Crie um novo arquivo
word-count.yaml
, com uma definiçãoSparkApplication
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 -
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
chamadoword-count
.sparkapplication.sparkoperator.k8s.io/word-count configured
-
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