目录
1 案例目标
使用SSL证书对Shuffle过程加密
2 环境要求
Hadoop完全分布式集群
主机 | Hadoop功能 |
---|---|
hadoop01 | namenode/resourceManager/作业提交客户端 |
hadoop02 | datanode/nodeManager |
hadoop03 | datanode/nodeManager |
3 知识储备
除了web通讯之外,Hadoop集群的进程和服务之间常规的数据交换基于RPC(remote procedure call,远程过程调用)。这包括控制消息,状态消息或者数据,而且在主机间进行Shuffle和Sort操作时也需要交互中间数据。
当然最佳方式是进行网络隔离,防止数据被嗅探,但是一种妥协的做法是使用加密的SSL进行RPC通讯。
通过安装必要的证书并且在集群从节点上进行配置,这样可以使shuffle在交互中间数据时进行加密。
在MapReduce作业的生命周期中,Shuffle是将数据由Map任务向Reduce任务移动的过程。这个数据移动过程需要通过网络跨多个机器。跨网络移动数据通常使用HTTP协议。
HTTP协议本身是纯文本,是一种非加密形式,这会导致信息泄露。HTTPS是HTTP的加密形式,HTTP端点间的数据包会使用SSL(Secure Socket Layer )加密。Hadoop允许在Map和Reduce任务节点间利用HTTPS对Shuffle过程进行加密。
Hadoop提供了相应的配置,可以做到:
-
控制shuffle过程在HTTP和HTTPS间进行切换
-
指定HTTP加密使用的keystore和truststore
-
当添加或者移除节点时重载truststore
4 案例流程
-
在core-site.xml添加SSL配置
-
配置mapred-site.xml启用shuffle加密
-
ssl-server.xml和ssl-client.xml指定keystore和truststore
-
启动集群
-
运行测试
5 案例实践
Step 1 core-site.xml配置
要使shuffle启用加密可以在集群中所有节点的core-site.xml中配置如下属性:
属性 | 默认值 | 说明 |
---|---|---|
hadoop.ssl.require.client.cert | false | 是否需要客户端证书 |
hadoop.ssl.hostname.verifier | DEFAULT | 提供给HttpsURLConnections的主机名验证器. 合法的值是: DEFAULT, STRICT, STRICT_I6, DEFAULT_AND_LOCALHOST 和ALLOW_ALL |
hadoop.ssl.keystores. factory.class | org.apache.hadoop.security. ssl.FileBasedKeyStoresFactory | 要用的KeyStoresFactory实现 |
hadoop.ssl.server.conf | ssl-server.xml | 配置提取ssl server keystore信息的文件,该文件通常在类路径中,比如:Hadoop的conf文件夹 |
hadoop.ssl.client.conf | ssl-client.xml | 配置提取ssl server keystore信息的文件,该文件通常在类路径中,比如:Hadoop的conf文件夹 |
hadoop.ssl.enabled.protocols | TLSv1,SSLv2Hello,TLSv1.1,TLSv1.2 | 支持的SSL协议 |
说明:
-
客户端证书通常需要设置为false,原因参考后面【其他说明-客户端证书】一节
-
集群中配置文件中的所有属性标记为final,表示不允许修改配置,比如其他框架或者用户
core-site.xml具体配置:
<property> <name>hadoop.ssl.require.client.cert</name> <value>false</value> <final>true</final> </property> <property> <name>hadoop.ssl.hostname.verifier</name> <value>DEFAULT</value> <final>true</final> </property> <property> <name>hadoop.ssl.keystores.factory.class</name> <value>org.apache.hadoop.security.ssl.FileBasedKeyStoresFactory</value> <final>true</final> </property> <property> <name>hadoop.ssl.server.conf</name> <value>ssl-server.xml</value> <final>true</final> </property> <property> <name>hadoop.ssl.client.conf</name> <value>ssl-client.xml</value> <final>true</final> </property>
[root@hadoop01 ~]# cd /opt/hadoop-2.8.5/etc/hadoop/
[root@hadoop01 hadoop]# ll
Step 2 mapred-site.xml配置
要启用加密的shuffle,需要在集群的所有节点上对mapred-site.xml做如下属性配置:
属性 | 默认值 | 说明 |
---|---|---|
mapreduce.shuffle.ssl.enabled | false | 是否启用加密shuffle |
说明:
在集群配置文件中,该属性必须标记为final
mapred-site.xml具体配置
<property> <name>mapreduce.shuffle.ssl.enabled</name> <value>true</value> <final>true</final> </property>
Step 3 Keystore和Truststore设置
当前FileBasedKeyStoresFactory是唯一的KeyStoresFactory实现。在FileBasedKeyStoresFactory中需要通过ssl-server.xml和ssl-client.xml文件设置相关属性,以便配置keystore和truststore。
ssl-server.xml (Shuffle server)配置:
属性 | 默认值 | 说明 |
---|---|---|
ssl.server.keystore.type | jks | Keystore文件类型(jks表示:Java keystores) |
ssl.server.keystore.location | NONE | 本地节点的Keystore文件位置,运行任何MapReduce作业都需要读取次文件 |
ssl.server.keystore.password | NONE | Keystore文件密码,任何keystore和truststore都是受密码保护的,这里指定访问keystore的密码 |
ssl.server.truststore.type | jks | Truststore文件类型 |
ssl.server.truststore.location | NONE | Truststore文件位置 |
ssl.server.truststore.password | NONE | Truststore文件密码 |
ssl.server.truststore.reload.interval | 10000 | Truststore重载间隔,单位为毫秒 |
复制ssl-server.xml.example文件生成一份新的ssl-server.xml文件:
[root@hadoop01 hadoop]# cp ssl-server.xml.example ssl-server.xml
ssl-server.xml具体配置
<configuration> <!-- Server Trust Store --> <property> <name>ssl.server.truststore.type</name> <value>jks</value> <description>Optional. The keystore file format, default value is "jks". </description> </property> <property> <name>ssl.server.truststore.location</name> <value>${user.home}/keystores/truststore.jks</value> <description>Truststore to be used by NN and DN. Must be specified. </description> </property> <property> <name>ssl.server.truststore.password</name> <value>Smx990726@</value> <description>Optional. Default value is "". </description> </property> <property> <name>ssl.server.truststore.reload.interval</name> <value>10000</value> <description>Truststore reload check interval, in milliseconds. Default value is 10000 (10 seconds). </description> </property> <!-- Server Certificate Store --> <property> <name>ssl.server.keystore.type</name> <value>jks</value> <description>Optional. The keystore file format, default value is "jks". </description> </property> <property> <name>ssl.server.keystore.location</name> <value>${user.home}/keystores/server-keystore.jks</value> <description>Keystore to be used by NN and DN. Must be specified. </description> </property> <property> <name>ssl.server.keystore.password</name> <value>Smx990726@</value> <description>Must be specified. </description> </property> <property> <name>ssl.server.keystore.keypassword</name> <value>Smx990726@</value> <description>Must be specified. </description> </property> <property> <name>ssl.server.exclude.cipher.list</name> <value>TLS_ECDHE_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5</value> <description>Optional. The weak security cipher suites that you want excluded from SSL communication.</description> </property> </configuration>
ssl-client.xml(Reducer/Fetcher)配置
属性 | 默认值 | 说明 |
---|---|---|
ssl.client.keystore.type | jks | Keystore文件类型 |
ssl.client.keystore.location | NONE | 本地节点上的Keystore文件位置,运行任何MapReduce作业都需要访问此文件 |
ssl.client.keystore.password | NONE | Keystore文件密码 |
ssl.client.truststore.type | jks | Truststore文件类型 |
ssl.client.truststore.location | NONE | Truststore文件位置 |
ssl.client.truststore.password | NONE | Truststore文件密码 |
ssl.client.truststore.reload.interval | 10000 | Truststore重载间隔,单位为毫秒 |
复制ssl-client.xml.example文件生成一份新的ssl-client.xml文件:
[root@hadoop01 hadoop]# cp ssl-client.xml.example ssl-client.xml
ssl-client.xml具体配置
<configuration> <!-- Client Trust Store --> <property> <name>ssl.client.truststore.type</name> <value>jks</value> <description>Optional. The keystore file format, default value is "jks". </description> </property> <property> <name>ssl.client.truststore.location</name> <value>${user.home}/keystores/truststore.jks</value> <description>Truststore to be used by clients like distcp. Must be specified. </description> </property> <property> <name>ssl.client.truststore.password</name> <value>Smx990726@</value> <description>Optional. Default value is "". </description> </property> <property> <name>ssl.client.truststore.reload.interval</name> <value>10000</value> <description>Truststore reload check interval, in milliseconds. Default value is 10000 (10 seconds). </description> </property> <!-- Client certificate Store --> <property> <name>ssl.client.keystore.type</name> <value>jks</value> <description>Optional. The keystore file format, default value is "jks". </description> </property> <property> <name>ssl.client.keystore.location</name> <value>${user.home}/keystores/client-keystore.jks</value> <description>Keystore to be used by clients like distcp. Must be specified. </description> </property> <property> <name>ssl.client.keystore.password</name> <value>Smx990726@</value> <description>Optional. Default value is "". </description> </property> <property> <name>ssl.client.keystore.keypassword</name> <value>Smx990726@</value> <description>Optional. Default value is "". </description> </property> </configuration>
配置完成后,将配置文件分发到所有节点:
scp core-site.xml ssl-server.xml ssl-client.xml mapred-site.xml root@hadoop02:/opt/hadoop-2.8.5/etc/hadoop/ scp core-site.xml ssl-server.xml ssl-client.xml mapred-site.xml root@hadoop03:/opt/hadoop-2.8.5/etc/hadoop/
Step 4 激活Shuffle加密
激活Shuffle加密需要重启所有NodeManagers节点:start-all.sh
注意:使用加密的shuffle会带来明显的性能问题
在这里遇到问题:
hadoop02、hadoop03节点启动后jps没有nodemanager
解决途径:
查看日志找出问题:
cd /opt/hadoop-2.8.5/logs/
cat yarn-root-nodemanager-hadoop02.log
报错信息为:2022-03-13 21:47:08,850 FATAL org.apache.hadoop.yarn.server.nodemanager.NodeManager: Error starting NodeManager
java.lang.RuntimeException: java.io.FileNotFoundException: /root/keystores/keystore.jks (没有那个文件或目录)我们的配置文件是.jks文件,而root目录下的keystores的文件复制的时候没有添加.jks
解决:
[root@hadoop02 keystores]# mv keystore keystore.jks
[root@hadoop02 keystores]# mv truststore truststore.jks将三个节点都进行如上修改
hadoop01:
hadoop03:
在hadoop01上:stop-all.sh 停掉重启服务start-all.sh
Step 5 运行测试
hadoop jar /opt/hadoop-2.8.5/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.5.jar pi 4 1000
如果没有可信任证书,将出现如下错误(说明shuffle加密已经起作用,shuflle时需要使用证书加密):
注意:在这里我的执行正确,提交mapreduce作业,map阶段正常,reduce阶段失败,报虚拟内存不足
22/03/10 16:00:48 INFO mapreduce.Job: Task Id : attempt_1646898479823_0006_m_000010_1, Status : FAILED Container [pid=3174,containerID=container_1646898479823_0006_01_000015] is running beyond virtual memory limits. Current usage: 70.9 MB of 1 GB physical memory used; 2.1 GB of 2.1 GB virtual memory used. Killing container. Dump of the process-tree for container_1646898479823_0006_01_000015 :
Container killed on request. Exit code is 143
Container exited with a non-zero exit code 143
原因分析:yarn调度发现虚拟内存不足。默认虚拟内存是实际内存的2.1,是系统先检查虚拟内存,认为不足就kill容器
查看磁盘利用率:
解决方案,不让hadoop检查虚拟内存:
设置:yarn-site.xml
添加:
不检查虚拟内存:
<property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> <description>Whether virtual memory limits will be enforced for containers</description> </property>
提高虚拟内存和物理内存的倍数
<property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>4</value> <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description> </property>
[root@hadoop01 hadoop]# scp yarn-site.xml root@hadoop02:/opt/hadoop-2.8.5/etc/hadoop/
[root@hadoop01 hadoop]# scp yarn-site.xml root@hadoop03:/opt/hadoop-2.8.5/etc/hadoop/
拷贝到hadoop02、hadoop03节点。
停止服务并重启,重新执行
6 案例解析
客户端证书
目前,客户端证书(私钥)keystore文件对所有向集群提交作业的用户来说都是可读的,因此使用客户端证书也不能完全保证客户端作业是一个合法的reducer任务,一些非法的作业可以读取keystore文件,并使用客户端证书和shuffle服务器建立连接,但是除非它有一个合理的JobToken,否则不能从Shuffle上返回数据。一个作业,通过自己的JobToken仅可以检索属于它自己的数据。
重载Truststore
默认情况下,truststore每隔10秒重载一次配置。如果使用新的truststore文件替换旧的文件,这个文件会被重新读取。它上面的证书也会被换成新证书。通过这种机制可以向集群添加或者删除节点,或者添加或者移除受信任的客户端。新配置生效不必重启NodeManager。
7 案例总结
-
在Hadoop集群中,默认情况下,任何人都可以提交作业,使用计算资源
-
Map阶段完成后,在进行Reduce阶段时要经历Shuffle阶段在各节点间传输数据,默认情况下这个过程没有使用HTTPS传输
-
通过本案例是Shuffle过程基于SSL进行传输数据
-
要基于SSL需要配置keystore和truststore
8 扩充vbox虚拟盘
virtualbox非常简单修改硬盘大小(界面操作) - 简书
9 参考文档
ssl证书制作:案例 2:Hadoop集群SSL证书制作_Siobhan_明鑫的博客-CSDN博客
hadoop加密报错解决:hadoop集群加密问题汇总_Siobhan_明鑫的博客-CSDN博客