Comment configurer une connexion SSL entre Hive sur Amazon EMR et un métastore sur Amazon RDS MySQL ?

Date de la dernière mise à jour : 04/09/2020

Je veux configurer une connexion SSL entre Apache Hive et un métastore qui se trouve sur une instance de base de données MySQL Amazon Relational Database Service (Amazon RDS). Comment dois-je procéder ?

Brève description

Configurez une connexion chiffrée entre Hive et un métastore externe à l'aide d'un certificat SSL. Vous pouvez configurer cette connexion lorsque vous lancez un nouveau cluster Amazon EMR ou après l'exécution du cluster.

Solution

Remarque : les étapes suivantes ont été testées avec Amazon EMR version 5.18.0 et Amazon RDS MySQL version 5.7.

Configurer la connexion SSL sur un nouveau cluster Amazon EMR

1.     Exécutez une commande similaire à celle ci-dessous pour créer une instance DB MySQL Amazon RDS. Remplacez $RDS_MASTER_USER_NAME et $RDS_MASTER_PASSWORD par votre nom d'utilisateur et votre mot de passe. Pour plus d'informations,consultez create-db-instance.

Remarque : si vous recevez des erreurs lors de l'exécution de commandes depuis l'interface de ligne de commande (CLI) AWS, veillez à utiliser la version la plus récente de l'interface de ligne de commande (CLI).

aws rds create-db-instance --db-name hive --db-instance-identifier mysql-hive-meta --db-instance-class db.t2.micro\ 
    --engine mysql --engine-version 5.7.19 --master-username $RDS_MASTER_USER_NAME --master-user-password $RDS_MASTER_PASSWORD\
    --allocated-storage 20 --storage-type gp2 --vpc-security-group-ids $RDS_VPC_SG --publicly-accessible

2.     Connectez-vous à l'instance DB MySQL Amazon RDS en tant qu'utilisateur principal. Ensuite, créez un utilisateur pour le métastore Hive, comme indiqué dans l'exemple suivant.

Important : veillez à restreindre l'accès de cet utilisateur à l'instance de base de données que vous avez créée à l'étape 1.

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_PASSWORD

CREATE USER 'hive_user'@'%' IDENTIFIED BY 'hive_user_password';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'hive_user'@'%';
GRANT ALL PRIVILEGES ON hive.* TO 'hive_user'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;

3.     Créez un fichier de configuration JSON similaire à celui-ci. Remplacez hive_user et hive_user_password par les valeurs que vous avez utilisées dans le script JSON à l'étape 2. Remplacez le point de terminaison dans l'URL JDBC par le point de terminaison de votre instance DB RDS.

Vous allez utiliser ce fichier pour lancer le cluster Amazon EMR dans l'étape suivante. Le fichier active une connexion SSL à l'instance DB RDS. Pour plus d'informations, consultez Utilisation de SSL avec une instance de base de données MySQL.

[
    {
        "Classification": "hive-site",
        "Properties": {
            "javax.jdo.option.ConnectionURL": "jdbc:mysql:\/\/mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306\/hive?createDatabaseIfNotExist=true&useSSL=true&serverSslCert=\/home\/hadoop\/rds-combined-ca-bundle.pem",
            "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
            "javax.jdo.option.ConnectionUserName": "hive_user",
            "javax.jdo.option.ConnectionPassword": "hive_user_password"
        }
    }
]

4.     Dans le groupe de sécurité associé à l'instance MySQL Amazon RDS, créez une règle entrante avec les paramètres suivants.
Pour Type, choisissez MySQL/Aurora (3306).
Pour Protocol (Protocole), TCP (6) est sélectionné par défaut.
Pour Ports Range (Plage de ports), 3306 est sélectionné par défaut.
Pour Source, entrez l'ID du groupe de sécurité géré par Amazon EMR associé au nœud principal.

Cette règle permet au nœud principal du cluster Amazon EMR d'accéder à l'instance Amazon RDS. Pour plus d'informations, consultez Groupes de sécurité VPC.

5.     Exécutez la commande create-cluster pour lancer un cluster Amazon EMR en utilisant le fichier JSON de l'étape 3, avec une action d'amorçage qui télécharge le certificat SSL vers /home/hadoop/ sur le nœud principal. Exemple :

