Ir para o conteúdo

Como faço para configurar uma conexão SSL entre a Hive no Amazon EMR e uma metastore no Amazon RDS para MySQL?

9 minuto de leitura
0

Quero configurar uma conexão SSL entre a Hive no Amazon EMR e uma metastore no Amazon Relational Database Service (Amazon RDS) para MySQL.

Breve descrição

Para configurar uma conexão criptografada entre o Hive e uma metastore externa, use um certificado SSL. É possível configurar uma conexão SSL ao inicializar um novo cluster do Amazon EMR ou depois que o cluster estiver em execução.

Observação: as etapas a seguir foram testadas no Amazon EMR versão 7.3.0 e no Amazon RDS para MySQL versão 8.0.39.

Resolução

Observação: Se você receber erros ao executar comandos da AWS Command Line Interface (AWS CLI), consulte Solução de erros da AWS CLI. Além disso, verifique se você está usando a versão mais recente da AWS CLI.

Configurar uma conexão SSL em um novo cluster do Amazon EMR

Conclua as seguintes etapas:

  1. Para criar uma instância de banco de dados do Amazon RDS para MySQL, execute o seguinte comando create-db-instance:

    aws rds create-db-instance \
     --db-name hive \
     --db-instance-identifier example-db-instance-identifier \
     --db-instance-class db.c6gd.large \
     --engine mysql --engine-version 8.0.39 \
     --db-subnet-group-name example-subnet-group \
     --master-username example-rds-primary-user \
     --master-user-password example-rds-primary-password \
     --allocated-storage 200 \
     --storage-type gp3 \
     --vpc-security-group-ids example-rds-vpc-security-group

    Observação: substitua example-db-instance-identifier pelo identificador de instância do banco de dados, example-subnet-group com o seu nome de grupo de sub-rede, example-rds-primary-user pelo nome de usuário principal do Amazon RDS e example-rds-primary-password pela senha principal do Amazon RDS. Além disso, substitua example-rds-vpc-security-group pelo nome do seu grupo de segurança do Amazon Virtual Private Cloud (Amazon VPC) do Amazon RDS.

  2. Conecte-se à instância de banco de dados do Amazon RDS para MySQL como usuário principal. Em seguida, crie um usuário da metastore do Hive:
    Observação: certifique-se de restringir o acesso do usuário principal à instância de banco de dados que você criou anteriormente.

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p
    Enter password: example-rds-primary-password
    CREATE USER 'example-hive-username' IDENTIFIED BY 'example-hive-password' REQUIRE SSL;
    REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'example-hive-username';
    GRANT ALL PRIVILEGES ON hive.* TO 'example-hive-username';
    FLUSH PRIVILEGES;

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-rds-primary-user pelo nome de usuário principal do Amazon RDS e example-rds-primary-password pela senha principal do Amazon RDS. Além disso, substitua example-hive-username pelo nome de usuário da Hive e example-hive-password com a sua senha de example-hive-username.

  3. Crie um arquivo de configuração JSON semelhante ao seguinte:

    Observação: use o arquivo JSON a seguir para inicializar o cluster do Amazon EMR na próxima etapa. O arquivo permite que a Hive estabeleça uma conexão SSL com a instância de banco de dados do Amazon RDS.

    [
        {
            "Classification": "hive-site",
            "Properties": {
                "javax.jdo.option.ConnectionURL": "jdbc:mysql://example-rds-db-instance-endpoint:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSslCert=/home/hadoop/global-bundle.pem",
                "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
                "javax.jdo.option.ConnectionUserName": "example-hive-username",
                "javax.jdo.option.ConnectionPassword": "example-hive-password"
            }
        }
    ]

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-hive-username pelo nome de usuário que a Hive usará para se conectar à instância de banco de dados do Amazon RDS e example-hive-password pela senha de example-hive-username.

  4. Crie uma regra de entrada no grupo de segurança associado à sua instância do Amazon RDS para MySQL da seguinte forma:
    Em Tipo, escolha MySQL/Aurora (3306).
    Em Protocolo, TCP (6) é selecionado por padrão.
    Em Intervalo de portas, 3306 é selecionado por padrão.
    Em Origem, insira o ID do grupo de segurança gerenciado do Amazon EMR associado ao nó primário.
    Observação: essa regra permite que o nó primário do cluster do Amazon EMR acesse a instância do Amazon RDS. Para mais informações, consulte Visão geral dos grupos de segurança da VPC.

  5. Crie o seguinte arquivo de script de ação de bootstrap. Em seguida, faça o upload para um bucket do Amazon S3. A ação de bootstrap baixa o certificado SSL para /home/hadoop/ no nó primário.

    #!/bin/bash
    if grep isMaster /mnt/var/lib/info/instance.json | grep false;
    then        
        echo "This is not primary node, do nothing, exiting"
        exit 0
    fi
    echo "This is primary, continuing to execute script"
    cd /home/hadoop
    wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
  6. Para inicializar um cluster do Amazon EMR, execute o seguinte comando create-cluster com o arquivo JSON anterior e a ação de bootstrap:

    Exemplo:

    aws emr create-cluster \
     --name "EMR Hive Metastore SSL" \
     --log-uri $LOG_URI \
     --release-label "emr-7.3.0" \
     --service-role $EMRServiceRole \
     --ec2-attributes KeyName=$EC2_KEY_PAIR,InstanceProfile=$EMREC2Role,SubnetId=$EMR_SUBNET,EmrManagedSlaveSecurityGroup=$EMR_CORE_AND_TASK_VPC_SG,EmrManagedMasterSecurityGroup=$EMR_PRIMARY_VPC_SG \
     --applications Name=Hadoop Name=Hive \
     --bootstrap-actions Path=$BOOTSTRAP_ACTION_SCRIPT_PATH \
     --configurations file:///<Full-Path-To>/hive-ext-meta-mysql-ssl.json \
     --instance-groups '[{"InstanceCount":1,"InstanceGroupType":"CORE","Name":"Core","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}},{"InstanceCount":1,"InstanceGroupType":"MASTER","Name":"Primary","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}},{"InstanceCount":1,"InstanceGroupType":"TASK","Name":"Task - 1","InstanceType":"m5.xlarge","EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"VolumeType":"gp2","SizeInGB":32},"VolumesPerInstance":2}]}}]'
  7. use SSH para se conectar ao nó primário.

  8. Abra uma sessão da Hive no nó primário. Em seguida, crie uma tabela para fins de teste.

    Exemplo:

    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)
  9. para se conectar à metastore do Amazon RDS para MySQL, use o cliente mysql no nó primário. Em seguida, verifique os metadados da tabela na metastore. Se os metadados corresponderem à tabela que você criou na etapa anterior, a conexão SSL funcionará.

    Exemplo:

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -pEnter password: example-rds-primary-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)

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-rds-primary-user pelo nome de usuário principal do Amazon RDS e example-rds-primary-password pela senha principal do Amazon RDS.

