

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# JupyterHub
<a name="emr-jupyterhub"></a>

[Jupyter Notebook](https://jupyter.org/) es una aplicación web de código abierto que puede utilizar para crear y compartir documentos que contienen código activo, ecuaciones, visualizaciones y texto narrativo. [JupyterHub](https://jupyterhub.readthedocs.io/en/latest/)permite alojar varias instancias de un servidor portátil Jupyter de un solo usuario. Al crear un clúster con JupyterHub, Amazon EMR crea un contenedor Docker en el nodo principal del clúster. JupyterHub, todos los componentes necesarios para Jupyter y [Sparkmagic](https://github.com/jupyter-incubator/sparkmagic/blob/master/README.md) se ejecutan en el contenedor.

Sparkmagic es una biblioteca de kernels que permite que los blocs de notas de Jupyter interactúen con [Apache Spark](https://aws.amazon.com/big-data/what-is-spark/) que se ejecuta en Amazon EMR a través de [Apache Livy](emr-livy.md), que es un servidor de REST para Spark. Spark y Apache Livy se instalan automáticamente al crear un clúster con JupyterHub. El núcleo de Python 3 predeterminado para Jupyter está disponible junto con los núcleos PySpark 3 PySpark, y Spark que están disponibles con Sparkmagic. Puede utilizar estos kernels para ejecutar código Spark ad hoc y consultas SQL interactiva con Python y Scala. Puede instalar kernels adicionales en el contenedor de Docker manualmente. Para obtener más información, consulte [Instalación de kernels y bibliotecas adicionales](emr-jupyterhub-install-kernels-libs.md).

El siguiente diagrama muestra los componentes de JupyterHub Amazon EMR con los métodos de autenticación correspondientes para los usuarios de portátiles y el administrador. Para obtener más información, consulte [Agregar usuarios y administradores de Cuadernos de Jupyter](emr-jupyterhub-user-access.md).

![\[JupyterHub architecture on EMR showing user authentication and component interactions.\]](http://docs.aws.amazon.com/es_es/emr/latest/ReleaseGuide/images/jupyter-arch.png)


En la siguiente tabla se muestra la versión JupyterHub incluida en la última versión de la serie Amazon EMR 7.x, junto con los componentes con los que se instala Amazon EMR. JupyterHub

[Para ver la versión de los componentes que se incluyen JupyterHub en esta versión, consulte Versiones de componentes de la versión 7.12.0.](emr-7120-release.md)


**JupyterHub información sobre la versión de emr-7.12.0**  

| Etiqueta de versión de Amazon EMR | JupyterHub Versión | Componentes instalados con JupyterHub | 
| --- | --- | --- | 
| emr-7.12.0 | JupyterHub 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

En la siguiente tabla se muestra la versión JupyterHub incluida en la última versión de la serie Amazon EMR 6.x, junto con los componentes con los que se instala Amazon EMR. JupyterHub

[Para ver la versión de los componentes que se incluyen JupyterHub en esta versión, consulte Versiones de componentes de la versión 6.15.0.](emr-6150-release.md)


**JupyterHub información sobre la versión de emr-6.15.0**  

| Etiqueta de versión de Amazon EMR | JupyterHub Versión | Componentes instalados con JupyterHub | 
| --- | --- | --- | 
| emr-6.15.0 | JupyterHub 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

En la siguiente tabla se muestra la versión JupyterHub incluida en la última versión de la serie Amazon EMR 5.x, junto con los componentes con los que se instala Amazon EMR. JupyterHub

[Para ver la versión de los componentes que se incluyen JupyterHub en esta versión, consulte Versiones de componentes de la versión 5.36.2.](emr-5362-release.md)


**JupyterHub información sobre la versión de emr-5.36.2**  

| Etiqueta de versión de Amazon EMR | JupyterHub Versión | Componentes instalados con JupyterHub | 
| --- | --- | --- | 
| emr-5.36.2 | JupyterHub 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

El núcleo de Python 3 incluido JupyterHub en Amazon EMR es 3.6.4.

Las bibliotecas instaladas en el contenedor `jupyterhub` pueden variar según las versiones de lanzamiento de Amazon EMR y las versiones de AMI de Amazon EC2.

**Para enumerar las bibliotecas instaladas utilizando `conda`**
+ Ejecute el siguiente comando en la línea de comandos del nodo principal:

  ```
  sudo docker exec jupyterhub bash -c "conda list"
  ```

**Para enumerar las bibliotecas instaladas utilizando `pip`**
+ Ejecute el siguiente comando en la línea de comandos del nodo principal:

  ```
  sudo docker exec jupyterhub bash -c "pip freeze"
  ```

**Topics**
+ [Cree un clúster con JupyterHub](emr-jupyterhub-launch.md)
+ [Consideraciones al usarlo JupyterHub en Amazon EMR](emr-jupyterhub-considerations.md)
+ [Configurando JupyterHub](emr-jupyterhub-configure.md)
+ [Configuración de la persistencia de los cuadernos en Amazon S3](emr-jupyterhub-s3.md)
+ [Conexión al nodo maestro y a los servidores de blocs de notas](emr-jupyterhub-connect.md)
+ [JupyterHub configuración y administración](emr-jupyterhub-administer.md)
+ [Agregar usuarios y administradores de Cuadernos de Jupyter](emr-jupyterhub-user-access.md)
+ [Instalación de kernels y bibliotecas adicionales](emr-jupyterhub-install-kernels-libs.md)
+ [JupyterHub historial de versiones](JupyterHub-release-history.md)

# Cree un clúster con JupyterHub
<a name="emr-jupyterhub-launch"></a>

Puede crear un clúster de Amazon EMR con la Consola de administración de AWS AWS Command Line Interface, o la JupyterHub API de Amazon EMR. Asegúrese de que el clúster no se crea con la opción de terminar automáticamente después de completar los pasos (opción `--auto-terminate` de la AWS CLI). Además, asegúrese de que los administradores y los usuarios de blocs de notas puedan obtener acceso al par de claves que utiliza al crear el clúster. Para obtener más información, consulte [Usar un par de claves para credenciales SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-access-ssh.html) en la *Guía de administración de Amazon EMR*.

## Cree un clúster con la JupyterHub consola
<a name="emr-jupyterhub-launch-console"></a>

Utilice el siguiente procedimiento para crear un clúster JupyterHub instalado mediante **las opciones avanzadas** de la consola de Amazon EMR.

**Para crear un clúster de Amazon EMR JupyterHub instalado mediante la consola Amazon EMR**

1. Vaya hasta la nueva consola de Amazon EMR y seleccione **Ir a la consola antigua** en el panel de navegación lateral. Para más información sobre lo que puede esperar al cambiar a la consola antigua, consulte [Uso de la consola antigua](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Elija **Crear clúster** e **Ir a las opciones avanzadas**.

1. En **Software Configuration (Configuración de software)**:
   + Para **Release**, seleccione emr-5.36.2 y elija. JupyterHub
   + Si usas Spark, para usar el catálogo de datos de AWS Glue como metaalmacén de Spark SQL, selecciona **Usar para metadatos de tablas de Spark**. Para obtener más información, consulte [Usa el catálogo de AWS Glue Data Catalog con Spark en Amazon EMR](emr-spark-glue.md).
   + En **Edit software settings (Editar configuración de software)** elija **Enter configuration (Escribir la configuración)** y especifique los valores o elija **Load JSON from S3 (Cargar JSON desde S3)** y especifique un archivo de configuración JSON. Para obtener más información, consulte [Configurando JupyterHub](emr-jupyterhub-configure.md).

1. En **Add steps (optional) (Añadir pasos (opcional))** configure los pasos que se ejecutarán cuando se cree el clúster, asegúrese de que no se ha seleccionado **Auto-terminate cluster after the last step is completed (Terminar automáticamente el clúster después de que se complete el último paso)** y elija **Next (Siguiente)**.

1. Elija opciones de **Hardware Configuration (Configuración de hardware)** y **Next (Siguiente)**. Para obtener más información, consulte [Configuración del hardware y las redes de los clústeres](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-instances.html) en la *Guía de administración de Amazon EMR*.

1. Elija las opciones de **General Cluster Settings (Configuración general del clúster)** y **Next (Siguiente)**.

1. Elija **Security Options (Opciones de seguridad)**, especifique un par de claves y, a continuación, elija **Create Cluster (Crear clúster)**.

## Crea un clúster JupyterHub con el AWS CLI
<a name="emr-jupyterhub-launch-cli"></a>

Para lanzar un clúster con JupyterHub, utilice el `aws emr create-cluster` comando y, para la `--applications` opción, especifique`Name=JupyterHub`. El siguiente ejemplo lanza un JupyterHub clúster en Amazon EMR con dos instancias EC2 (una instancia maestra y una instancia principal). Además, la depuración está habilitada y los registros se almacenan en la ubicación de Amazon S3 especificada mediante `--log-uri`. El par de claves especificado proporciona acceso a las instancias de Amazon EC2 del clúster.

**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

```
aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
--applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
--use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair
```

# Consideraciones al usarlo JupyterHub en Amazon EMR
<a name="emr-jupyterhub-considerations"></a>

Tenga en cuenta lo siguiente cuando lo utilice JupyterHub en Amazon EMR.
+ 
**aviso**  
Los blocs de notas y los archivos de usuario se guardan en el sistema de archivos en el nodo principal. Se trata de un almacenamiento efímero que no se conserva al terminar el clúster. Cuando un clúster termina, estos datos se pierden si no se ha hecho una copia de seguridad. Le recomendamos que programe copias de seguridad periódicas con trabajos `cron` u otros medios adecuados para su aplicación.  
Además, los cambios de configuración realizados en el contenedor no se pueden mantener si se reinicia el contenedor. Le recomendamos que cree un script o automatice la configuración de contenedores de otra forma para que pueda reproducir personalizaciones más fácilmente.
+ No se admite la autenticación de Kerberos que se ha configurado con una configuración de seguridad de Amazon EMR.
+ [OAuthenticator](https://github.com/jupyterhub/oauthenticator) no se admite.

# Configurando JupyterHub
<a name="emr-jupyterhub-configure"></a>

Puede personalizar la configuración de los blocs de JupyterHub notas de Amazon EMR y de los usuarios individuales conectándose al nodo principal del clúster y editando los archivos de configuración. Después de cambiar los valores, reinicie el contenedor `jupyterhub`.

Modifique las propiedades de los siguientes archivos para configurar JupyterHub cuadernos de Jupyter individuales:
+ `jupyterhub_config.py`: de forma predeterminada, este archivo se guarda en el directorio de `/etc/jupyter/conf/` del nodo maestro. Para obtener más información, consulte [Conceptos básicos de configuración](http://jupyterhub.readthedocs.io/en/latest/getting-started/config-basics.html) en la documentación. JupyterHub 
+ `jupyter_notebook_config.py`: este archivo se guarda en el directorio `/etc/jupyter/` de forma predeterminada y se copia en el contenedor `jupyterhub` como la opción predeterminada. Para obtener más información, consulte [Config file and command line options](https://jupyter-notebook.readthedocs.io/en/5.7.4/config.html) en la documentación de Jupyter Notebook.

También puede utilizar la clasificación de configuración `jupyter-sparkmagic-conf` al crear un clúster para personalizar Sparkmagic, que actualiza los valores del archivo `config.json` para Sparkmagic. Para obtener más información sobre los ajustes disponibles, consulta [example\$1config.json](https://github.com/jupyter-incubator/sparkmagic/blob/master/sparkmagic/example_config.json) en. GitHub Para obtener más información sobre cómo usar clasificaciones de configuración con aplicaciones en Amazon EMR, consulte [Configuración de aplicaciones](emr-configure-apps.md).

En el siguiente ejemplo, se lanza un clúster utilizando el archivo `MyJupyterConfig.json` para los ajustes AWS CLI de clasificación de la configuración de Sparkmagic.

**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

```
aws emr create-cluster --use-default-roles --release-label emr-5.14.0 \
--applications Name=Jupyter --instance-type m4.xlarge --instance-count 3 \
--ec2-attributes KeyName=MyKey,SubnetId=subnet-1234a5b6 --configurations file://MyJupyterConfig.json
```

El contenido de ejemplo de `MyJupyterConfig.json` es el siguiente:

```
[
    {
    "Classification":"jupyter-sparkmagic-conf",
    "Properties": {
      "kernel_python_credentials" : "{\"username\":\"diego\",\"base64_password\":\"mypass\",\"url\":\"http:\/\/localhost:8998\",\"auth\":\"None\"}"
      }
    }
]
```

**nota**  
Con la versión 5.21.0 y posteriores de Amazon EMR, puede anular las configuraciones de clúster y especificar las clasificaciones de configuración adicionales para cada grupo de instancias en un clúster en ejecución. Para ello, utilice la consola Amazon EMR, el AWS Command Line Interface (AWS CLI) o el AWS SDK. Para obtener más información, consulte [Suministrar una configuración para un grupo de instancias en un clúster en ejecución](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html).

# Configuración de la persistencia de los cuadernos en Amazon S3
<a name="emr-jupyterhub-s3"></a>

Puede configurar un JupyterHub clúster en Amazon EMR para que las libretas guardadas por un usuario permanezcan en Amazon S3, fuera del almacenamiento efímero de las instancias EC2 del clúster.

Para especificar la persistencia en Amazon S3, utilice la clasificación de configuración `jupyter-s3-conf` al crear el clúster. Para obtener más información, consulte [Configuración de aplicaciones](emr-configure-apps.md).

Además de habilitar la persistencia de Amazon S3 utilizando la propiedad `s3.persistence.enabled`, debe utilizar la propiedad `s3.persistence.bucket` para especificar el bucket en Amazon S3 donde se guardan los cuadernos. Los blocs de notas de cada usuario se guardan en una carpeta `jupyter/jupyterhub-user-name` del bucket especificado. El bucket ya debe existir en Amazon S3, y el rol para el perfil de instancia de EC2 que especifique al crear el clúster debe tener permisos para el bucket (de forma predeterminada, el rol es `EMR_EC2_DefaultRole`). Para obtener más información, consulte [Configurar las funciones de IAM para los permisos AWS de Amazon EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles.html) a los servicios.

Cuando se lanza un nuevo clúster con las mismas propiedades de clasificación de configuración, los usuarios pueden abrir los blocs de notas con el contenido de la ubicación donde se guardaron.

Tenga en cuenta que, si importa archivos como módulos en un cuaderno con Amazon S3 activado, los archivos se subirán a Amazon S3. Cuando importa archivos sin habilitar la persistencia de Amazon S3, se cargan en su JupyterHub contenedor. 

En el siguiente ejemplo, se habilita la persistencia de Amazon S3. Los blocs de notas guardados por los usuarios se almacenan en la carpeta `s3://MyJupyterBackups/jupyter/jupyterhub-user-name` de cada usuario, donde `jupyterhub-user-name` es un nombre de usuario, como por ejemplo `diego`.

```
[
    {
        "Classification": "jupyter-s3-conf",
        "Properties": {
            "s3.persistence.enabled": "true",
            "s3.persistence.bucket": "MyJupyterBackups"
        }
    }
]
```

# Conexión al nodo maestro y a los servidores de blocs de notas
<a name="emr-jupyterhub-connect"></a>

JupyterHub los administradores y los usuarios de portátiles deben conectarse al nodo principal del clúster mediante un túnel SSH y, a continuación, conectarse a las interfaces web servidas por JupyterHub el nodo maestro. Para obtener más información sobre la configuración de un túnel SSH y el uso del túnel para conexiones web proxy, consulte [Conectar con el clúster](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html) en la *Guía de administración de Amazon EMR*.

De forma predeterminada, JupyterHub en Amazon EMR está disponible a través del **puerto 9443** del nodo principal. El JupyterHub proxy interno también sirve a las instancias de notebook a través del puerto 9443. JupyterHub y se puede acceder a las interfaces web de Jupyter mediante una URL con el siguiente patrón:

****https://:9443 *MasterNodeDNS*****

Puede especificar otro puerto con la propiedad `c.JupyterHub.port` en el archivo `jupyterhub_config.py`. Para obtener más información, consulte [Conceptos básicos de redes](http://jupyterhub.readthedocs.io/en/latest/getting-started/networking-basics.html) en la documentación. JupyterHub 

De forma predeterminada, JupyterHub en Amazon EMR utiliza un certificado autofirmado para el cifrado SSL mediante HTTPS. Se pide a los usuarios que confíen en el certificado autofirmado cuando se conecten. Puede utilizar un certificado de confianza y sus propias claves. Reemplace el archivo de certificado predeterminado, `server.crt`, y el archivo de claves `server.key` en el directorio `/etc/jupyter/conf/` del nodo principal por sus propios archivos de certificados y claves. Utilice las propiedades `c.JupyterHub.ssl_key` y `c.JupyterHub.ssl_cert` en el archivo `jupyterhub_config.py` para especificar sus materiales SSL. Para obtener más información, consulte la [configuración de seguridad](https://jupyterhub.readthedocs.io/en/latest/tutorial/getting-started/security-basics.html) en la JupyterHub documentación. Después de actualizar `jupyterhub_config.py`, reinicie el contenedor.

# JupyterHub configuración y administración
<a name="emr-jupyterhub-administer"></a>

JupyterHub y los componentes relacionados se ejecutan dentro de un contenedor Docker cuyo nombre `jupyterhub` es el que ejecuta el sistema operativo Ubuntu. Existen varias maneras en las que puede administrar los componentes que se ejecutan en el contenedor.

**aviso**  
Es posible que las personalizaciones que realice en el contenedor no se mantengan si se reinicia el contenedor. Le recomendamos que cree un script o automatice la configuración de contenedores de otra forma para que pueda reproducir personalizaciones más fácilmente.

## Administración mediante la línea de comandos
<a name="emr-jupyterhub-administer-cli"></a>

Cuando se conecta al nodo principal mediante SSH, puede emitir comandos utilizando la interfaz de línea de comandos (CLI) de Docker y especificando el contenedor por nombre (`jupyterhub`) o ID. Por ejemplo, `sudo docker exec jupyterhub command` ejecuta los comandos que reconoce el sistema operativo o una aplicación que se ejecuta en el contenedor. Puede utilizar este método para añadir usuarios al sistema operativo y para instalar aplicaciones y bibliotecas adicionales en el contenedor de Docker. Por ejemplo, la imagen de contenedor predeterminada incluye Conda para la instalación de paquetes, por lo que puede ejecutar el siguiente comando en la línea de comandos del nodo principal para instalar una aplicación, Keras, en el contenedor:

```
sudo docker exec jupyterhub conda install keras
```

## Administración mediante el envío de pasos
<a name="emr-jupyterhub-administer-steps"></a>

Los pasos son una forma de enviar el trabajo a un clúster. Puede enviar pasos cuando al lanzar un clúster o bien puede enviar pasos a un clúster en ejecución. Los comandos que se ejecutan en la línea de comandos se pueden enviar como pasos usando `command-runner.jar`. Para obtener más información, consulte [Uso de pasos con la CLI y la consola](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-work-with-steps.html) en la *Guía de administración de Amazon EMR* y [Ejecución de comandos y scripts en un clúster de Amazon EMR](emr-commandrunner.md).

Por ejemplo, puede usar el siguiente AWS CLI comando en un equipo local para instalar Keras de la misma manera que lo hizo desde la línea de comandos del nodo maestro en el ejemplo anterior:

```
aws emr add-steps --cluster-id MyClusterID --steps Name="Command Runner",Jar="command-runner.jar",Args="/usr/bin/sudo","/usr/bin/docker","exec","jupyterhub","conda","install","keras"
```

También puede crear un script de una secuencia de pasos, cargar el script en Amazon S3 y usar `script-runner.jar` para ejecutar el script cuando cree el clúster o agregar el script como un paso. Para obtener más información, consulte [Ejecución de comandos y scripts en un clúster de Amazon EMR](emr-commandrunner.md). Para ver un ejemplo, consulta [Ejemplo: script bash para agregar varios usuarios](emr-jupyterhub-pam-users.md#emr-jupyterhub-script-multuser).

## Administración mediante REST APIs
<a name="emr-jupyterhub-administer-rest"></a>

Jupyter y el proxy HTTP para JupyterHub proporcionar REST APIs que puede usar para enviar solicitudes. JupyterHub Para enviar solicitudes a JupyterHub, debes pasar un token de API con la solicitud. Puede utilizar el comando `curl` de la línea de comandos del nodo principal para ejecutar comandos REST. Para obtener más información, consulte los siguientes recursos:
+ [Utiliza JupyterHub la API REST](http://jupyterhub.readthedocs.io/en/latest/reference/rest.html) en la documentación de JupyterHub, que incluye instrucciones para generar los tokens de API
+ La API del [servidor Jupyter Notebook está activada](https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API) GitHub
+ [configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy)activado GitHub

En el siguiente ejemplo, se muestra el uso de la API REST JupyterHub para obtener una lista de usuarios. El comando pasa un token de administración generado previamente y usa el puerto predeterminado, 9443 JupyterHub, para canalizar el resultado a [jq](https://stedolan.github.io/jq/) para facilitar la visualización:

```
curl -XGET -s -k https://$HOST:9443/hub/api/users \
-H "Authorization: token $admin_token" | jq .
```

# Agregar usuarios y administradores de Cuadernos de Jupyter
<a name="emr-jupyterhub-user-access"></a>

Puede utilizar uno de los dos métodos para que los usuarios se autentiquen, de JupyterHub modo que puedan crear libretas y, de forma opcional, administrarlas. JupyterHub El método más sencillo es utilizar el módulo JupyterHub de autenticación conectable (PAM). Además, JupyterHub en Amazon EMR es compatible con el [complemento de autenticación LDAP JupyterHub para](https://github.com/jupyterhub/ldapauthenticator/) obtener las identidades de los usuarios de un servidor LDAP, como un servidor Microsoft Active Directory. En esta sección se proporcionan instrucciones y ejemplos para añadir usuarios con cada método de autenticación.

JupyterHub en Amazon EMR tiene un usuario predeterminado con permisos de administrador. El nombre de usuario es `jovyan` y la contraseña es `jupyter`. Le recomendamos que reemplace el usuario por otro que tenga permisos administrativos. Para ello, puede utilizar un paso cuando cree el clúster o conectarse al nodo principal cuando se ejecute el clúster.

**Topics**
+ [Uso de la autenticación PAM](emr-jupyterhub-pam-users.md)
+ [Uso de la autenticación LDAP](emr-jupyterhub-ldap-users.md)
+ [Suplantación de usuarios](emr-jupyterhub-user-impersonation.md)

# Uso de la autenticación PAM
<a name="emr-jupyterhub-pam-users"></a>

La creación de usuarios de PAM JupyterHub en Amazon EMR es un proceso de dos pasos. El primer paso es añadir usuarios al sistema operativo que se está ejecutando en el contenedor `jupyterhub` del nodo principal y añadir un directorio de inicio correspondiente a cada usuario. El segundo paso consiste en añadir a estos usuarios del sistema operativo como JupyterHub usuarios, un proceso que se conoce como inclusión en una lista blanca. JupyterHub Una vez agregado un JupyterHub usuario, este puede conectarse a la JupyterHub URL y proporcionar las credenciales de acceso de su sistema operativo.

Cuando un usuario inicia sesión, JupyterHub abre la instancia del servidor portátil de ese usuario, que se guarda en el directorio principal del usuario en el nodo principal, que es`/var/lib/jupyter/home/username`. Si no existe una instancia de servidor de notebook, JupyterHub genera una instancia de notebook en el directorio principal del usuario. En las siguientes secciones se muestra cómo añadir usuarios de forma individual al sistema operativo y a él JupyterHub, seguido de un rudimentario script bash que añade varios usuarios.

## Agregar un usuario de sistema operativo al contenedor
<a name="emr-jupyterhub-system-user"></a>

El siguiente ejemplo primero usa el comando [useradd](https://linux.die.net/man/8/useradd) en el contenedor para añadir un solo usuario, diego, y crear un directorio de inicio para ese usuario. El segundo comando utiliza [chpasswd](https://linux.die.net/man/8/chpasswd) para establecer la contraseña diego para este usuario. Los comandos se ejecutan en la línea de comandos del nodo principal mientras están conectados mediante SSH. También puede ejecutar estos comandos usando un paso tal como se ha descrito anteriormente en [Administración mediante el envío de pasos](emr-jupyterhub-administer.md#emr-jupyterhub-administer-steps).

```
sudo docker exec jupyterhub useradd -m -s /bin/bash -N diego
sudo docker exec jupyterhub bash -c "echo diego:diego | chpasswd"
```

## Añadir un usuario JupyterHub
<a name="emr-jupyterhub-jupyterhub-user"></a>

Puede usar el panel de **administración** JupyterHub o la API REST para agregar usuarios y administradores, o solo usuarios.

**Para añadir usuarios y administradores mediante el panel de administración de JupyterHub**

1. Conéctese al nodo principal mediante SSH e inicie sesión en https: //:9443 *MasterNodeDNS* con una identidad que tenga permisos de administrador.

1. Elija **Control Panel (Panel de control)**, **Admin (Administración)**.

1. Elija **User (Usuario)**, **Add Users (Añadir usuarios)** o elija **Admin (Administrador)**, **Add Admins** (Añadir administradores).

**Para añadir un usuario con la API de REST**

1. Conéctese al nodo principal con SSH y utilice el siguiente comando en él o ejecute el comando como un paso.

1. Adquiera un token administrativo para realizar solicitudes a la API y sustitúyalo por ese token *AdminToken* en el siguiente paso.

1. Usa el siguiente comando y *UserName* sustitúyelo por un usuario del sistema operativo que se haya creado en el contenedor.

   ```
   curl -XPOST -H "Authorization: token AdminToken" "https://$(hostname):9443/hub/api/users/UserName
   ```

**nota**  
Al iniciar sesión en la interfaz JupyterHub web por primera vez, se le añade automáticamente como usuario JupyterHub no administrador.

## Ejemplo: script bash para agregar varios usuarios
<a name="emr-jupyterhub-script-multuser"></a>

El siguiente ejemplo de script bash combina los pasos anteriores de esta sección para crear varios JupyterHub usuarios. El script puede ejecutarse directamente en el nodo maestro o puede cargarse en Amazon S3 y, a continuación, ejecutarse como un paso.

El script establece primero una matriz de nombres de usuario y utiliza el comando `jupyterhub token` para crear un token de API para el administrador predeterminado, jovyan. A continuación, crea un usuario de sistema operativo en el contenedor `jupyterhub` para cada usuario, asignando a cada uno una contraseña inicial igual que su nombre de usuario. Por último, llama a la operación de la API REST para crear cada usuario. JupyterHub Pasa el token generado anteriormente en el script y canaliza la respuesta REST a `jq` para facilitar su visualización.

```
# Bulk add users to container and JupyterHub with temp password of username
set -x
USERS=(shirley diego ana richard li john mary anaya)
TOKEN=$(sudo docker exec jupyterhub /opt/conda/bin/jupyterhub token jovyan | tail -1)
for i in "${USERS[@]}"; 
do 
   sudo docker exec jupyterhub useradd -m -s /bin/bash -N $i
   sudo docker exec jupyterhub bash -c "echo $i:$i | chpasswd"
   curl -XPOST --silent -k https://$(hostname):9443/hub/api/users/$i \
 -H "Authorization: token $TOKEN" | jq
done
```

Guarde el script en una ubicación en Amazon S3, como `s3://amzn-s3-demo-bucket/createjupyterusers.sh`. A continuación, puede utilizar `script-runner.jar` para ejecutarlo como un paso.

### Ejemplo: ejecución del script al crear un clúster (AWS CLI)
<a name="emr-jupyterhub-multuser-createcluster"></a>

**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

```
aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
--applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
--use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \
--steps Type=CUSTOM_JAR,Name=CustomJAR,ActionOnFailure=CONTINUE,\
Jar=s3://region.elasticmapreduce/libs/script-runner/script-runner.jar,Args=["s3://amzn-s3-demo-bucket/createjupyterusers.sh"]
```

### Ejecución del script en un clúster existente (AWS CLI)
<a name="emr-jupyterhub-multuser-runningcluster"></a>

**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

```
aws emr add-steps --cluster-id j-XXXXXXXX --steps Type=CUSTOM_JAR,\
Name=CustomJAR,ActionOnFailure=CONTINUE,\
Jar=s3://region.elasticmapreduce/libs/script-runner/script-runner.jar,Args=["s3://amzn-s3-demo-bucket/createjupyterusers.sh"]
```

# Uso de la autenticación LDAP
<a name="emr-jupyterhub-ldap-users"></a>

El protocolo ligero de acceso a directorios (LDAP) es un protocolo de aplicación para consultar y modificar objetos que corresponden a recursos como usuarios y equipos almacenados en un proveedor de servicios de directorio compatible con LDAP, como Active Directory o un servidor OpenLDAP. Puede usar el [complemento de autenticación LDAP para JupyterHub Amazon EMR para JupyterHub](https://github.com/jupyterhub/ldapauthenticator/) usar LDAP para la autenticación de usuarios. El complemento controla las sesiones de inicio de sesión para usuarios LDAP y proporciona información de usuario a Jupyter. Esto permite a los usuarios conectarse a sus libretas JupyterHub y cuadernos utilizando las credenciales de sus identidades almacenadas en un servidor compatible con LDAP.

Los pasos de esta sección explican los siguientes pasos para configurar y habilitar LDAP mediante el complemento LDAP Authenticator para. JupyterHub Los pasos se realizan mientras está conectado a la línea de comandos del nodo principal. Para obtener más información, consulte [Conexión al nodo maestro y a los servidores de blocs de notas](emr-jupyterhub-connect.md).

1. Cree un archivo de configuración LDAP con información sobre el servidor LDAP, como la dirección IP del host, el puerto, los nombres de enlace, etc.

1. Modifique `/etc/jupyter/conf/jupyterhub_config.py` para habilitar el complemento de autenticación LDAP para JupyterHub.

1. Cree y ejecute un script que configure LDAP en el contenedor `jupyterhub`.

1. Consulte el LDAP para los usuarios y, a continuación, cree los directorios principales dentro del contenedor para cada usuario. JupyterHub requiere que los directorios principales alojen los blocs de notas.

1. Ejecute un script que se reinicie JupyterHub

**importante**  
Antes de configurar LDAP, pruebe la infraestructura de red para asegurarse de que el servidor LDAP y el nodo principal del clúster puedan comunicarse según sea necesario. TLS suele utilizar el puerto 389 a través de una conexión TCP sencilla. Si su conexión LDAP utiliza SSL, el puerto TCP conocido para SSL es 636.

## Crear del archivo de configuración de LDAP
<a name="emr-jupyterhub-ldap-config"></a>

En el siguiente ejemplo se utilizan los siguientes valores de configuración de marcador de posición. Reemplácelos por parámetros que coincidan con su implementación.
+ El servidor LDAP ejecuta la versión 3 y está disponible en el puerto 389. Es el puerto no SSL estándar para LDAP.
+ El nombre distinguido (DN) base es `dc=example, dc=org`.

Utilice un editor de texto para crear el archivo [ldap.conf](http://manpages.ubuntu.com/manpages/bionic/man5/ldap.conf.5.html), con un contenido similar al siguiente. Utilice valores apropiados para su implementación de LDAP. *host*Sustitúyalo por la dirección IP o el nombre de host que se pueda resolver del servidor LDAP.

```
base dc=example,dc=org
uri ldap://host
ldap_version 3
binddn cn=admin,dc=example,dc=org
bindpw admin
```

## Habilite el complemento de autenticación LDAP para JupyterHub
<a name="emr-jupyterhub-ldap-plugin"></a>

Utilice un editor de texto para modificar el archivo `/etc/jupyter/conf/jupyterhub_config.py` y añadir propiedades [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) similares a las siguientes. *host*Sustitúyalo por la dirección IP o el nombre de host resoluble del servidor LDAP. En el ejemplo se supone que los objetos de usuario se encuentran dentro de una unidad organizativa denominada *people* ou y se utilizan los componentes de nombres distintivos que se establecieron anteriormente. `ldap.conf`

```
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.use_ssl = False
c.LDAPAuthenticator.server_address = 'host' 
c.LDAPAuthenticator.bind_dn_template = 'cn={username},ou=people,dc=example,dc=org'
```

## Configuración de LDAP en el contenedor
<a name="emr-jupyterhub-ldap-container"></a>

Utilice un editor de texto para crear un script bash con los siguientes contenidos:

```
#!/bin/bash

# Uncomment the following lines to install LDAP client libraries only if
# using Amazon EMR release version 5.14.0. Later versions install libraries by default.
# sudo docker exec jupyterhub bash -c "sudo apt-get update"
# sudo docker exec jupyterhub bash -c "sudo apt-get -y install libnss-ldap libpam-ldap ldap-utils nscd"
 
# Copy ldap.conf
sudo docker cp ldap.conf jupyterhub:/etc/ldap/
sudo docker exec jupyterhub bash -c "cat /etc/ldap/ldap.conf"
 
# configure nss switch
sudo docker exec jupyterhub bash -c "sed -i 's/\(^passwd.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^group.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^shadow.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "cat /etc/nsswitch.conf"
 
# configure PAM to create home directories
sudo docker exec jupyterhub bash -c "echo 'session required        pam_mkhomedir.so skel=/etc/skel umask=077' >> /etc/pam.d/common-session"
sudo docker exec jupyterhub bash -c "cat /etc/pam.d/common-session"
 
# restart nscd service
sudo docker exec jupyterhub bash -c "sudo service nscd restart"
 
# Test
sudo docker exec jupyterhub bash -c "getent passwd"

# Install ldap plugin
sudo docker exec jupyterhub bash -c "pip install jupyterhub-ldapauthenticator"
```

Guarde el script en el nodo principal y, a continuación, ejecútelo desde la línea de comandos del nodo principal. Por ejemplo, con el script guardado como `configure_ldap_client.sh` haga que el archivo sea ejecutable:

```
chmod +x configure_ldap_client.sh
```

Y ejecute el script:

```
./configure_ldap_client.sh
```

## Adición de atributos a Active Directory
<a name="emr-jupyterhub-ldap-adproperties"></a>

Para encontrar a cada usuario y crear la entrada adecuada en la base de datos, el contenedor JupyterHub docker requiere las siguientes propiedades de UNIX para el objeto de usuario correspondiente en Active Directory. Para obtener más información, consulte la sección *¿Cómo puedo seguir editando los atributos del GID/UID RFC 2307 ahora que el complemento Unix Attributes ya no está disponible para el complemento MMC Usuarios y equipos de Active Directory*? en el artículo, [aclaraciones sobre el estado de la administración de identidades para Unix (IDMU) y la función del servidor NIS en la versión preliminar técnica de Windows Server 2016 y](https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/) versiones posteriores.
+ `homeDirectory`

  Esta es la ubicación del directorio de inicio del usuario, que suele ser `/home/username`.
+ `gidNumber`

  Es un valor mayor que 60 000 que todavía no esté utilizando ningún otro usuario. Compruebe en el archivo `etc/passwd` cuáles son los gids en uso.
+ `uidNumber`

  Es un valor mayor que 60 000 que todavía no esté utilizando ningún otro grupo. Compruebe en el archivo `etc/group` cuáles son los uids en uso.
+ `uid`

  Esto es lo mismo que el. *username*

## Crear directorios de inicio de los usuarios
<a name="emr-jupyterhub-ldap-directories"></a>

JupyterHub necesita directorios principales dentro del contenedor para autenticar a los usuarios de LDAP y almacenar los datos de las instancias. El siguiente ejemplo muestra dos usuarios, *shirley* y *diego*, en el directorio LDAP.

El primer paso consiste en consultar al servidor LDAP la información sobre el identificador de usuario y el identificador de grupo de cada usuario mediante [ldapsearch](http://manpages.ubuntu.com/manpages/xenial/man1/ldapsearch.1.html), como se muestra en el siguiente ejemplo, y sustituirlo por la dirección IP o el nombre de *host* host resoluble del servidor LDAP:

```
ldapsearch -x -H ldap://host \
 -D "cn=admin,dc=example,dc=org" \
 -w admin \
 -b "ou=people,dc=example,dc=org" \
 -s sub \
 "(objectclass=*)" uidNumber gidNumber
```

El comando `ldapsearch` devuelve una respuesta con formato LDIF que se parece a la siguiente para los usuarios *shirley* y *diego*.

```
# extended LDIF

# LDAPv3
# base <ou=people,dc=example,dc=org> with scope subtree
# filter: (objectclass=*)
# requesting: uidNumber gidNumber sn 

# people, example.org
dn: ou=people,dc=example,dc=org

# diego, people, example.org
dn: cn=diego,ou=people,dc=example,dc=org
sn: B
uidNumber: 1001
gidNumber: 100

# shirley, people, example.org
dn: cn=shirley,ou=people,dc=example,dc=org
sn: A
uidNumber: 1002
gidNumber: 100

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```

Con la información de la respuesta, ejecute comandos en el contenedor para crear un directorio de inicio para cada nombre común de usuario (`cn`). Utilice `uidNumber` y `gidNumber` para fijar la propiedad del directorio de inicio de ese usuario. Los siguientes comandos de ejemplo hacen esto para el usuario. *shirley*

```
sudo docker container exec jupyterhub bash -c "mkdir /home/shirley"
sudo docker container exec jupyterhub bash -c "chown -R $uidNumber /home/shirley"
sudo docker container exec jupyterhub bash -c "sudo chgrp -R $gidNumber /home/shirley"
```

**nota**  
El autenticador LDAP no JupyterHub admite la creación de usuarios locales. Para obtener más información, consulte [Nota de la configuración del autenticador LDAP sobre la creación de usuarios locales](https://github.com/jupyterhub/ldapauthenticator#configuration-note-on-local-user-creation).   
Para crear manualmente un usuario local, utilice el siguiente comando.  

```
sudo docker exec jupyterhub bash -c "echo 'shirley:x:$uidNumber:$gidNumber::/home/shirley:/bin/bash' >> /etc/passwd"
```

## Reinicie el contenedor JupyterHub
<a name="emr-jupyterhub-ldap-restart"></a>

Ejecute los siguientes comandos para reiniciar el contenedor de `jupyterhub`:

```
sudo docker stop jupyterhub
sudo docker start jupyterhub
```

# Suplantación de usuarios
<a name="emr-jupyterhub-user-impersonation"></a>

Un trabajo de Spark que se ejecute dentro de un cuaderno de Jupyter recorre varias aplicaciones durante su ejecución en Amazon EMR. Por ejemplo, Sparkmagic recibe PySpark tres códigos que un usuario ejecuta en Jupyter, y utiliza una solicitud HTTP POST para enviarlos a Livy, que luego crea un trabajo de Spark para ejecutarlo en el clúster mediante YARN.

De forma predeterminada, los trabajos de YARN enviados de esta manera se ejecutan como el usuario `livy`, con independencia de quién haya iniciado el trabajo. Al configurar la *suplantación de usuarios*, puede hacer que el ID de usuario del usuario del bloc de notas también sea el usuario asociado al trabajo de YARN. En lugar de que los trabajos iniciados por `shirley` y `diego` se asocien al usuario `livy`, los trabajos que inicia cada usuario se asocian a `shirley` y `diego`, respectivamente. Esto le ayuda a auditar el uso de Jupyter y a administrar las aplicaciones dentro de su organización.

Esta configuración solo se admite cuando las llamadas de Sparkmagic a Livy no están autenticadas. Las aplicaciones que proporcionan una capa de autenticación o delegación entre las aplicaciones de Hadoop y Livy (como Apache Knox Gateway) no se admiten. En los pasos de esta sección para configurar la suplantación de identidad de un usuario, se parte del supuesto de que JupyterHub Livy y Livy se ejecutan en el mismo nodo maestro. Si la aplicación tiene clústeres distintos, [Paso 3: Crear directorios de inicio de HDFS para los usuarios](#Step3-UserImpersonation) debe modificarse de manera que los directorios HDFS se creen en el nodo principal de Livy.

**Topics**
+ [Paso 1: Configurar Livy](#Step1-UserImpersonation)
+ [Paso 2: Añadir usuarios](#Step2-UserImpersonation)
+ [Paso 3: Crear directorios de inicio de HDFS para los usuarios](#Step3-UserImpersonation)

## Paso 1: Configurar Livy
<a name="Step1-UserImpersonation"></a>

Puede utilizar las clasificaciones de configuración `livy-conf` y `core-site` al crear un clúster para habilitar la suplantación de usuarios de Livy tal y como se muestra en el siguiente ejemplo. Guarde la clasificación de configuración como JSON y haga referencia a ella cuando cree el clúster o especifique la clasificación de configuración directamente. Para obtener más información, consulte [Configuración de aplicaciones](emr-configure-apps.md).

```
[
  {
    "Classification": "livy-conf",
    "Properties": {
      "livy.impersonation.enabled": "true"
    }
  },
  {
    "Classification": "core-site",
    "Properties": {
      "hadoop.proxyuser.livy.groups": "*",
      "hadoop.proxyuser.livy.hosts": "*"
    }
  }
]
```

## Paso 2: Añadir usuarios
<a name="Step2-UserImpersonation"></a>

Agregue JupyterHub usuarios mediante PAM o LDAP. Para obtener más información, consulte [Uso de la autenticación PAM](emr-jupyterhub-pam-users.md) y [Uso de la autenticación LDAP](emr-jupyterhub-ldap-users.md).

## Paso 3: Crear directorios de inicio de HDFS para los usuarios
<a name="Step3-UserImpersonation"></a>

Se ha conectado al nodo principal para crear usuarios. Mientras está conectado al nodo principal, copie el contenido que se indica a continuación y guárdelo en un archivo de script. El script crea directorios principales de HDFS para cada JupyterHub usuario del nodo principal. El script asume que está utilizando el ID de usuario administrador predeterminado,*jovyan*.

```
#!/bin/bash

CURL="curl --silent -k"
HOST=$(curl -s http://169.254.169.254/latest/meta-data/local-hostname)

admin_token() {
    local user=jovyan
    local pwd=jupyter
    local token=$($CURL https://$HOST:9443/hub/api/authorizations/token \
        -d "{\"username\":\"$user\", \"password\":\"$pwd\"}" | jq ".token")
    if [[ $token != null ]]; then
        token=$(echo $token | sed 's/"//g')
    else
        echo "Unable to get Jupyter API Token."
        exit 1
    fi
    echo $token
}

# Get Jupyter Admin token
token=$(admin_token)

# Get list of Jupyter users
users=$(curl -XGET -s -k https://$HOST:9443/hub/api/users \
 -H "Authorization: token $token" | jq '.[].name' | sed 's/"//g')

# Create HDFS home dir 
for user in ${users[@]}; 
do
 echo "Create hdfs home dir for $user"
 hadoop fs -mkdir /user/$user
 hadoop fs -chmod 777 /user/$user
done
```

# Instalación de kernels y bibliotecas adicionales
<a name="emr-jupyterhub-install-kernels-libs"></a>

Al crear un clúster con Amazon EMR, JupyterHub el núcleo de Python 3 predeterminado para Jupyter junto con los núcleos PySpark y Spark de Sparkmagic se instalan en el contenedor de Docker. Puede instalar kernels adicionales. También puede instalar bibliotecas y paquetes adicionales y, a continuación, importarlos al shell apropiado.

## Instalación de un kernel
<a name="emr-jupyterhub-install-kernels"></a>

Los kernels se instalan en el contenedor de Docker. La manera más fácil de conseguirlo es crear un script bash con comandos de instalación, guardarlo en el nodo principal y, a continuación, usar el comando `sudo docker exec jupyterhub script_name` para ejecutar el script en el contenedor `jupyterhub`. El siguiente script de ejemplo instala el kernel y, a continuación, instala algunas bibliotecas para ese kernel en el nodo principal para que más tarde pueda importar las bibliotecas utilizando el kernel en Jupyter.

```
#!/bin/bash

# Install Python 2 kernel
conda create -n py27 python=2.7 anaconda
source /opt/conda/envs/py27/bin/activate
apt-get update
apt-get install -y gcc
/opt/conda/envs/py27/bin/python -m pip install --upgrade ipykernel
/opt/conda/envs/py27/bin/python -m ipykernel install

# Install libraries for Python 2
/opt/conda/envs/py27/bin/pip install paramiko nltk scipy numpy scikit-learn pandas
```

Para instalar el kernel y las bibliotecas en el contenedor, abra una conexión de terminal al nodo principal, guarde el script en `/etc/jupyter/install_kernels.sh` y ejecute el siguiente comando en la línea de comandos del nodo principal:

```
sudo docker exec jupyterhub bash /etc/jupyter/install_kernels.sh
```

## Uso de bibliotecas e instalación de bibliotecas adicionales
<a name="emr-jupyterhub-install-libs"></a>

Amazon EMR viene preinstalado un conjunto básico de bibliotecas de ciencia de datos y aprendizaje automático para Python 3. JupyterHub Puede utilizar `sudo docker exec jupyterhub bash -c "conda list" ` y `sudo docker exec jupyterhub bash -c "pip freeze"`.

Si un trabajo de Spark necesita bibliotecas en los nodos de trabajo, le recomendamos que utilice una acción de arranque para ejecutar un script que instale las bibliotecas cuando cree el clúster. Las acciones de arranque se ejecutan en todos los nodos del clúster durante el proceso de creación de clúster, lo que simplifica la instalación. Si instala bibliotecas en nodos secundarios o de trabajo después un clúster esté en ejecución, la operación es más compleja. Proporcionamos un ejemplo programa en Python en esta sección que muestra cómo instalar estas bibliotecas.

La acción de arranque y los ejemplos de programas de Python mostrados en esta sección utilizan un script bash guardado en Amazon S3 para instalar las bibliotecas en todos los nodos.

El script al que se hace referencia en los siguientes ejemplos usa `pip` para instalar paramiko, nltk, scipy, scikit-learn y pandas para el kernel de Python 3:

```
#!/bin/bash

sudo python3 -m pip install boto3 paramiko nltk scipy scikit-learn pandas
```

Después de crear el script, cárguelo en una ubicación en Amazon S3, por ejemplo, `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`. Para obtener más información, consulte [Carga de objetos](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html) en la *Guía del usuario de Amazon Simple Storage Service* para que pueda utilizarlos en su acción de arranque o en su programa de Python.

**Para especificar una acción de arranque que instale bibliotecas en todos los nodos al crear un clúster mediante el AWS CLI**

1. Cree un script similar al ejemplo anterior y guárdelo en una ubicación en Amazon S3. Usamos el ejemplo `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`.

1. Cree el clúster con JupyterHub y utilice el `Path` argumento de la `--bootstrap-actions` opción para especificar la ubicación del script, como se muestra en el siguiente ejemplo:
**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

   ```
   aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
   --applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
   --use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \
   --bootstrap-actions Path=s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh,Name=InstallJupyterLibs
   ```

**Para especificar una acción de arranque que instale bibliotecas en todos los nodos cuando cree un clúster mediante la consola**

1. Vaya hasta la nueva consola de Amazon EMR y seleccione **Ir a la consola antigua** en el panel de navegación lateral. Para más información sobre lo que puede esperar al cambiar a la consola antigua, consulte [Uso de la consola antigua](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Elija **Crear clúster** e **Ir a las opciones avanzadas**.

1. Especifique la configuración de **Software and Steps (Software y pasos)** y de **Hardware** según sea apropiado para su aplicación.

1. En la pantalla **General Cluster Settings (Configuración de clúster general)**, expanda **Bootstrap Actions (Acciones de arranque)**.

1. En **Add bootstrap action (Añadir acción de arranque)**, seleccione **Custom action (Acción personalizada)**, **Configure and add (Configurar y añadir)**.

1. En **Name (Nombre)**, escriba un nombre fácil de recordar. En **Ubicación del script**, introduzca la ubicación del script en Amazon S3 (el ejemplo que utilizamos es *s3://amzn-s3-demo-bucket/ install-my-jupyter-libraries .sh*). Deje **Optional arguments (Argumentos opcionales)** en blanco y elija **Add (Añadir)**.

1. Especifique otros ajustes para el clúster y elija **Next (Siguiente)**.

1. Especifique la configuración de seguridad y seleccione **Create cluster (Crear clúster)**.

**Example Instalación de bibliotecas en los nodos principales de un clúster en ejecución**  
Después de instalar las bibliotecas en el nodo principal desde Jupyter, puede instalar bibliotecas en nodos secundarios en ejecución de varias maneras. El siguiente ejemplo muestra un programa Python escrito para ejecutarse en un equipo local. Cuando ejecutas el programa Python de forma local, utiliza `AWS-RunShellScript` of AWS Systems Manager para ejecutar el script de ejemplo, que se muestra anteriormente en esta sección, que instala bibliotecas en los nodos principales del clúster.  

```
import argparse
import time
import boto3


def install_libraries_on_core_nodes(cluster_id, script_path, emr_client, ssm_client):
    """
    Copies and runs a shell script on the core nodes in the cluster.

    :param cluster_id: The ID of the cluster.
    :param script_path: The path to the script, typically an Amazon S3 object URL.
    :param emr_client: The Boto3 Amazon EMR client.
    :param ssm_client: The Boto3 AWS Systems Manager client.
    """
    core_nodes = emr_client.list_instances(
        ClusterId=cluster_id, InstanceGroupTypes=["CORE"]
    )["Instances"]
    core_instance_ids = [node["Ec2InstanceId"] for node in core_nodes]
    print(f"Found core instances: {core_instance_ids}.")

    commands = [
        # Copy the shell script from Amazon S3 to each node instance.
        f"aws s3 cp {script_path} /home/hadoop",
        # Run the shell script to install libraries on each node instance.
        "bash /home/hadoop/install_libraries.sh",
    ]
    for command in commands:
        print(f"Sending '{command}' to core instances...")
        command_id = ssm_client.send_command(
            InstanceIds=core_instance_ids,
            DocumentName="AWS-RunShellScript",
            Parameters={"commands": [command]},
            TimeoutSeconds=3600,
        )["Command"]["CommandId"]
        while True:
            # Verify the previous step succeeded before running the next step.
            cmd_result = ssm_client.list_commands(CommandId=command_id)["Commands"][0]
            if cmd_result["StatusDetails"] == "Success":
                print(f"Command succeeded.")
                break
            elif cmd_result["StatusDetails"] in ["Pending", "InProgress"]:
                print(f"Command status is {cmd_result['StatusDetails']}, waiting...")
                time.sleep(10)
            else:
                print(f"Command status is {cmd_result['StatusDetails']}, quitting.")
                raise RuntimeError(
                    f"Command {command} failed to run. "
                    f"Details: {cmd_result['StatusDetails']}"
                )


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("cluster_id", help="The ID of the cluster.")
    parser.add_argument("script_path", help="The path to the script in Amazon S3.")
    args = parser.parse_args()

    emr_client = boto3.client("emr")
    ssm_client = boto3.client("ssm")

    install_libraries_on_core_nodes(
        args.cluster_id, args.script_path, emr_client, ssm_client
    )


if __name__ == "__main__":
    main()
```

# JupyterHub historial de versiones
<a name="JupyterHub-release-history"></a>

En la siguiente tabla se muestra la versión JupyterHub incluida en cada versión de Amazon EMR, junto con los componentes instalados con la aplicación. Para ver las versiones de los componentes de cada versión, consulte la sección Versiones de los componentes en la versión correspondiente de [Versiones de Amazon EMR 7.x](emr-release-7x.md), [Versiones de lanzamiento de Amazon EMR 6.x](emr-release-6x.md) o [Versiones de lanzamiento de Amazon EMR 5.x](emr-release-5x.md).


**JupyterHub información sobre la versión**  

| Etiqueta de versión de Amazon EMR | JupyterHub Versión | Componentes instalados con JupyterHub | 
| --- | --- | --- | 
| emr-7.12.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.11.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.10.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.9.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.8.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.7.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.6.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.5.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.4.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.3.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.2.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.2 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.1.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.0.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.15.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.14.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.13.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.12.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.11.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.11.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.10.1 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.10.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.9.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.9.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.8.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.8.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.7.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.6.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.35.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.5.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.4.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.3.1 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.3.0 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.2.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.2.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.1.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.1.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.0.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.0.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.34.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.33.1 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.33.0 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.32.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.32.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.31.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.31.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.2 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.29.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.28.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.28.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.27.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.27.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.26.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.25.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.24.1 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.24.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.23.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.23.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.22.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.2 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.20.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.20.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.19.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.19.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.18.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.18.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.2 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.16.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.16.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.15.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.15.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.2 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 