Estoy tratando de leer un depósito s3 de Spark y, hasta el día de hoy, Spark siempre se queja de que la solicitud devuelve 403.
hadoopConf = spark_context._jsc.hadoopConfiguration() hadoopConf.set("fs.s3a.access.key", "ACCESSKEY") hadoopConf.set("fs.s3a.secret.key", "SECRETKEY") hadoopConf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") logs = spark_context.textFile("s3a://mybucket/logs/*)Spark decía... Clave de acceso no válida [TECLA DE ACCESO]
Sin embargo, con la misma ACCESSKEY y SECRETKEY esto funcionaba con aws-cli
aws s3 ls mybucket/logs/y en python boto3 esto estaba funcionando
resource = boto3.resource("s3", region_name="us-east-1") resource.Object("mybucket", "logs/text.py") \ .put(Body=open("text.py", "rb"),ContentType="text/x-py")así que mis credenciales NO son válidas y el problema definitivamente es algo con Spark ...
Hoy decidí activar el registro de "DEPURACIÓN" para toda la chispa y, para mi sorpresa... Spark NO está usando la [SECRETKEY] que proporcioné, sino que... ¿agrega una al azar?
17/03/08 10:40:04 Solicitud DEBUG: Solicitud de envío: HEAD https://mybucket.s3.amazonaws.com / Encabezados: (Autorización: AWS ACCESSKEY: [RANDON-SECRET-KEY] , Agente de usuario: aws -sdk-java/1.7.4 Mac_OS_X/10.11.6 Java_HotSpot(TM)_64-Bit_Server_VM/25.65-b01/1.8.0_65, fecha: miércoles, 08 de marzo de 2017 10:40:04 GMT, tipo de contenido: aplicación/x -www-formulario-urlencodificado; charset=utf-8, )
¡Es por eso que todavía devuelve 403! Spark no está usando la clave que proporciono con fs.s3a.secret.key sino que inventa una aleatoria.
Para que conste, estoy ejecutando esto localmente en mi máquina (OSX) con este comando
spark-submit --packages com.amazonaws:aws-java-sdk-pom:1.11.98,org.apache.hadoop:hadoop-aws:2.7.3 test.py¿Alguien podría iluminarme sobre esto?
(actualizado ya que mi original fue rechazado como claramente considerado inaceptable)
El protocolo de autenticación de AWS no envía su secreto por cable. Firma el mensaje. Es por eso que lo que ves no es lo que pasaste.
Para obtener más información, vuelva a leer.
Me encontré con un problema similar. Las solicitudes que usaban credenciales de AWS válidas devolvieron un 403 Prohibido, pero solo en ciertas máquinas. Eventualmente descubrí que la hora del sistema en esas máquinas en particular estaba 10 minutos atrasada. Sincronizar el reloj del sistema resolvió el problema.
¡Espero que esto ayude!
Es muy intrigante esta clave aleatoria. Tal vez AWS SDK obtenga la contraseña del entorno del sistema operativo.
En hadoop 2.8, la cadena de proveedores de AWS predeterminada muestra la siguiente lista de proveedores:
BasicAWSCredentialsProvider EnvironmentVariableCredentialsProvider SharedInstanceProfileCredentialsProvider¡El orden, por supuesto, importa! AWSCredentialProviderChain, obtenga las primeras claves del primer proveedor que proporciona esa información.
if (credentials.getAWSAccessKeyId() != null && credentials.getAWSSecretKey() != null) { log.debug("Loading credentials from " + provider.toString()); lastUsedProvider = provider; return credentials; }Consulte el código en "GrepCode for AWSCredentialProviderChain" .
Me enfrento a un problema similar al usar las credenciales de perfil. SDK estaba ignorando las credenciales dentro de ~/.aws/credentials (como buena práctica, le recomiendo que no almacene las credenciales dentro del programa de ninguna manera).
Mi solución...
Configure el proveedor de credenciales para usar ProfileCredentialsProvider
sc._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "s3.eu-central-1.amazonaws.com") # yes, I am using central eu server. sc._jsc.hadoopConfiguration().set('fs.s3a.aws.credentials.provider', 'com.amazonaws.auth.profile.ProfileCredentialsProvider')