在NodeManager中,有三种运行Container的方式,它们分别是:
从它们的名字中,我们就能看得出来,默认情况下,一定使用的是DefaultContainerExecutor。
而一般情况下,DefaultContainerExecutor也确实能够满足我们的需求。
DefaultContainerExecutor
这个ContainerExecutor的实现实际上很简单,就是通过构建一个脚本来执行而已。
支持Windows脚本以及Linux脚本。
在ContainerExecutor启动一个Container的过程中,涉及到了三个脚本,它们分别是:
这三个脚本,都是跟Container相关的,所以它们都被放在一个Container所代表的目录结构下。
在NodeManager中,会为每个Application,以及每个Container建立一个对应的目录,在每个Container的目录下,就放置了一些运行这个Container必需的信息。
一般来说,这些目录是位于**/tmp**这个目录下,并且会在一个Application完成后,被删除。减少磁盘空间的消耗。
我们分别查看一下,上面我们所说的那三个脚本文件的内容。
default-container_executor.sh:
我们可以看到,在这个脚本文件的内部,会启动default_container_executor_session.sh这个脚本,并将执行结果写入到这个Container的一个名为Container ID+pid.exitcode的文件中。
而default_container_executor_session.sh这个脚本呢?
我们可以看到,它主要是启动launch_container.sh这个脚本。
而我们可以看到,launch_container.sh中,就负责运行相应的Container,也能是MRAppMaster,也可能是Mapper或者Reducer:
在launch_container.sh中,设置了很多环境变量。
这里因为我查看了一个ApplicationMaster的Container,所以启动的是MRAppMaster。
那么,DefaultContainerExecutor应该就是首先执行default_container_executor.sh这个脚本
实际上,DefaultContainerExecutor中,实例化的是一个UnixLocalWrapperScriptBuilder对象,而这个对象,是LocalWrapperScriptBuilder的一个子类,并且在constructor中调用了LocalWrapperScriptBuilder的constructor。
总之,最后DefaultContainerExecutor确实就是直接调用了default_container_executor.sh这个脚本。
我们可以看到,它的实现实际上非常简单。
同时,我们也可以看到,这个实现有一些问题,即,对于资源隔离做的并不好。全部Container都是由运行NodeManager的那个用户启动的。
LinuxContainerExecutor
而LinuxContainerExecutor就解决了上面的那个问题。
从代码中,我们可以看到,现在,launch a container时,它是调用了container-executor这个程序:
那么,container-executor这个程序是啥东西呢?
在Hadoop的安装目录下,bin目录中,你应该就会发现这个程序。
这个执行器仅在GNU/Linux上支持。在安全状态启用时,这个执行器以提交应用的YARN用户运行容器,在非安全状态时以特定用户执行(默认是nobody)。在安全状态启用时,这个执行器需要所有的用户账户在容器启动的集群节点被创建。它会用到包含在Hadoop部署包中的setuid可执行工具,NodeManager使用这个工具来启动和kill掉容器。为了最大化安全,executor安装限制本地文件和被容器使用目录(如共享对象,jars,中间文件,日志文件等等)的权限和用户/组所属权。特别需要注意的一点,正是因为此,除了应用所有者和NodeManager外,不该有其它用户能访问任何上述本地文件或目录
编译可执行文件
如果你的环境中安装了maven,那可以参照官方帮助中的编译方法:
mvn package -Dcontainer-executor.conf.dir=/etc/
参数-Dcontainer-executor.conf.dir传入的路径应该是集群节点上放置配置文件的路径,保证setuid可执行文件能定位到。可执行文件应该安装在$HADOOP_YARN_HOME/bin目录下。
分配可执行文件权限
[root@hadoop-1 bin]# chown root:hadoop /home/hadoop/hadoop-2.8/bin/container-executor
[root@hadoop-1 bin]# chmod 6050 /home/hadoop/hadoop-2.8/bin/container-executor
这里的组hadoop是NodeManager Unix用户(yarn)所属的组,并且组内没有非hadoop相关的用户,以防安全风险。这个组名需要在yarn-site.xml和container-executor.cfg中都配置,
配置yarn-site.xml
<property>
<name>yarn.nodemanager.container-executor.classname>
<value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutorvalue>
property>
<property>
<name>yarn.nodemanager.linux-container-executor.pathname>
<value>/home/hadoop/hadoop-2.8/bin/container-executorvalue>
property>
<property>
<name>yarn.nodemanager.linux-container-executor.groupname>
<value>hadoopvalue>
property>
分配本地目录权限
LinuxTaskController还需要在container-executor.cfg中配置的yarn.nodemanager.local-dirs和yarn.nodemanager.log-dirs路径被赋予755权限。设置如下:
[root@hadoop-1 ~]# mkdir -p /hadoop/yarn/local
[root@hadoop-1 ~]# mkdir -p /hadoop/yarn/log
[root@hadoop-1 yarn]# chown yarn:hadoop /hadoop/yarn/local
[root@hadoop-1 yarn]# chown yarn:hadoop /hadoop/yarn/log
[root@hadoop-1 yarn]# chmod 755 /hadoop/yarn/local
[root@hadoop-1 yarn]# chmod 755 /hadoop/yarn/log
配置container-executor.cfg文件
[root@hadoop-1 ~]# vim /data/apps/hadoop-3.3.1/etc/hadoop/container-executor.cfg
yarn.nodemanager.local-dirs=/hadoop/yarn/local
yarn.nodemanager.log-dirs=/hadoop/yarn/log
yarn.nodemanager.linux-container-executor.group=hadoop
banned.users=hdfs,yarn,mapred,bin
min.user.id=1000
配置文件container-executor.cfg需要拷贝到之前编译可执行文件中指定的/etc/目录下,以便能被可执行文件访问到。
[root@hadoop-1 ~]# cp /data/apps/hadoop-3.3.1/etc/hadoop/container-executor.cfg /etc/
配置文件目录需要运行在root用户,hadoop组,并且赋予0400权限,配置如下:
[root@hadoop-1 ~]# chown root:hadoop /etc/container-executor.cfg
[root@hadoop-1 ~]# chmod 400 /etc/container-executor.cfg
必须如此配置,因为可执行程序逻辑会检测这些权限,否则NodeManager会启动失败。_
最后,再总结下所有涉及目录的权限和权属分配表,以保证你做对了,任意一项都要严格遵守配置。
Filesystem | Path | User:Group | Permissions |
---|---|---|---|
local | container-executor | root:hadoop | –Sr-s–* |
local | conf/container-executor.cfg | root:hadoop | r-------* |
local | yarn.nodemanager.local-dirs | yarn:hadoop | drwxr-xr-x |
local | yarn.nodemanager.log-dirs | yarn:hadoop | drwxr-xr-x |
配置文件的坑
经过了上述审慎配置后,检查了无数遍,依然无法运行nodeManager,始终报如下错误:
Caused by: org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationException: ExitCodeException exitCode=24: Can’t get group information for hadoop - Success.
问题的原因是hadoop编码不够严谨,如果.cfg中group组配置中存在空格,就会始终报检测不到组的错误。这个解决方案借鉴了secfree的博客,文章写的非常赞,完美解决这个问题。
检测错误,运行:
[root@hadoop-1 bin]# ./container-executor --checksetup Can't get group information for hadoop - Success
修复错误:
[root@hadoop-1 etc]# chmod 777 container-executor.cfg
[root@hadoop-2 etc]# vim container-executor.cfg
yarn.nodemanager.local-dirs=/hadoop/yarn/local
yarn.nodemanager.log-dirs=/hadoop/yarn/log
yarn.nodemanager.linux-container-executor.group=hadoop
banned.users=hdfs,yarn,mapred,bin
min.user.id=1000
[root@hadoop-2 etc]# chmod 0400 container-executor.cfg
希望对正在查看文章的您有所帮助,记得关注、评论、收藏,谢谢您