

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

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

[Jupyter Notebook](https://jupyter.org/) ist eine Open-Source-Webanwendung, mit der Sie Dokumente erstellen und teilen können, die Live-Code, Gleichungen, Visualisierungen und erläuternden Text enthalten. [JupyterHub](https://jupyterhub.readthedocs.io/en/latest/)ermöglicht es Ihnen, mehrere Instanzen eines Jupyter-Notebookservers für einen einzelnen Benutzer zu hosten. Wenn Sie einen Cluster mit erstellen JupyterHub, erstellt Amazon EMR einen Docker-Container auf dem Master-Knoten des Clusters. JupyterHub, alle für Jupyter und [Sparkmagic](https://github.com/jupyter-incubator/sparkmagic/blob/master/README.md) erforderlichen Komponenten werden innerhalb des Containers ausgeführt.

Sparkmagic ist eine Kernel-Bibliothek, mit der Jupyter-Notebooks mit [Apache Spark](https://aws.amazon.com/big-data/what-is-spark/) in Amazon EMR über [Apache Livy](emr-livy.md) interagieren. Dabei handelt es sich um einen REST-Server für Spark. Spark und Apache Livy werden automatisch installiert, wenn Sie mit JupyterHub einen Cluster erstellen. Der Standard-Python-3-Kernel für Jupiter ist zusammen mit den Kerneln PySpark 3,, und Spark verfügbar PySpark, die mit Sparkmagic verfügbar sind. Sie können diese Kernel verwenden, um ad-hoc-Spark-Code und interaktive SQL-Abfragen mit Python und Scala auszuführen. Sie können zusätzliche Kernel innerhalb des Docker-Containers manuell installieren. Weitere Informationen finden Sie unter [Installieren von zusätzlicher Kerneln und Bibliotheken](emr-jupyterhub-install-kernels-libs.md).

Das folgende Diagramm zeigt die Komponenten von JupyterHub on Amazon EMR mit den entsprechenden Authentifizierungsmethoden für Notebook-Benutzer und den Administrator. Weitere Informationen finden Sie unter [Hinzufügen von Jupyter-Notebook-Benutzern und Administratoren](emr-jupyterhub-user-access.md).

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


In der folgenden Tabelle sind die Version von JupyterHub aufgeführt, die in der neuesten Version der Amazon EMR 7.x-Serie enthalten ist, zusammen mit den Komponenten, mit denen Amazon EMR installiert wird. JupyterHub

Informationen zur Version der Komponenten, mit denen JupyterHub in dieser Version installiert wurde, finden Sie unter Komponentenversionen von [Version 7.12.0](emr-7120-release.md).


**JupyterHub Versionsinformationen für emr-7.12.0**  

| Amazon-EMR-Versionsbezeichnung | JupyterHub Version | Komponenten, die mit installiert wurden 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 | 

In der folgenden Tabelle sind die Version von JupyterHub aufgeführt, die in der neuesten Version der Amazon EMR 6.x-Serie enthalten ist, zusammen mit den Komponenten, mit denen Amazon EMR installiert wird. JupyterHub

Informationen zur Version der Komponenten, mit denen JupyterHub in dieser Version installiert wurde, finden Sie unter Komponentenversionen von [Version 6.15.0](emr-6150-release.md).


**JupyterHub Versionsinformationen für emr-6.15.0**  

| Amazon-EMR-Versionsbezeichnung | JupyterHub Version | Komponenten, die mit installiert wurden 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 | 

In der folgenden Tabelle sind die Version von JupyterHub aufgeführt, die in der neuesten Version der Amazon EMR 5.x-Serie enthalten ist, zusammen mit den Komponenten, mit denen Amazon EMR installiert wird. JupyterHub

Informationen zur Version der Komponenten, mit denen JupyterHub in dieser Version installiert wurde, finden Sie unter Komponentenversionen von [Version 5.36.2](emr-5362-release.md).


**JupyterHub Versionsinformationen für emr-5.36.2**  

| Amazon-EMR-Versionsbezeichnung | JupyterHub Version | Komponenten, die mit installiert wurden 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 | 

Der in Amazon EMR enthaltene JupyterHub Python-3-Kernel ist 3.6.4.

Die im `jupyterhub`-Container installierten Bibliotheken können zwischen Amazon-EMR-Versionen und Amazon-EC2-AMI-Versionen variieren.

**Installierte Bibliotheken mit `conda` auflisten**
+ Führen Sie den folgenden Befehl in der Befehlszeile des Master-Knotens aus:

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

**Installierte Bibliotheken mit `pip` auflisten**
+ Führen Sie den folgenden Befehl in der Befehlszeile des Master-Knotens aus:

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

**Topics**
+ [Erstellen Sie einen Cluster mit JupyterHub](emr-jupyterhub-launch.md)
+ [Überlegungen bei der Verwendung JupyterHub auf Amazon EMR](emr-jupyterhub-considerations.md)
+ [Konfiguration JupyterHub](emr-jupyterhub-configure.md)
+ [Konfigurieren von Persistenz für Notebooks in Amazon S3](emr-jupyterhub-s3.md)
+ [Eine Verbindung mit dem Hauptknoten und Notebook-Servern herstellen](emr-jupyterhub-connect.md)
+ [JupyterHub Konfiguration und Verwaltung](emr-jupyterhub-administer.md)
+ [Hinzufügen von Jupyter-Notebook-Benutzern und Administratoren](emr-jupyterhub-user-access.md)
+ [Installieren von zusätzlicher Kerneln und Bibliotheken](emr-jupyterhub-install-kernels-libs.md)
+ [JupyterHub Versionsverlauf](JupyterHub-release-history.md)

# Erstellen Sie einen Cluster mit JupyterHub
<a name="emr-jupyterhub-launch"></a>

Sie können einen Amazon EMR-Cluster JupyterHub mithilfe der AWS-Managementkonsole AWS Command Line Interface, oder der Amazon EMR-API erstellen. Stellen Sie sicher, dass der Cluster nicht mit der Option zum automatischen Beenden nach Abschluss der Schritte angelegt wird (Option `--auto-terminate` in der AWS CLI). Stellen Sie außerdem sicher, dass Administratoren und Notebook-Benutzer auf das Schlüsselpaar zugreifen können, das Sie beim Erstellen des Clusters verwenden. Weitere Informationen finden Sie unter [Verwenden eines Schlüsselpaars für SSH-Anmeldeinformationen](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-access-ssh.html) im *Verwaltungshandbuch für Amazon EMR*.

## Erstellen Sie einen Cluster JupyterHub mithilfe der Konsole
<a name="emr-jupyterhub-launch-console"></a>

Gehen Sie wie folgt vor, um einen Cluster mit JupyterHub installierten **erweiterten Optionen** in der Amazon EMR-Konsole zu erstellen.

**Um einen Amazon EMR-Cluster zu erstellen, der über die Amazon EMR-Konsole JupyterHub installiert ist**

1. Navigieren Sie zur neuen Amazon-EMR-Konsole und wählen Sie in der Seitennavigation die Option **Zur alten Konsole wechseln** aus. Weitere Informationen darüber, was Sie erwartet, wenn Sie zur alten Konsole wechseln, finden Sie unter [Verwenden der alten Konsole](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Wählen Sie **Create Cluster (Cluster erstellen)** und **Go to advanced options (Zu erweiterten Optionen)** aus.

1. Unter **Software Configuration (Softwarekonfiguration)**:
   + Wählen Sie für **Version** emr-5.36.2 aus und wählen Sie. JupyterHub
   + Wenn Sie Spark verwenden, um den AWS Glue-Datenkatalog als Metastore für Spark-SQL zu verwenden, wählen Sie Für **Spark-Tabellenmetadaten verwenden** aus. Weitere Informationen finden Sie unter [Verwenden Sie den AWS Glue Data Catalog-Katalog mit Spark auf Amazon EMR](emr-spark-glue.md).
   + Für **Edit software settings (Softwareeinstellungen bearbeiten)** wählen Sie die Option **Enter configuration (Konfiguration auswählen)** und geben Werte an, oder wählen **Load JSON von S3 (JSON aus S3 laden)** und geben eine JSON-Konfigurationsdatei an. Weitere Informationen finden Sie unter [Konfiguration JupyterHub](emr-jupyterhub-configure.md).

1. Konfigurieren Sie unter **Add steps (optional) (Schritte hinzufügen (optional))** die Schritte, die ausgeführt werden sollen, wenn der Cluster erstellt wird, stellen Sie sicher, dass **Auto-terminate cluster after the last step is completed (Cluster automatisch beenden, nachdem der letzte Schritt ausgeführt wurde)** nicht ausgewählt ist, und klicken Sie auf **Next (Weiter)**.

1. Wählen Sie die Option **Hardware Configuration (Hardwarekonfiguration)**, **Next (Weiter)**. Weitere Informationen finden Sie unter [Konfigurieren von Cluster-Hardware und Netzwerken](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-instances.html) im *Verwaltungshandbuch für Amazon EMR*.

1. Wählen Sie Optionen für **General Cluster Settings (Allgemeine Cluster-Einstellungen)**, **Next (Weiter)**.

1. Wählen Sie **Security Options (Sicherheitsoptionen)**, geben Sie ein Schlüsselpaar an und wählen Sie **Create Cluster (Cluster erstellen)**.

## Erstellen Sie einen Cluster JupyterHub mit AWS CLI
<a name="emr-jupyterhub-launch-cli"></a>

Um einen Cluster mit zu starten JupyterHub, verwenden Sie den `aws emr create-cluster` Befehl und geben Sie für die `--applications` Option Folgendes an`Name=JupyterHub`. Im folgenden Beispiel wird ein JupyterHub Cluster auf Amazon EMR mit zwei EC2-Instances (eine Master- und eine Core-Instance) gestartet. Außerdem ist das Debugging aktiviert, wobei die Protokolle am Amazon-S3-Speicherort gespeichert werden wie in `--log-uri` angegeben. Das angegebene Schlüsselpaar bietet Zugriff auf Amazon-EC2-Instances in dem Cluster.

**Anmerkung**  
Linux-Zeilenfortsetzungszeichen (\$1) sind aus Gründen der Lesbarkeit enthalten. Sie können entfernt oder in Linux-Befehlen verwendet werden. Entfernen Sie sie unter Windows oder ersetzen Sie sie durch ein Caret-Zeichen (^).

```
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
```

# Überlegungen bei der Verwendung JupyterHub auf Amazon EMR
<a name="emr-jupyterhub-considerations"></a>

Beachten Sie bei der Verwendung JupyterHub auf Amazon EMR Folgendes.
+ 
**Warnung**  
Benutzer-Notebooks und Dateien werden in dem Dateisystem auf dem Master-Knoten gespeichert. Hierbei handelt es sich um flüchtigen Speicher, der nach der Beendigung des Clusters nicht dauerhaft bestehen bleibt. Wenn ein Cluster beendet wird, gehen diese Daten verloren, wenn sie nicht gesichert sind. Wir empfehlen, dass Sie regelmäßige Sicherungen mithilfe von `cron`-Jobs oder anderen für Ihre Anwendung geeigneten Methoden einplanen.  
Außerdem bleiben Konfigurationsänderungen innerhalb des Containers bei einem Neustart des Containers möglicherweise nicht bestehen. Wir empfehlen Ihnen, die Containerkonfiguration per Skript vorzunehmen oder anderweitig zu automatisieren, damit Sie Anpassungen leichter reproduzieren können.
+ Kerberos-Authentifizierung, die mit einer Amazon-EMR-Sicherheitskonfiguration eingerichtet wurde, wird nicht unterstützt.
+ [OAuthenticator](https://github.com/jupyterhub/oauthenticator) wird nicht unterstützt.

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

Sie können die Konfiguration von Notebooks JupyterHub auf Amazon EMR und einzelnen Benutzern anpassen, indem Sie eine Verbindung zum Cluster-Masterknoten herstellen und die Konfigurationsdateien bearbeiten. Nachdem Sie Werte geändert haben, starten Sie den `jupyterhub`-Container.

Ändern Sie die Eigenschaften in den folgenden Dateien, um einzelne JupyterHub Jupyter-Notebooks zu konfigurieren:
+ `jupyterhub_config.py` – Diese Datei befindet sich standardmäßig im `/etc/jupyter/conf/`-Verzeichnis auf dem Hauptknoten. Weitere Informationen finden Sie in der Dokumentation unter [Grundlagen der Konfiguration](http://jupyterhub.readthedocs.io/en/latest/getting-started/config-basics.html). JupyterHub 
+ `jupyter_notebook_config.py` – Diese Datei wird im `/etc/jupyter/`-Verzeichnis gespeichert und standardmäßig in den `jupyterhub`-Container kopiert. Weitere Informationen finden Sie unter [Konfigurationsdatei und Befehlszeilen-Optionen](https://jupyter-notebook.readthedocs.io/en/5.7.4/config.html) in der Jupyter-Notebook-Dokumentation.

Sie können auch die Konfigurationsklassifizierung `jupyter-sparkmagic-conf` verwenden, um Sparkmagic anzupassen. Dadurch werden Werte in der `config.json`-Datei für Sparkmagic aktualisiert. Weitere Informationen zu verfügbaren Einstellungen finden Sie unter [example\$1config.json](https://github.com/jupyter-incubator/sparkmagic/blob/master/sparkmagic/example_config.json) unter. GitHub Weitere Informationen zur Verwendung von Konfigurationsklassifizierungen für Anwendungen in Amazon EMR finden Sie unter [Anwendungen konfigurieren](emr-configure-apps.md).

Im folgenden Beispiel wird ein Cluster mit dem gestartet AWS CLI, der auf die Datei `MyJupyterConfig.json` für die Sparkmagic-Konfigurationsklassifizierungseinstellungen verweist.

**Anmerkung**  
Linux-Zeilenfortsetzungszeichen (\$1) sind aus Gründen der Lesbarkeit enthalten. Sie können entfernt oder in Linux-Befehlen verwendet werden. Entfernen Sie sie unter Windows oder ersetzen Sie sie durch ein Caret-Zeichen (^).

```
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
```

Beispiele für den Inhalt der Datei `MyJupyterConfig.json`:

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

**Anmerkung**  
Ab Amazon-EMR-Version 5.21.0 können Sie Cluster-Konfigurationen überschreiben und zusätzliche Konfigurationsklassifikationen für jede Instance-Gruppe in einem ausgeführten Cluster angeben. Dazu verwenden Sie die Amazon EMR-Konsole, das AWS Command Line Interface (AWS CLI) oder das AWS SDK. Weitere Informationen finden Sie unter [Angeben einer Konfiguration für eine Instance-Gruppe in einem aktiven Cluster](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html).

# Konfigurieren von Persistenz für Notebooks in Amazon S3
<a name="emr-jupyterhub-s3"></a>

Sie können einen JupyterHub Cluster in Amazon EMR so konfigurieren, dass von einem Benutzer gespeicherte Notizbücher in Amazon S3 außerhalb des kurzlebigen Speichers auf Cluster-EC2-Instances bestehen bleiben.

Sie geben die Amazon-S3-Persistenz mithilfe der `jupyter-s3-conf`-Konfigurationsklassifizierung an, wenn Sie einen Cluster erstellen. Weitere Informationen finden Sie unter [Anwendungen konfigurieren](emr-configure-apps.md).

Zusätzlich zur Aktivierung der Amazon-S3-Persistenz mithilfe der Eigenschaft `s3.persistence.enabled` geben Sie einen Bucket in Amazon S3 an, in dem Notebooks mithilfe der Eigenschaft `s3.persistence.bucket` gespeichert werden. Notebooks für jeden Benutzer werden in einem `jupyter/jupyterhub-user-name`-Ordner im angegebenen Bucket gespeichert. Der Bucket muss bereits in Amazon S3 vorhanden sein und die Rolle für das EC2-Instance-Profil, die Sie bei der Erstellung des Clusters angeben, muss über Berechtigungen für den Bucket verfügen (standardmäßig ist die Rolle `EMR_EC2_DefaultRole`). Weitere Informationen finden [Sie unter Konfigurieren von IAM-Rollen für Amazon EMR-Berechtigungen](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles.html) für Dienste. AWS 

Wenn Sie einen neuen Cluster mit denselben Konfigurationsklassifizierungseigenschaften verwenden, können Benutzer Notebooks mit den Inhalten des Speicherorts öffnen.

Beachten Sie, dass wenn Sie Dateien als Module in ein Notebook importieren und Amazon S3 aktiviert haben, dies dazu führt, dass die Dateien auf Amazon S3 hochgeladen werden. Wenn Sie Dateien importieren, ohne die Amazon S3 S3-Persistenz zu aktivieren, werden sie in Ihren JupyterHub Container hochgeladen. 

Im folgenden Beispiel wird Amazon-S3-Persistenz aktiviert. Von Benutzern gespeicherte Notebooks werden im Ordner `s3://MyJupyterBackups/jupyter/jupyterhub-user-name` der einzelnen Benutzer gespeichert. Dabei ist `jupyterhub-user-name` ein Benutzername wie beispielsweise `diego`.

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

# Eine Verbindung mit dem Hauptknoten und Notebook-Servern herstellen
<a name="emr-jupyterhub-connect"></a>

JupyterHub Administratoren und Notebook-Benutzer müssen über einen SSH-Tunnel eine Verbindung zum Cluster-Masterknoten herstellen und dann eine Verbindung zu den Webschnittstellen herstellen, die JupyterHub auf dem Master-Knoten bedient werden. Weitere Informationen zum Konfigurieren eines SSH-Tunnels und zur Verwendung des Tunnels als Proxy für Web-Verbindungen finden Sie unter [Mit dem Cluster verbinden](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html) im *Verwaltungshandbuch für Amazon EMR*.

Standardmäßig ist EMR JupyterHub auf Amazon über **Port 9443** auf dem Master-Knoten verfügbar. Der interne JupyterHub Proxy bedient auch Notebook-Instances über Port 9443. JupyterHub und auf Jupyter-Webschnittstellen kann über eine URL mit dem folgenden Muster zugegriffen werden:

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

Sie können unter Verwendung der `c.JupyterHub.port`-Eigenschaft in der `jupyterhub_config.py`-Datei einen anderen Port angeben. Weitere Informationen finden Sie in der Dokumentation unter [Netzwerkgrundlagen](http://jupyterhub.readthedocs.io/en/latest/getting-started/networking-basics.html). JupyterHub 

Standardmäßig verwendet EMR JupyterHub auf Amazon ein selbstsigniertes Zertifikat für die SSL-Verschlüsselung mit HTTPS. Benutzer werden aufgefordert, das selbstsignierte Zertifikat als vertrauenswürdig einstufen, wenn sie eine Verbindung herstellen. Sie können ein vertrauenswürdiges Zertifikat und eigene Schlüssel verwenden. Ersetzen Sie die Standard-Zertifikatsdatei, `server.crt`, und die Schlüsseldatei, `server.key`, im `/etc/jupyter/conf/`-Verzeichnis auf dem Master-Knoten durch Ihre eigenen Zertifikat- und Schlüsseldateien. Verwenden Sie die Eigenschaften `c.JupyterHub.ssl_key` und `c.JupyterHub.ssl_cert` der `jupyterhub_config.py`-Datei zur Angabe Ihres SSL-Materialien. Weitere Informationen finden Sie in der [Dokumentation unter Sicherheitseinstellungen](https://jupyterhub.readthedocs.io/en/latest/tutorial/getting-started/security-basics.html). JupyterHub Nachdem Sie `jupyterhub_config.py` geändert haben, starten Sie den Container neu.

# JupyterHub Konfiguration und Verwaltung
<a name="emr-jupyterhub-administer"></a>

JupyterHub und verwandte Komponenten laufen in einem Docker-Container mit dem Namen`jupyterhub`, auf dem das Ubuntu-Betriebssystem ausgeführt wird. Sie haben mehrere Möglichkeiten, Komponenten zu verwalten, die innerhalb des Containers ausgeführt werden.

**Warnung**  
Anpassungen, die Sie innerhalb des Containers vornehmen, bleiben möglicherweise nicht erhalten, wenn der Container neu gestartet wird. Wir empfehlen Ihnen, die Containerkonfiguration per Skript vorzunehmen oder anderweitig zu automatisieren, damit Sie Anpassungen leichter reproduzieren können.

## Administration über die Befehlszeile
<a name="emr-jupyterhub-administer-cli"></a>

Wenn Sie mit dem Master-Knoten über SSH verbunden sind, können Sie Befehle über die Docker-Befehlszeilenschnittstelle (CLI) ausgeben und den Container per Namen (`jupyterhub`) oder ID angeben. Beispiel: `sudo docker exec jupyterhub command` führt Befehle aus, die vom Betriebssystem oder einer im Container ausgeführten Anwendung erkannt werden. Mit dieser Methode können Sie Benutzer zum Betriebssystem hinzufügen und zusätzliche Anwendungen und Bibliotheken innerhalb des Docker-Containers installieren. Beispiel: Das Standard-Container-Image enthält Conda für die Paketinstallation, sodass Sie den folgenden Befehl in der Befehlszeile des Master-Knotens ausführen können, um eine Anwendung, Keras, innerhalb des Containers zu installieren:

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

## Administration durch Übermitteln von Schritten
<a name="emr-jupyterhub-administer-steps"></a>

Schritte sind eine Möglichkeit, Arbeit an einen Cluster zu übermitteln. Schritte können Sie senden, wenn der Cluster gestartet oder ausgeführt wird. Befehle, die Sie in der Befehlszeile ausführen, können mit`command-runner.jar` als Schritte übermittelt werden. Weitere Informationen finden Sie unter [Arbeiten mit Schritten unter Verwendung der CLI und der Konsole](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-work-with-steps.html) im *Verwaltungshandbuch für Amazon EMR* und [Befehle und Skripte auf einem Amazon-EMR-Cluster ausführen](emr-commandrunner.md).

Sie könnten beispielsweise den folgenden AWS CLI Befehl auf einem lokalen Computer verwenden, um Keras auf die gleiche Weise zu installieren, wie Sie es im vorherigen Beispiel über die Befehlszeile des Master-Knotens getan haben:

```
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"
```

Sie können auch eine Folge von Schritten per Skript festlegen, das Skript in Amazon S3 hochladen und dann `script-runner.jar` verwenden, um das Skript auszuführen, wenn Sie den Cluster erstellen, oder das Skript als Schritt hinzufügen. Weitere Informationen finden Sie unter [Befehle und Skripte auf einem Amazon-EMR-Cluster ausführen](emr-commandrunner.md). Ein Beispiel finden Sie unter [Beispiel: Bash-Skript zum Hinzufügen mehrerer Benutzer](emr-jupyterhub-pam-users.md#emr-jupyterhub-script-multuser).

## Verwaltung mit REST APIs
<a name="emr-jupyterhub-administer-rest"></a>

Jupyter und der HTTP-Proxy für JupyterHub stellen REST bereit APIs , mit dem Sie Anfragen senden können. JupyterHub Um Anfragen an zu senden JupyterHub, müssen Sie der Anfrage ein API-Token beifügen. Mit dem Befehl `curl` können Sie von der Befehlszeile des Master-Knoten aus REST-Befehle ausführen. Weitere Informationen finden Sie in den folgenden Ressourcen:
+ [Verwenden JupyterHub der REST-API](http://jupyterhub.readthedocs.io/en/latest/reference/rest.html) in der Dokumentation für JupyterHub, die Anweisungen zum Generieren von API-Token enthält
+ [Jupyter Notebook-Server-API](https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API) aktiviert GitHub
+ [configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy)auf GitHub

Das folgende Beispiel zeigt die Verwendung der REST-API JupyterHub zum Abrufen einer Benutzerliste. Der Befehl übergibt ein zuvor generiertes Admin-Token und verwendet den Standardport 9443 für JupyterHub, um die Ausgabe zur besseren Anzeige an [jq weiterzuleiten:](https://stedolan.github.io/jq/)

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

# Hinzufügen von Jupyter-Notebook-Benutzern und Administratoren
<a name="emr-jupyterhub-user-access"></a>

Sie können eine von zwei Methoden verwenden, um sich für Benutzer zu authentifizieren, JupyterHub sodass sie Notizbücher erstellen und optional verwalten können. JupyterHub Die einfachste Methode ist die Verwendung JupyterHub des Pluggable Authentication Module (PAM). Darüber hinaus unterstützt EMR JupyterHub auf Amazon das [LDAP-Authentifikator-Plugin JupyterHub zum](https://github.com/jupyterhub/ldapauthenticator/) Abrufen von Benutzeridentitäten von einem LDAP-Server, z. B. einem Microsoft Active Directory-Server. Anweisungen und Beispiele für das Hinzufügen von Benutzern mit den beiden Authentifizierungsmethoden finden Sie in diesem Abschnitt.

JupyterHub hat auf Amazon EMR einen Standardbenutzer mit Administratorrechten. Der Benutzername ist `jovyan` , das Passwort ist `jupyter`. Wir empfehlen Ihnen dringend, den Benutzer durch einen anderen Benutzer mit Administratorrechten zu ersetzen. Dies ist mit einem Schritt beim Erstellen des Clusters oder durch das Herstellen einer Verbindung zum Master-Knoten möglich, während der Cluster ausgeführt wird.

**Topics**
+ [Verwenden der PAM-Authentifizierung](emr-jupyterhub-pam-users.md)
+ [Verwenden der LDAP-Authentifizierung](emr-jupyterhub-ldap-users.md)
+ [Benutzer-Identitätswechsel](emr-jupyterhub-user-impersonation.md)

# Verwenden der PAM-Authentifizierung
<a name="emr-jupyterhub-pam-users"></a>

Das Erstellen von PAM-Benutzern in JupyterHub Amazon EMR erfolgt in zwei Schritten. Der erste Schritt besteht darin, dem Betriebssystem, das im Container `jupyterhub` auf dem Master-Knoten ausgeführt wird, Benutzer hinzuzufügen, und für jeden Benutzer ein entsprechendes Benutzer-Stammverzeichnis hinzuzufügen. Der zweite Schritt besteht darin, diese Betriebssystembenutzer als JupyterHub Benutzer hinzuzufügen — ein Vorgang, der als Whitelisting bezeichnet wird. JupyterHub Nachdem ein JupyterHub Benutzer hinzugefügt wurde, kann er eine Verbindung zur JupyterHub URL herstellen und seine Betriebssystemanmeldeinformationen für den Zugriff angeben.

Wenn sich ein Benutzer anmeldet, JupyterHub wird die Notebook-Server-Instanz für diesen Benutzer geöffnet, die im Home-Verzeichnis des Benutzers auf dem Master-Knoten gespeichert ist`/var/lib/jupyter/home/username`. Wenn eine Notebook-Server-Instanz nicht existiert, JupyterHub wird eine Notebook-Instanz im Home-Verzeichnis des Benutzers erzeugt. In den folgenden Abschnitten wird gezeigt, wie Benutzer einzeln zum Betriebssystem und zu hinzugefügt werden JupyterHub, gefolgt von einem rudimentären Bash-Skript, das mehrere Benutzer hinzufügt.

## Hinzufügen eines Betriebssystembenutzers zum Container
<a name="emr-jupyterhub-system-user"></a>

Das folgende Beispiel verwendet den Befehl [useradd](https://linux.die.net/man/8/useradd) innerhalb des Containers, um einen einzelnen Benutzer hinzuzufügen, diego, und ein Stammverzeichnis für diesen Benutzer anzulegen. Der zweite Befehl verwendet [chpasswd](https://linux.die.net/man/8/chpasswd), um diego ein Passwort für diesen Benutzer zu erteilen. Die Befehle werden in der Befehlszeile auf dem Master-Knoten ausgeführt, während mit SSH eine Verbindung eingerichtet wird. Sie können diese Befehle auch mithilfe eines Schritts ausführen, wie zuvor in [Administration durch Übermitteln von Schritten](emr-jupyterhub-administer.md#emr-jupyterhub-administer-steps) beschrieben.

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

## Einen Benutzer hinzufügen JupyterHub
<a name="emr-jupyterhub-jupyterhub-user"></a>

Sie können das **Admin-Panel** in JupyterHub oder die REST-API verwenden, um Benutzer und Administratoren oder einfach nur Benutzer hinzuzufügen.

**So fügen Sie Benutzer und Administratoren über das Admin-Panel in hinzu JupyterHub**

1. Stellen Sie über SSH Connect zum Master-Knoten her und melden Sie sich *MasterNodeDNS* mit einer Identität mit Administratorrechten bei https: //:9443 an.

1. Wählen Sie **Control Panel (Systemsteuerung)**, **Admin (Administrator)**.

1. Wählen Sie **User (Benutzer)**, **Add Users (Benutzer hinzufügen)** oder wählen Sie **Admin (Administrator)**, **Add Admins (Administratoren hinzufügen)**.

**So fügen Sie einen Benutzer mit dem REST API hinzu**

1. Stellen Sie unter Verwendung von SSH eine Verbindung mit dem Master-Knoten her und verwenden Sie den folgenden Befehl auf dem Master-Knoten, oder führen Sie den Befehl als Schritt aus.

1. Erwerben Sie ein Administrator-Token, um API-Anfragen zu stellen, und ersetzen Sie es *AdminToken* im folgenden Schritt durch dieses Token.

1. Verwenden Sie den folgenden Befehl und *UserName* ersetzen Sie ihn durch einen Betriebssystembenutzer, der im Container erstellt wurde.

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

**Anmerkung**  
Sie werden automatisch als Benutzer JupyterHub ohne Administratorrechte hinzugefügt, wenn Sie sich zum ersten Mal an der JupyterHub Weboberfläche anmelden.

## Beispiel: Bash-Skript zum Hinzufügen mehrerer Benutzer
<a name="emr-jupyterhub-script-multuser"></a>

Das folgende Bash-Beispielskript verknüpft die vorherigen Schritte in diesem Abschnitt, um mehrere JupyterHub Benutzer zu erstellen. Das Skript kann direkt auf dem Hauptknoten ausgeführt werden, oder in Amazon S3 hochgeladen und als Schritt ausgeführt werden.

Das Skript stellt zuerst ein Array mit Benutzernamen, und verwendet den Befehl `jupyterhub token` zum Erstellen eines API-Token für den Standard-Administrator, jovyan. Anschließend erstellt es einen Betriebssystem-Benutzer im `jupyterhub`-Container für jeden Benutzer und weist jedem von ihnen ein anfängliches Passwort zu, das gleich ihrem Benutzernamen ist. Schließlich ruft es die REST-API-Operation auf, um jeden Benutzer in JupyterHub zu erstellen. Es übergibt das Token, das zuvor im Skript erstellt wurde und gibt die REST-Antwort der besseren Übersicht halber per Pipe an `jq` weiter.

```
# 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
```

Speichern Sie das Skript an einem Speicherort in Amazon S3, beispielsweise `s3://amzn-s3-demo-bucket/createjupyterusers.sh`. Anschließend können Sie es mit `script-runner.jar` als Schritt ausführen.

### Beispiel: Ausführen des Skripts beim Erstellen eines Clusters (AWS CLI)
<a name="emr-jupyterhub-multuser-createcluster"></a>

**Anmerkung**  
Linux-Zeilenfortsetzungszeichen (\$1) sind aus Gründen der Lesbarkeit enthalten. Sie können entfernt oder in Linux-Befehlen verwendet werden. Entfernen Sie sie unter Windows oder ersetzen Sie sie durch ein Caret-Zeichen (^).

```
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"]
```

### Ausführen des Skripts auf einem vorhandenen Cluster (AWS CLI)
<a name="emr-jupyterhub-multuser-runningcluster"></a>

**Anmerkung**  
Linux-Zeilenfortsetzungszeichen (\$1) sind aus Gründen der Lesbarkeit enthalten. Sie können entfernt oder in Linux-Befehlen verwendet werden. Entfernen Sie sie unter Windows oder ersetzen Sie sie durch ein Caret-Zeichen (^).

```
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"]
```

# Verwenden der LDAP-Authentifizierung
<a name="emr-jupyterhub-ldap-users"></a>

Lightweight Directory Access Protocol (LDAP) ist ein Anwendungsprotokoll zum Abfragen und Ändern von Objekten, die Ressourcen wie Benutzern und Computern entsprechen, die bei einem LDAP-kompatiblen Verzeichnisdiensteanbieter wie Active Directory oder auf einem OpenLDAP-Server gespeichert sind. Sie können das [LDAP-Authentifikator-Plug-In für JupyterHub](https://github.com/jupyterhub/ldapauthenticator/) with JupyterHub auf Amazon EMR verwenden, um LDAP für die Benutzerauthentifizierung zu verwenden. Das Plugin verwaltet Anmeldesitzungen für LDAP-Benutzer und stellt Jupyter Benutzerinformationen zur Verfügung. Auf diese Weise können Benutzer mithilfe der auf einem LDAP-kompatiblen Server gespeicherten Anmeldeinformationen für ihre Identitäten eine Verbindung zu JupyterHub und Notebooks herstellen.

Die Schritte in diesem Abschnitt führen Sie durch die folgenden Schritte zur Einrichtung und Aktivierung von LDAP mithilfe des LDAP Authenticator-Plug-ins für. JupyterHub Sie führen die Schritte aus, während Sie mit der Befehlszeile des Master-Knotens verbunden sind. Weitere Informationen finden Sie unter [Eine Verbindung mit dem Hauptknoten und Notebook-Servern herstellen](emr-jupyterhub-connect.md).

1. Erstellen Sie eine LDAP-Konfigurationsdatei mit Informationen über den LDAP-Server, wie Host-IP-Adresse, Port, Bindungsnamen usw.

1. Ändern Sie `/etc/jupyter/conf/jupyterhub_config.py`, um das LDAP-Authenticator-Plug-in für JupyterHub zu aktivieren.

1. Erstellen Sie ein Skript, das LDAP innerhalb des `jupyterhub`-Containers konfiguriert, und führen Sie es aus.

1. Fragen Sie LDAP nach Benutzern ab und erstellen Sie dann Basisverzeichnisse innerhalb des Containers für jeden Benutzer. JupyterHub benötigt Home-Verzeichnisse zum Hosten von Notebooks.

1. Führen Sie ein Skript aus, das neu gestartet wird JupyterHub

**Wichtig**  
Bevor Sie LDAP einrichten, testen Sie Ihre Netzwerkinfrastruktur, um sicherzustellen, dass der LDAP-Server und der Cluster-Master-Knoten wie gefordert kommunizieren können. TLS verwendet in der Regel Port 389 über eine einfache TCP-Verbindung. Wenn Ihre LDAP-Verbindung SSL verwendet, ist der bekannte TCP-Port für SSL 636.

## Die LDAP-Konfigurationsdatei erstellen
<a name="emr-jupyterhub-ldap-config"></a>

Das folgende Beispiel verwendet die folgenden Platzhalter-Konfigurationswerte. Ersetzen Sie diese durch Parameter, die Ihrer Implementierung entsprechen.
+ Der LDAP-Server läuft in Version 3 und ist auf Port 389 verfügbar. Dies ist der standardmäßige Nicht-SSL-Port für LDAP.
+ Der grundlegende spezifische Name (DN, Distinguished Name) ist `dc=example, dc=org`.

Erstellen Sie mit einem Texteditor die Datei [ldap.conf](http://manpages.ubuntu.com/manpages/bionic/man5/ldap.conf.5.html) mit Inhalt, der etwa wie folgt aussieht. Verwenden Sie geeignete Werte für Ihre LDAP-Implementierung. *host*Ersetzen Sie es durch die IP-Adresse oder den auflösbaren Hostnamen Ihres LDAP-Servers.

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

## Aktivieren Sie das LDAP Authenticator Plugin für JupyterHub
<a name="emr-jupyterhub-ldap-plugin"></a>

Verwenden Sie einen Texteditor, um die Datei `/etc/jupyter/conf/jupyterhub_config.py` zu ändern, und fügen Sie [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator)-Eigenschaften hinzu, etwa wie folgt. *host*Ersetzen Sie es durch die IP-Adresse oder den auflösbaren Hostnamen des LDAP-Servers. Das Beispiel geht davon aus, dass sich die Benutzerobjekte innerhalb einer benannten Organisationseinheit (OU) befinden*people*, und verwendet die definierten Namenskomponenten, die Sie zuvor mit Hilfe eingerichtet haben. `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'
```

## LDAP im Container konfigurieren
<a name="emr-jupyterhub-ldap-container"></a>

Erstellen Sie mithilfe eines Texteditors ein Bash-Skript mit folgendem Inhalt:

```
#!/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"
```

Speichern Sie das Skript auf dem Master-Knoten und führen Sie es in der Befehlszeile des Master-Knotens aus. Wenn das Skript beispielsweise als `configure_ldap_client.sh` gespeichert ist, machen Sie die Datei ausführbar:

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

Und führen das Skript aus:

```
./configure_ldap_client.sh
```

## Attribute zur Active Directory hinzufügen
<a name="emr-jupyterhub-ldap-adproperties"></a>

Um jeden Benutzer zu finden und den entsprechenden Eintrag in der Datenbank zu erstellen, benötigt der JupyterHub Docker-Container die folgenden UNIX-Eigenschaften für das entsprechende Benutzerobjekt in Active Directory. Weitere Informationen finden Sie im Abschnitt *Wie bearbeite ich weiterhin die GID/UID RFC 2307-Attribute, da das Unix Attributes Plug-in für das MMC-Snap-In Active Directory-Benutzer und -Computer nicht mehr verfügbar ist*? im Artikel [Klarstellung zum Status der Identitätsverwaltung für Unix (IDMU) und der NIS-Serverrolle in der technischen Vorschau von Windows Server 2016](https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/) und darüber hinaus.
+ `homeDirectory`

  Dies ist der Speicherort im Stammverzeichnis des Benutzers, das in der Regel `/home/username` ist.
+ `gidNumber`

  Dies ist ein Wert größer als 60.000, der noch nicht von einem anderen Benutzer verwendet wird. Überprüfen Sie die `etc/passwd`-Datei auf GIDs, die bereits verwendet werden.
+ `uidNumber`

  Dies ist ein Wert größer als 60000, der noch nicht von einer anderen Gruppe verwendet wird. Überprüfen Sie die `etc/group`-Datei auf UIDs, die bereits verwendet werden.
+ `uid`

  Das ist dasselbe wie das*username*.

## Root-Verzeichnisse für Benutzer erstellen
<a name="emr-jupyterhub-ldap-directories"></a>

JupyterHub benötigt Home-Verzeichnisse innerhalb des Containers, um LDAP-Benutzer zu authentifizieren und Instanzdaten zu speichern. Das folgende Beispiel zeigt zwei Benutzer, *shirley* und *diego*, im LDAP-Verzeichnis.

Der erste Schritt besteht darin, den LDAP-Server mithilfe von [ldapsearch nach](http://manpages.ubuntu.com/manpages/xenial/man1/ldapsearch.1.html) den Benutzer-IDs und Gruppen-ID-Informationen der einzelnen Benutzer abzufragen, wie im folgenden Beispiel gezeigt, und durch die IP-Adresse oder den auflösbaren Hostnamen Ihres LDAP-Servers zu *host* ersetzen:

```
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
```

Der Befehl `ldapsearch` gibt eine LDIF-formatierte Antwort zurück, die für die Benutzer *shirley* und *diego* etwa wie nachfolgend gezeigt aussieht.

```
# 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
```

Unter Verwendung der Informationen aus der Antwort führen Sie Befehle innerhalb des Containers zum Erstellen eines Stammverzeichnisses für jeden allgemeinen Namen (`cn`) des Benutzers aus. Verwenden Sie `uidNumber` und `gidNumber`, um das Eigentum für das Stammverzeichnis für diesen Benutzer festzulegen. Die folgenden Beispielbefehle erledigen dies für den Benutzer. *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"
```

**Anmerkung**  
Der LDAP-Authentifikator für JupyterHub unterstützt die lokale Benutzererstellung nicht. Weitere Informationen finden Sie unter [LDAP-Authentifikator-Konfigurationshinweis zur lokalen Benutzererstellung](https://github.com/jupyterhub/ldapauthenticator#configuration-note-on-local-user-creation).   
Um einen lokalen Benutzer manuell zu erstellen, verwenden Sie den folgenden Befehl.  

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

## Starten Sie den Container neu JupyterHub
<a name="emr-jupyterhub-ldap-restart"></a>

Führen Sie den folgenden Befehl aus, um den `jupyterhub`-Container neu zu starten:

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

# Benutzer-Identitätswechsel
<a name="emr-jupyterhub-user-impersonation"></a>

Ein Spark-Auftrag, der in einem Jupyter-Notebook ausgeführt wird, durchläuft während seiner Ausführung in Amazon EMR mehrere Anwendungen. Zum Beispiel wird PySpark 3-Code, den ein Benutzer in Jupyter ausführt, von Sparkmagic empfangen. Sparkmagic verwendet eine HTTP-POST-Anfrage, um ihn an Livy zu senden, das dann einen Spark-Job erstellt, der mit YARN auf dem Cluster ausgeführt wird.

Standardmäßig werden auf diese Weise gesendete YARN-Aufträge als Benutzer `livy` ausgeführt. Dies gilt unabhängig von dem Benutzer, der den Auftrag initiiert hat. Durch das Einrichten eines *Benutzer-Identitätswechsels* können Sie die Benutzer-ID des Notebook-Benutzers auch für den dem YARN-Auftrag zugeordneten Benutzer verwenden. Von `shirley` und `diego` initiierte Aufträge werden nicht dem Benutzer `livy` zugeordnet. Stattdessen werden die von den Benutzern initiierten Aufträge `shirley` und `diego` zugeordnet. Dies erleichtert das Überwachen der Jupyter-Nutzung und das Verwalten von Anwendungen in der Organisation.

Diese Konfiguration wird nur unterstützt, wenn Aufrufe von Sparkmagic an Livy ohne Authentifizierung erfolgen. Anwendungen, die eine Authentifizierung oder einen Proxy-Layer zwischen Hadoop-Anwendungen und Livy (z. B. Apache Knox Gateway) bereitstellen, werden nicht unterstützt. Bei den Schritten zur Konfiguration des Benutzerwechsels in diesem Abschnitt wird davon ausgegangen, dass JupyterHub und Livy auf demselben Master-Knoten ausgeführt werden. Wenn die Anwendung separate Cluster enthält, muss [Schritt 3: HDFS-Stammverzeichnisse für Benutzer erstellen](#Step3-UserImpersonation) geändert werden, damit HDFS-Verzeichnisse auf dem Livy-Master-Knoten erstellt werden.

**Topics**
+ [Schritt 1: Livy konfigurieren](#Step1-UserImpersonation)
+ [Schritt 2: Benutzer hinzufügen](#Step2-UserImpersonation)
+ [Schritt 3: HDFS-Stammverzeichnisse für Benutzer erstellen](#Step3-UserImpersonation)

## Schritt 1: Livy konfigurieren
<a name="Step1-UserImpersonation"></a>

Sie verwenden die Konfigurationsklassifizierungen `livy-conf` und `core-site`, wenn Sie einen Cluster erstellen, um Livy-Benutzer-Identitätswechsel zu ermöglichen (siehe folgendes Beispiel). Speichern Sie die Konfigurationsklassifizierung als JSON-Objekt und verweisen Sie dann darauf, wenn Sie den Cluster erstellen. Sie können die Konfigurationsklassifizierung auch im Code angeben. Weitere Informationen finden Sie unter [Anwendungen konfigurieren](emr-configure-apps.md).

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

## Schritt 2: Benutzer hinzufügen
<a name="Step2-UserImpersonation"></a>

Fügen Sie JupyterHub Benutzer mithilfe von PAM oder LDAP hinzu. Weitere Informationen erhalten Sie unter [Verwenden der PAM-Authentifizierung](emr-jupyterhub-pam-users.md) und [Verwenden der LDAP-Authentifizierung](emr-jupyterhub-ldap-users.md).

## Schritt 3: HDFS-Stammverzeichnisse für Benutzer erstellen
<a name="Step3-UserImpersonation"></a>

Sie haben eine Verbindung zum Master-Knoten hergestellt, um Benutzer zu erstellen. Kopieren Sie den unten angegebenen Inhalt, während die Verbindung zum Master-Knoten noch besteht, und speichern Sie ihn in einer Skriptdatei. Das Skript erstellt HDFS-Home-Verzeichnisse für jeden JupyterHub Benutzer auf dem Master-Knoten. Das Skript geht davon aus, dass Sie die Standard-Administratorbenutzer-ID verwenden,*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
```

# Installieren von zusätzlicher Kerneln und Bibliotheken
<a name="emr-jupyterhub-install-kernels-libs"></a>

Wenn Sie einen Cluster mit JupyterHub Amazon EMR erstellen, werden der Standard-Python-3-Kernel für Jupyter zusammen mit den PySpark und Spark-Kernel für Sparkmagic auf dem Docker-Container installiert. Sie können zusätzliche Kernel installieren. Sie können auch zusätzliche Bibliotheken und Pakete installieren und dann für die entsprechende Shell importieren.

## Installieren eines Kernels
<a name="emr-jupyterhub-install-kernels"></a>

Kernel werden innerhalb des Docker-Containers installiert. Am einfachsten ist dies zu bewerkstelligen, indem Sie ein Bash-Skript mit Installationsbefehlen erstellen, es auf dem Master-Knoten speichern und es dann mit dem Befehl `sudo docker exec jupyterhub script_name` im Container `jupyterhub` ausführen. Das folgende Beispielskript installiert den Kernel und installiert dann einige Bibliotheken für diesen Kernel auf dem Master-Knoten, sodass Sie die Bibliotheken später unter Verwendung des Kernels in Jupyter importieren können.

```
#!/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
```

Um den Kernel und Bibliotheken innerhalb des Containers zu installieren, öffnen Sie eine Terminal-Verbindung zu dem Master-Knoten, speichern das Skript in `/etc/jupyter/install_kernels.sh` und führen den folgenden Befehl in der Master-Knoten Befehlszeile aus:

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

## Verwenden von Bibliotheken und Installieren von zusätzlichen Bibliotheken
<a name="emr-jupyterhub-install-libs"></a>

Ein Kernsatz von Bibliotheken für maschinelles Lernen und Datenwissenschaft für Python 3 ist JupyterHub auf Amazon EMR vorinstalliert. Sie können `sudo docker exec jupyterhub bash -c "conda list" ` und `sudo docker exec jupyterhub bash -c "pip freeze"` verwenden.

Wenn ein Spark-Job Bibliotheken auf Worker-Knoten benötigt, empfehlen wir, dass Sie beim Erstellen des Clusters ein Skript ausführen, um die Bibliotheken zu installieren. Bootstrap-Aktionen werden beim Erstellungsprozess des Clusters auf allen Cluster-Knoten ausgeführt, was die Installation vereinfacht. Wenn Sie Bibliotheken auf Core-/Worker-Knoten installieren, nachdem ein Cluster läuft, ist die Operation komplizierter. Wir zeigen in diesem Abschnitt ein Python-Beispielprogramm, das demonstriert, wie diese Bibliotheken zu installieren sind.

Die in diesem Abschnitt gezeigten Beispiele für Bootstrap-Aktionen und Python-Programme verwenden ein Bash-Skript, das in Amazon S3 gespeichert ist, um die Bibliotheken auf allen Knoten zu installieren.

Das in den folgenden Beispielen verwendete Skript `pip` installiert paramiko, nltk, scipy, scikit-learn und pandas für den Python 3-Kernel:

```
#!/bin/bash

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

Nachdem Sie das Skript erstellen, laden Sie es an einem Speicherort in Amazon S3 hoch, z. B `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`. Weitere Informationen finden Sie unter [Hochladen von Objekten](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html) im *Benutzerhandbuch für Amazon Simple Storage Service*, sodass Sie es in Ihrer Bootstrap-Aktion oder in Ihrem Python-Programm verwenden können.

**Um eine Bootstrap-Aktion anzugeben, mit der Bibliotheken auf allen Knoten installiert werden, wenn Sie einen Cluster mit dem AWS CLI**

1. Erstellen Sie ein Skript ähnlich dem früheren Beispiel und speichern Sie es an einem Speicherort in Amazon S3. Wir verwenden das Beispiel `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`.

1. Erstellen Sie den Cluster mit JupyterHub und verwenden Sie das `Path` Argument der `--bootstrap-actions` Option, um den Speicherort des Skripts anzugeben, wie im folgenden Beispiel gezeigt:
**Anmerkung**  
Linux-Zeilenfortsetzungszeichen (\$1) sind aus Gründen der Lesbarkeit enthalten. Sie können entfernt oder in Linux-Befehlen verwendet werden. Entfernen Sie sie unter Windows oder ersetzen Sie sie durch ein Caret-Zeichen (^).

   ```
   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
   ```

**So geben Sie eine Bootstrap-Aktion an, die Bibliotheken auf allen Knoten installiert, wenn Sie einen Cluster mithilfe der Konsole erstellen**

1. Navigieren Sie zur neuen Amazon-EMR-Konsole und wählen Sie in der Seitennavigation die Option **Zur alten Konsole wechseln** aus. Weitere Informationen darüber, was Sie erwartet, wenn Sie zur alten Konsole wechseln, finden Sie unter [Verwenden der alten Konsole](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Wählen Sie **Create Cluster (Cluster erstellen)** und **Go to advanced options (Zu erweiterten Optionen)** aus.

1. Geben Sie Einstellungen für **Software and Steps (Software und Schritte)** und **Hardware** an, wie für Ihre Anwendung geeignet.

1. Auf dem Bildschirm **General Cluster Settings (Allgemeine Cluster-Einstellungen)** expandieren Sie **Bootstrap Actions (Bootstrap-Aktionen)**.

1. Wählen Sie für **Add bootstrap action (Bootstrap-Aktion hinzufügen)** die Option **Custom action (Benutzerdefinierte Aktion)** und **Configure and add (Konfigurieren und hinzufügen)** aus.

1. Geben Sie für **Name** einen benutzerfreundlichen Namen ein. Geben Sie unter **Skriptspeicherort** den Speicherort Ihres Skripts in Amazon S3 ein (das Beispiel, das wir verwenden, ist *s3://amzn-s3-demo-bucket/ install-my-jupyter-libraries .sh*). Tragen Sie in **Optional arguments (Optionale Argumente)** nichts ein und wählen Sie **Add (Hinzufügen)**.

1. Geben Sie andere Einstellungen für Ihren Cluster an und wählen Sie **Next (Weiter)**.

1. Geben Sie Sicherheitseinstellungen an und wählen Sie **Create cluster (Cluster erstellen)**.

**Example Installieren von Bibliotheken auf Core-Knoten eines aktiven Clusters**  
Nach der Installation von Bibliotheken auf dem Master-Knoten innerhalb von Jupyter können Sie auf verschiedene Arten Bibliotheken auf in Ausführung befindlichen Core-Knoten installieren. Das folgende Beispiel zeigt ein Python-Programm, das für die Ausführung auf einem lokalen Computer geschrieben wurde. Wenn Sie das Python-Programm lokal ausführen, verwendet es das `AWS-RunShellScript` von, AWS Systems Manager um das weiter oben in diesem Abschnitt gezeigte Beispielskript auszuführen, das Bibliotheken auf den Kernknoten des Clusters installiert.  

```
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 Versionsverlauf
<a name="JupyterHub-release-history"></a>

In der folgenden Tabelle sind die Versionen von aufgeführt, die in jeder Release-Version von Amazon EMR JupyterHub enthalten sind, zusammen mit den Komponenten, die mit der Anwendung installiert wurden. Informationen zu den Komponentenversionen in den einzelnen Versionen finden Sie im Abschnitt Komponentenversion für Ihre Version in [Amazon-EMR-7.x-Versionen](emr-release-7x.md), [Amazon-EMR-6.x-Versionen](emr-release-6x.md) oder [Amazon-EMR-5.x-Versionen](emr-release-5x.md).


**JupyterHub Versionsinformationen**  

| Amazon-EMR-Versionsbezeichnung | JupyterHub Version | Komponenten, die mit installiert wurden 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 | 