Configurar uma conexão SSL em um cluster do Amazon EMR em execução

Observação: antes de começar, certifique-se de ter uma instância de banco de dados do Amazon RDS para MySQL.

  1. Use SSH para se conectar ao nó primário.

  2. Baixe o certificado SSL em /home/hadoop/ no nó primário:

    cd /home/hadoop && wget -S -T 10 -t 5 https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
  3. No diretório /etc/hive/conf.dist, adicione ou edite as seguintes linhas no arquivo hive-site.xml:

    <property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://example-rds-db-instance-endpoint:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=true&amp;serverSslCert=/home/hadoop/global-bundle.pem</value>
      <description>example-rds-db-instance-endpoint</description>
    </property>
    
    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>example-hive-username</value>
        <description>example-metastore-db-user</description>
    </property>
    
    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>example-hive-password</value>
        <description>example-metastore-db-password</description>
    </property>

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-hive-username pelo nome de usuário que a Hive usará para se conectar à instância de banco de dados do Amazon RDS e example-hive-password pela senha de example-hive-username. Além disso, o e comercial (&) é um caractere especial em XML. Para usar um e comercial em hive-site.xml, como na string JDBC, use & em vez de &. Se você não usar &, receberá um erro ao reiniciar o hive-hcatalog-server.

  4. Teste a conexão SSL:

    mysql -h example-rds-db-instance-endpoint -P 3306 -u example-hive-username -p --ssl-ca /home/hadoop/global-bundle.pem
    Enter password: example-hive-password

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-hive-username pelo nome de usuário que a Hive usará para se conectar à instância de banco de dados do Amazon RDS e example-hive-password pela senha de example-hive-username.

  5. Reinicie hive-hcatalog-server no nó primário.

  6. Confirme se os serviços foram reiniciados:

    sudo systemctl status hive-hcatalog-server.service
  7. Abra uma sessão da Hive no nó primário. Em seguida, crie uma tabela para fins de teste.

    Exemplo:

    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. para se conectar à metastore do Amazon RDS para MySQL, use o cliente mysql no nó primário. Em seguida, verifique os metadados da tabela na metastore. Se os metadados corresponderem à tabela que você criou na etapa anterior, a conexão SSL funcionará.

    Exemplo:

    $ mysql -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-user -p
    Enter password: example-rds-primary-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)

    Observação: substitua example-rds-db-instance-endpoint pelo endpoint da instância de banco de dados do Amazon RDS, example-rds-primary-user pelo nome de usuário principal do Amazon RDS e example-rds-primary-password pela senha principal do Amazon RDS.

Solucionar erros de reinicialização do hive-hcatalog-server

Ao tentar reiniciar o hive-hcatalog-server, você pode receber o seguinte erro ou similar:

"2020-08-20T14:18:50,750 WARN [main] org.apache.hadoop.hive.metastore.HiveMetaStore - Tentando criar o banco de dados padrão novamente após o erro: Não é possível abrir uma conexão de teste com o banco de dados fornecido. JDBC url = jdbc:mysql://mysql-hive-meta.########.us-east-1.rds.amazonaws.com:3306/hive?createDatabaseIfNotExist=true&useSSL=true&serverSSlCert=/home/hadoop/global-bundle.pem, username = masteruser. Encerrando o pool de conexões (defina lazyInit como true se você espera iniciar o banco de dados após a aplicação). Exceção original: ------java.sql.SQLException: O host "172.31.41.187" está bloqueado devido a muitos erros de conexão; desbloqueie com 'mysqladmin flush-hosts'"

Esse erro ocorre quando a instância de banco de dados do Amazon RDS para MySQL bloqueia o nó primário do cluster do Amazon EMR como precaução de segurança. Para resolver esse erro, realize as etapas a seguir:

  1. Conecte-se a uma máquina local diferente ou a uma instância do Amazon Elastic Compute Cloud (Amazon EC2) que tenha a ferramenta mysqladmin instalada.
  2. Limpe o nó primário da instância de banco de dados:
    mysqladmin -h example-rds-db-instance-endpoint -P 3306 -u example-rds-primary-username -p flush-hosts
    Enter password: example-rds-primary-password
    Observação: substitua example-rds-primary-username pelo nome de usuário principal do Amazon RDS e example-rds-primary-password pela senha principal do Amazon RDS.
  3. Reinicie o hive-hcatalog-server.

Informações relacionadas

Usar um banco de dados do MySQL externo ou o Amazon Aurora

AWS OFICIALAtualizada há 10 meses