Hadoop集成OpenLDAP统一管理

Hadoop涉及用户管理的组件主要为: Kerberos, Sentry, hive/impala/hue身份认证,Yarn启动container 。
以前一直使用OpenLDAP集成hive/impala,提供用户密码登入方式,这样避免客户端采用Kerberos连接,简化连接方式 。
但是Sentry用户组默认依靠HADOOP group mapping方式,也就是os用户和组,Yarn启动container也是依赖 os用户,简单的理解就是通过Linux命令 id username来获取用户及用户组 。
也就是说虽然OpenLDAP已经存在用户,OS层仍然要建立对应用户,当你有几个千用户的时候,Hadoop几百个节点,这种方式简直是灭绝人性 。意味着每次有人申请账号,需要在LDAP建立一个用户,同时要在os建立一个对应用户 。所以最近打算把之前遗留的hadoop系统进行改造,采用LDAP group mapping, 去除之前的OS GROUP mapping方式,账号全部统一管理 。
这里有一个概念先说一下,集成openldap之后,sentry, hive, imapla, hdfs组件会直接忽略os层账号及组(就是说即使你os层有账号,这些服务也不会使用,而是根据mapping设置,从ldap获取),唯一例外的是YARN,这玩意即使设置了group mapping,也不会去ldap获取 。这是因为yarn 仅仅通过 id username 来获取用户信息,很显然id命令是从os直接获取,为了解决这个问题,需要配合SSSD安全服务来实现 。(为什么其他服务没问题,而yarn不行? 我猜想是其他组件通过hdfs id xxxx,hdfs id这个命令会根据group mapping设置去获取用户组信息,而yarn走的是 id xxxx,如果yarn走hdfs id xxx,没理由获取不到用户和组 。)
一. OpenLDAP双主实现高可用,可参考网友文章:Centos 7 下安装LDAP 双主同步 - Zeus~ - 博客园
安装步骤(2台机器执行)
1. 安装LDAP
yuminstall -y openldap openldap-servers openldap-clientscompat-openldap 2. 复制数据库模版,并修改为ldap权限
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIGchown ldap. /var/lib/ldap/DB_CONFIG 3. 启动ldap,并设置开机自动启动
systemctl enable slapd && systemctl start slapd && systemctl status slapd 4. 检查ldap端口是否启动
[root@elcndc2kfk05 ~]# lsof -i:389COMMANDPID USERFDTYPEDEVICE SIZE/OFF NODE NAMEslapd121435 ldap8uIPv4 1002037640t0TCP *:ldap (LISTEN)slapd121435 ldap9uIPv6 1002037650t0TCP *:ldap (LISTEN) 5.生成管理员加密密码,2台机器的加密密码不同,不能共用 。
[root@elcndc2dsjzt01 ldif_files]# slappasswd New password: Re-enter new password: {SSHA}TjlmySyahZi5Ej8Fp8wEwmZUQ/oXb7MH 6. 编辑ldif,导入管理密码
[root@elcndc2dsjzt01 ldif_files]# cat chrootpw.ldif dn: olcDatabase={0}config,cn=configchangetype: modifyadd: olcRootPWolcRootPW: {SSHA}TjlmySyahZi5Ej8Fp8wEwmZUQ/oXb7MH ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif SASL/EXTERNAL authentication startedSASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=authSASL SSF: 0modifying entry "olcDatabase={0}config,cn=config" 7. 导入ldap基本数据结构
ldapadd -Y EXTERNAL-H ldapi:/// -f /etc/openldap/schema/cosine.ldif ldapadd -Y EXTERNAL-H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif ldapadd -Y EXTERNAL-H ldapi:/// -f /etc/openldap/schema/ppolicy.ldif ldapadd -Y EXTERNAL-H ldapi:/// -f /etc/openldap/schema/nis.ldif ldapadd -Y EXTERNAL-H ldapi:/// -f /etc/openldap/schema/dyngroup.ldif 8. 配置ldap的根域及管理域
[root@elcndc2dsjzt01 ldif_files]# cat chdomain.ldif dn: olcDatabase={1}monitor,cn=configchangetype: modifyreplace: olcAccessolcAccess: {0}to *by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" readby dn.base="cn=Manager,dc=enn,dc=cn" readby * nonedn: olcDatabase={2}hdb,cn=configchangetype: modifyreplace: olcSuffixolcSuffix: dc=enn,dc=cndn: olcDatabase={2}hdb,cn=configchangetype: modifyreplace: olcRootDNolcRootDN: cn=Manager,dc=enn,dc=cndn: olcDatabase={2}hdb,cn=configchangetype: modifyadd: olcRootPWolcRootPW: {SSHA}TjlmySyahZi5Ej8Fp8wEwmZUQ/oXb7MHdn: olcDatabase={2}hdb,cn=configchangetype: modifyadd: olcAccessolcAccess: {0}to attrs=userPassword,shadowLastChangeby dn="cn=Manager,dc=enn,dc=cn" writeby anonymous authby self writeby * noneolcAccess: {1}to dn.base=""by * readolcAccess: {2}to *by dn="cn=Manager,dc=enn,dc=cn" writeby * read 导入
ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif SASL/EXTERNAL authentication startedSASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=authSASL SSF: 0modifying entry "olcDatabase={1}monitor,cn=config"modifying entry "olcDatabase={2}hdb,cn=config"modifying entry "olcDatabase={2}hdb,cn=config"modifying entry "olcDatabase={2}hdb,cn=config"modifying entry "olcDatabase={2}hdb,cn=config" 9. 配置组织
[root@elcndc2dsjzt01 ldif_files]# cat basedomain.ldif dn: dc=enn,dc=cnobjectClass: topobjectClass: dcObjectobjectClass: organizationo: enn.cndc: enndn: cn=Manager,dc=enn,dc=cnobjectClass: organizationalRolecn: Managerdn: ou=bigdata,dc=enn,dc=cnobjectClass: organizationalUnitou: bigdatadn: ou=Group,dc=enn,dc=cnobjectClass: organizationalRolecn: Group 导入
ldapadd -x -D cn=Manager,dc=enn,dc=cn -W -f basedomain.ldif Enter LDAP Password: (输入之前设置的明文密码) 10. 打开openldap日志
[root@elcndc2dsjzt01 ldif_files]# cat loglevel.ldif dn: cn=configchangetype: modifyreplace: olcLogLevelolcLogLevel: stats[root@elcndc2dsjzt01 ldif_files]# ldapmodify -Y EXTERNAL -H ldapi:/// -f loglevel.ldif[root@elcndc2dsjzt01 ldif_files]#systemctl restart slapd 11. 修改rsyslog配置
$ touch /var/log/slapd.log$ echo local4.* /var/log/slapd.log >> /etc/rsyslog.conf$ systemctl restart rsyslog 通过以上操作,建立一个根域为 dc=enn,dc=cn,管理域为: cn=Manager,dc=enn,dc=cn, 公司组织: ou=bigdata,dc=enn,dc=cn, ou=Group,dc=enn,dc=cn.
二. 配置双主复制,2台机器均执行
1. 启用OpenLDAP复制模块syncprov
[root@elcndc2dsjzt01 ldif_files]# cat syncprov_mod.ldif dn: cn=module,cn=configobjectClass: olcModuleListcn: moduleolcModulePath: /usr/lib64/openldapolcModuleLoad: syncprov.la 导入:
[root@elcndc2dsjzt01 ldif_files]#ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov_mod.ldifSASL/EXTERNAL authentication startedSASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=authSASL SSF: 0adding new entry "cn=module,cn=config" 2. 启用OpenLDAP双主同步
[root@elcndc2dsjzt01 ldif_files]# cat configrep.ldif dn: cn=configchangetype: modifyreplace: olcServerIDolcServerID: 1 ldap://10.37.54.187olcServerID: 2 ldap://10.37.54.188### Enable replication ###dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=configchangetype: addobjectClass: olcOverlayConfigobjectClass: olcSyncProvConfigolcOverlay: syncprov### Adding details for replication ###dn: olcDatabase={2}hdb,cn=configchangetype: modifyadd: olcSyncReplolcSyncRepl:rid=001provider=ldap://10.37.54.187binddn="cn=Manager,dc=enn,dc=cn"bindmethod=simplecredentials=Long,123searchbase="dc=enn,dc=cn"type=refreshAndPersistretry="5 5 300 5"timeout=1olcSyncRepl:rid=002provider=ldap://10.37.54.188binddn="cn=Manager,dc=enn,dc=cn"bindmethod=simplecredentials=Long,123searchbase="dc=enn,dc=cn"type=refreshAndPersistretry="5 5 300 5"timeout=1-add: olcMirrorModeolcMirrorMode: TRUE 导入
ldapmodify -Y EXTERNAL -H ldapi:/// -f configrep.ldif 至此,一个双主OpenLDAP配置完成 。可以通过ApacheDirectoryStudio工具进行连接,并测试双主是否同步
3. 最后一步,修改OpenLDAP绑定地址,根据2台机器ip进行修改
[root@elcndc2dsjzt01 ldif_files]# cat /etc/sysconfig/slapd# OpenLDAP server configuration# see 'man slapd' for additional information# Where the server will run (-h option)# - ldapi:/// is required for on-the-fly configuration using client tools#(use SASL with EXTERNAL mechanism for authentication)# - default: ldapi:/// ldap:///# - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:///SLAPD_URLS="ldapi:/// ldap://10.37.54.187"# Any custom options#SLAPD_OPTIONS=""# Keytab location for GSSAPI Kerberos authentication#KRB5_KTNAME="FILE:/etc/openldap/ldap.keytab" 经过测试发现,如果不修改具体ip绑定,配置完双主无法启动,会报错 ldap:/// doesn't match之类的错误 。如果是单机,这一步不需要 。
三.迁移CDH账号到OpenLDAP
注:hadoop环境一般会有开发,测试,生产等环境,一般共用一个ldap即可,但是组织可以分为 dev, test, prd,可以考虑cdh自带用户放在各个自己的域,个人用户可以考虑用一个共公域,这样所有环境的个人用户全部共享 。
1. 安装迁移工具
yum install migrationtools -y 修改openldap域,匹配自己的组织. /usr/share/migrationtools/migrate_common.ph
# Default DNS domain$DEFAULT_MAIL_DOMAIN = "test.enn.cn";# Default base $DEFAULT_BASE = "dc=test,dc=enn,dc=cn"; 2. 生成要导入的用户和组,os自带用户实际不需要,可以删除 。
#cat /etc/passwd > people#cat /etc/group > group 3. 生成ldif文件
/usr/share/migrationtools/migrate_passwd.pl people people.ldif/usr/share/migrationtools/migrate_group.pl group group.ldif 4.粗略的查看ldif文件
[root@host21 ~]# more people.ldif dn: uid=cloudera-scm,ou=People,dc=test,dc=enn,dc=cnuid: cloudera-scmcn: Cloudera ManagerobjectClass: accountobjectClass: posixAccountobjectClass: topobjectClass: shadowAccountuserPassword: {crypt}!!shadowLastChange: 18037loginShell: /sbin/nologinuidNumber: 990gidNumber: 985homeDirectory: /var/lib/cloudera-scm-servergecos: Cloudera Managerdn: uid=flume,ou=People,dc=test,dc=enn,dc=cnuid: flumecn: FlumeobjectClass: accountobjectClass: posixAccountobjectClass: topobjectClass: shadowAccountuserPassword: {crypt}!!shadowLastChange: 18043loginShell: /bin/falseuidNumber: 989gidNumber: 983homeDirectory: /var/lib/flume-nggecos: Flume 5. 导入ldif文件
#ldapadd -x -W -D "cn=Manager,dc=xxx,dc=com" -f people.ldif#ldapadd -x -W -D "cn=Manager,dc=xxx,dc=com" -f group.ldif 经过以上步骤,除了os自带用户,其他用户包括cdh用户,个人用户就全部导入到OpenLDAP
四. 配置CDH group mapping
1. hadoop.security.group.mapping: org.apache.hadoop.security.LdapGroupsMapping
2. hadoop.security.group.mapping.ldap.url: ldap://xxxxx:389
3. hadoop.security.group.mapping.ldap.bind.user:cn=Manager,dc=enn,dc=en
4. hadoop.security.group.mapping.ldap.bind.password: 密码
5. hadoop.security.group.mapping.ldap.base:dc=dev,dc=enn,dc=cn
6. hadoop.security.group.mapping.ldap.search.filter.user:(&(objectClass=posixAccount)(uid={0}))
7. hadoop.security.group.mapping.ldap.search.filter.group:(objectClass=posixGroup)
8. hadoop.security.group.mapping.ldap.search.attr.member:memberUid
9.修改core-site.xml文件,添加如下:
hadoop.security.group.mapping.ldap.posix.attr.uid.name=uid
重启hadoop系统,整个集成openldap工作就基本完成了 。
这里解释一下:(&(objectClass=posixAccount)(uid={0})),(objectClass=posixGroup) 的含义,在迁移cdh账号那一步产生 people.ldif,和group.ldif,查看内容会发现,用户使用的就是posixAccount,用户属性采用的是uid, 组就是posixGroup.这就是为什么配置cdh的时候需要修改默认2个objectclass的原因 。
测试,通过hdfs id xxxx, 这样就会根据上述配置去ldap获取用户信息,而忽略os层 。
五. 安装sssd,解决yarn无法使用openldap的账号(介绍部分已经说明了yarn默认只通过id xxxx来获取用户和组,无法从ldap获取用户,那么启动container的时候就会出问题)
sssd需要在所有yarn节点安装
1. 安装sssd
yum install -y sssd 2. 修改配置文件,并设置600权限,否者无法启动
[root@host21 ~]# cat /etc/sssd/sssd.conf [sssd]config_file_version = 2services = nss,pamdomains = defaultdebug_level = 9[nss]filter_users = root,ldapdebug_level = 9[pam]debug_level = 9[domain/default]auth_provider = ldapid_provider = ldapchpass_provider = ldapldap_schema = rfc2307ldap_uri = ldap://10.37.54.187:389ldap_default_bind_dn = cn=Manager,dc=enn,dc=cnldap_default_authtok = Long,123ldap_search_base = dc=test,dc=enn,dc=cnldap_access_filter = (&(objectClass=posixAccount)(uid={0}))ldap_tls_reqcert = neverldap_id_use_start_tls = Falseldap_tls_cacertdir = /etc/openldap/certscache_credentials = Trueentry_cache_timeout = 600ldap_network_timeout = 3 chmod 600 /etc/sssd/sssd.conf 3. 启动sssd
systemctl start sssd && sytemctl enabled sssd 4. 刷新所有客户端配置,启用sssd 。
# authconfig --enablesssdauth --enablesssd --updateall 简单说一下sssd的原理,通过/etc/nsswitch.conf文件可以看到以下几行:
passwd:files sssshadow:files sssgroup:files sss 先从files获取,也就是/etc/passwd, /etc/shadow, /etc/group, 如果没有,就从sss获取 。sss自然就是sssd服务连接的ldap了 。
【Hadoop集成OpenLDAP统一管理】现在可以测试当openldap存在的用户,而os没有,通过id username的方式是否可以获取相关用户信息 。