aws emr create-cluster --applications Name=Hadoop Name=Hive --tags Name="EMR Hive Metastore"\
    --ec2-attributes KeyName=$EC2_KEY_PAIR,InstanceProfile=EMR_EC2_DefaultRole,SubnetId=$EMR_SUBNET,EmrManagedSlaveSecurityGroup=$EMR_CORE_AND_TASK_VPC_SG,EmrManagedMasterSecurityGroup=$EMR_MASTER_VPC_SG\
   
    --service-role EMR_DefaultRole --release-label emr-5.18.0 --log-uri s3://awsdoc-example-bucket/emr-logs-path/ --name "Hive External Metastore RDS MySQL w/ SSL"\
    --instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m3.xlarge,Name="Master
    - 1"\ 
    --configurations file://hive-ext-meta-mysql-ssl.json\
    --bootstrap-actions Path=s3://elasticmapreduce/bootstrap-actions/run-if,Args=["instance.isMaster=true","cd /home/hadoop && wget -S -T
    10 -t 5 https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem"]

6.     Connectez-vous au nœud principal en utilisant SSH.

7.     Ouvrez une séance ruche sur le nœud principal. Ensuite, créez une table. Il peut s'agir de n'importe quelle table ; elle est utilisée uniquement à des fins de test. Exemple :

hive> create table tb_test (col1 STRING, col2 BIGINT);
OK
Time taken: 2.371 seconds

hive> describe tb_test;
OK
col1                    string
col2                    bigint
Time taken: 0.254 seconds, Fetched: 2 row(s)

8.     Connectez-vous au métastore RDS MySQL à l'aide du client mysql sur le nœud principal. Ensuite, vérifiez les métadonnées de la table dans le métastore. Si les métadonnées correspondent à la table que vous avez créée à l'étape précédente, la connexion SSL fonctionne. Exemple :

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_PASSWORD

mysql> use hive;
Database changed

mysql> select t1.OWNER, t1.TBL_NAME, t1.TBL_TYPE, s1.INPUT_FORMAT, s1.OUTPUT_FORMAT, s1.LOCATION from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID where t1.TBL_NAME = 'tb_test'\G
*************************** 1. row ***************************
        OWNER: hadoop
     TBL_NAME: tb_test
     TBL_TYPE: MANAGED_TABLE
 INPUT_FORMAT: org.apache.hadoop.mapred.TextInputFormat
OUTPUT_FORMAT: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
     LOCATION: hdfs://ip-xxx-xx-xx-xxx.ec2.internal:8020/user/hive/warehouse/tb_test
1 row in set (0.23 sec)

mysql> select t1.OWNER, t1.TBL_NAME, c1.COLUMN_NAME, c1.TYPE_NAME from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID inner join COLUMNS_V2 c1 on c1.CD_ID = s1.CD_ID where t1.TBL_NAME = 'tb_test';
+--------+----------+-------------+-----------+
| OWNER  | TBL_NAME | COLUMN_NAME | TYPE_NAME |
+--------+----------+-------------+-----------+
| hadoop | tb_test  | col1        | string    |
| hadoop | tb_test  | col2        | bigint    |
+--------+----------+-------------+-----------+
2 rows in set (0.22 sec)

Configuration de la connexion SSL sur un cluster Amazon EMR en cours d'exécution

Remarque : les étapes suivantes supposent que vous disposez d'une instance DB MySQL Amazon RDS.

1.     Connectez-vous au nœud principal en utilisant SSH.

2.     Exécutez la commande suivante pour télécharger le certificat SSL dans /home/hadoop/ sur le nœud principal :

cd /home/hadoop && wget -S -T 10 -t 5 https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

3.     Dans le répertoire /etc/hive/conf.dist ajoutez ou modifiez les lignes suivantes dans le fichier hive-site.xml. Cela active une connexion SSL à l'instance DB RDS. Dans l'exemple suivant, remplacez le point de terminaison dans l'URL JDBC par le point de terminaison de votre instance DB RDS.

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=true&amp;serverSslCert=/home/hadoop/rds-combined-ca-bundle.pem</value>
  <description>JDBC URL for the metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive_user</value>
    <description>User name for the metastore database</description>
</property>

<property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>HIVE_USER_PASSWORD</value>
    <description>Password for metastore database</description>
</property>

Important : Le « et » commercial (&) est un caractère spécial en XML. Pour l'utiliser dans hive-site.xml, comme dans la chaîne JDBC, vous devez utiliser « &amp; » au lieu de « &. » Sinon, vous obtenez une erreur lorsque vous redémarrez hive-hcatalog-server.

