Configuración de los permisos de acceso al clúster con roles de IAM para las cuentas de servicio (IRSA)
En esta sección, se utiliza un ejemplo para demostrar cómo configurar una cuenta de servicio de Kubernetes para que asuma un rol de AWS Identity and Access Management. Los pods que usan la cuenta de servicio pueden acceder a cualquier servicio de AWS al que el rol tenga permisos para acceder.
En el siguiente ejemplo, se ejecuta una aplicación de Spark para contar las palabras de un archivo en Amazon S3. Para ello, puede configurar roles de IAM para las cuentas de servicio (IRSA) a fin de autenticar y autorizar las cuentas de servicio de Kubernetes.
nota
En este ejemplo, se utiliza el espacio de nombres “spark-operator” para el operador de Spark y para el espacio de nombres al que se envía la solicitud de Spark.
Requisitos previos
Antes de probar el ejemplo de esta página, complete los siguientes requisitos previos:
-
Guarde su poema favorito en un archivo de texto llamado
poem.txt
y súbalo a su bucket de S3. La aplicación de Spark que cree en esta página leerá el contenido del archivo de texto. Para obtener más información sobre cómo cargar archivos en S3, consulte Cargar un objeto en el bucket en la Guía del usuario de Amazon Simple Storage Service.
Configurar una cuenta de servicio de Kubernetes para que asuma un rol de IAM
Siga estos pasos para configurar una cuenta de servicio de Kubernetes a fin de que asuma un rol de IAM que los pods puedan usar para acceder a los servicios de AWS a los que el rol tiene permisos de acceso.
-
Tras completar Requisitos previos, utilice la AWS Command Line Interface para crear un archivo
example-policy.json
que permita el acceso de solo lectura al archivo que ha subido a 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 -
Luego, cree una política de IAM
example-policy
:aws iam create-policy --policy-name example-policy --policy-document file://example-policy.json
-
A continuación, cree un rol de IAM
example-role
y asócielo a una cuenta de servicio de Kubernetes para el controlador de 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 -
Cree un archivo yaml con las vinculaciones de roles de clúster necesarias para la cuenta de servicio de controlador de 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 las configuraciones de la vinculación de roles del clúster:
kubectl apply -f spark-rbac.yaml
El comando kubectl debería confirmar que la cuenta se ha creado correctamente:
serviceaccount/driver-account-sa created
clusterrolebinding.rbac.authorization.k8s.io/spark-role configured
Ejecutar una aplicación desde el operador de Spark
Después de configurar la cuenta de servicio de Kubernetes, puede ejecutar una aplicación de Spark que cuente el número de palabras del archivo de texto que ha subido como parte de Requisitos previos.
-
Cree un archivo nuevo
word-count.yaml
con una definición deSparkApplication
para su aplicación de recuento de palabras.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 -
Envíe la aplicación de Spark.
kubectl apply -f word-count.yaml
El comando kubectl debería devolver la confirmación de que ha creado correctamente un objeto
SparkApplication
llamadoword-count
.sparkapplication.sparkoperator.k8s.io/word-count configured
-
Para comprobar los eventos del objeto
SparkApplication
, ejecute el siguiente comando:kubectl describe sparkapplication word-count -n spark-operator
El comando kubectl debería devolver la descripción de
SparkApplication
junto con los 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
La aplicación ahora cuenta las palabras del archivo de S3. Para saber el número de palabras, consulte los archivos de registro de su controlador:
kubectl logs pod/word-count-driver -n spark-operator
El comando kubectl debería devolver el contenido del archivo de registro con los resultados de la aplicación de recuento de palabras.
INFO DAGScheduler: Job 0 finished: collect at JavaWordCount.java:53, took 5.146519 s
Software: 1
Para obtener más información sobre cómo enviar solicitudes a Spark a través del operador de Spark, consulte Uso de SparkApplication