4.     Exécutez une commande similaire à celle ci-dessous pour tester la commande SSL :

mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u hive_user -p --ssl-ca ./rds-combined-ca-bundle.pem

5.     Redémarrez hive-server2 et hive-hcatalog-server sur le nœud principal. Pour plus d'informations, consultez Redémarrage des processus.

6.     Dans le répertoire /var/log/ vérifiez que les services ont redémarré correctement. Le journal doit avoir contenir des entrées comme celles-ci :

sudo stop hive-server2
sudo stop hive-hcatalog-server
sudo start hive-hcatalog-server
sudo start hive-server2

7.     Ouvrez une séance ruche sur le nœud principal. Ensuite, créez une table. Il peut s'agir de n'importe quelle table ; elle est utilisée uniquement à des fins de test. Exemple :

hive> create table tb_test (col1 STRING, col2 BIGINT);
OK
Time taken: 2.371 seconds

hive> describe tb_test;
OK
col1                    string
col2                    bigint
Time taken: 0.254 seconds, Fetched: 2 row(s)

8.     Connectez-vous au métastore RDS MySQL à l'aide du client mysql sur le nœud principal. Ensuite, vérifiez les métadonnées de la table dans le métastore. Si les métadonnées correspondent à la table que vous avez créée à l'étape précédente, la connexion SSL fonctionne. Exemple :

$ mysql -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_MASTER_USER_NAME -p
Enter password: $RDS_MASTER_PASSWORD

mysql> use hive;
Database changed

mysql> select t1.OWNER, t1.TBL_NAME, t1.TBL_TYPE, s1.INPUT_FORMAT, s1.OUTPUT_FORMAT, s1.LOCATION from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID where t1.TBL_NAME = 'tb_test'\G
*************************** 1. row ***************************
        OWNER: hadoop
     TBL_NAME: tb_test
     TBL_TYPE: MANAGED_TABLE
 INPUT_FORMAT: org.apache.hadoop.mapred.TextInputFormat
OUTPUT_FORMAT: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
     LOCATION: hdfs://ip-xxx-xx-xx-xxx.ec2.internal:8020/user/hive/warehouse/tb_test
1 row in set (0.23 sec)

mysql> select t1.OWNER, t1.TBL_NAME, c1.COLUMN_NAME, c1.TYPE_NAME from TBLS t1 inner join SDS s1 on s1.SD_ID = t1.SD_ID inner join COLUMNS_V2 c1 on c1.CD_ID = s1.CD_ID where t1.TBL_NAME = 'tb_test';
+--------+----------+-------------+-----------+
| OWNER  | TBL_NAME | COLUMN_NAME | TYPE_NAME |
+--------+----------+-------------+-----------+
| hadoop | tb_test  | col1        | string    |
| hadoop | tb_test  | col2        | bigint    |
+--------+----------+-------------+-----------+
2 rows in set (0.22 sec)

Résolution des erreurs de redémarrage du serveur hive-hcatalog-server

Vous pouvez obtenir un message d'erreur similaire à celui ci-dessous lorsque vous essayez de redémarrer hive-hcatalog-server. Cela se produit généralement lorsque l'instance de base de données MySQL RDS bloque le nœud principal du cluster EMR à titre de précaution de sécurité.

2020-08-20T14:18:50,750 WARN [main] org.apache.hadoop.hive.metastore.HiveMetaStore - Retrying creating default database after error: Unable to open a test connection to the given database. JDBC url = jdbc:mysql://mariadb-hive-meta.ch1nkjp4jjbq.eu-west-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSSlCert=/home/hadoop/rds-combined-ca-bundle.pem, username = masteruser. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
java.sql.SQLException: Host '172.31.41.187' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

Pour résoudre cette erreur, connectez-vous à une autre machine locale ou à une instance Amazon Elastic Compute Cloud (Amazon EC2) sur laquelle l'outil mysqladmin est installé. Exécutez la commande suivante pour vider le nœud principal depuis l'instance de base de données.

mysqladmin -h mysql-hive-meta.########.us-east-1.rds.amazonaws.com -P 3306 -u $RDS_MASTER_USER_NAME -p flush-hosts
Enter password: $RDS_MASTER_PASSWORD

Maintenant, vous devez pouvoir redémarrer le serveur hive-hcatalog-server.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?