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
yum install -y openldap openldap-servers openldap-clients compat-openldap
2. 复制数据库模版,并修改为ldap权限
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_ConFIG chown ldap. /var/lib/ldap/DB_CONFIG
3. 启动ldap,并设置开机自动启动
systemctl enable slapd && systemctl start slapd && systemctl status slapd
4. 检查ldap端口是否启动
[root@elcndc2kfk05 ~]# lsof -i:389 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME slapd 121435 ldap 8u IPv4 100203764 0t0 TCP *:ldap (LISTEN) slapd 121435 ldap 9u IPv6 100203765 0t0 TCP *: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=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}TjlmySyahZi5Ej8Fp8wEwmZUQ/oXb7MH
ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying 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=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
by dn.base="cn=Manager,dc=enn,dc=cn" read
by * none
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=enn,dc=cn
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=enn,dc=cn
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}TjlmySyahZi5Ej8Fp8wEwmZUQ/oXb7MH
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by dn="cn=Manager,dc=enn,dc=cn" write
by anonymous auth
by self write
by * none
olcAccess: {1}to dn.base=""
by * read
olcAccess: {2}to *
by dn="cn=Manager,dc=enn,dc=cn" write
by * read
导入
ldapmodify -Y EXTERNAL -H ldapi:/// -f chdomain.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying 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=cn objectClass: top objectClass: dcObject objectClass: organization o: enn.cn dc: enn dn: cn=Manager,dc=enn,dc=cn objectClass: organizationalRole cn: Manager dn: ou=bigdata,dc=enn,dc=cn objectClass: organizationalUnit ou: bigdata dn: ou=Group,dc=enn,dc=cn objectClass: organizationalRole cn: 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=config changetype: modify replace: olcLogLevel olcLogLevel: 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=config objectClass: olcModuleList cn: module olcModulePath: /usr/lib64/openldap olcModuleLoad: syncprov.la
导入:
[root@elcndc2dsjzt01 ldif_files]# ldapadd -Y EXTERNAL -H ldapi:/// -f syncprov_mod.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 adding new entry "cn=module,cn=config"
2. 启用OpenLDAP双主同步
[root@elcndc2dsjzt01 ldif_files]# cat configrep.ldif
dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1 ldap://10.37.54.187
olcServerID: 2 ldap://10.37.54.188
### Enable replication ###
dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
### Adding details for replication ###
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl:
rid=001
provider=ldap://10.37.54.187
binddn="cn=Manager,dc=enn,dc=cn"
bindmethod=simple
credentials=Long,123
searchbase="dc=enn,dc=cn"
type=refreshAndPersist
retry="5 5 300 5"
timeout=1
olcSyncRepl:
rid=002
provider=ldap://10.37.54.188
binddn="cn=Manager,dc=enn,dc=cn"
bindmethod=simple
credentials=Long,123
searchbase="dc=enn,dc=cn"
type=refreshAndPersist
retry="5 5 300 5"
timeout=1
-
add: olcMirrorMode
olcMirrorMode: 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=cn
uid: cloudera-scm
cn: Cloudera Manager
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}!!
shadowLastChange: 18037
loginShell: /sbin/nologin
uidNumber: 990
gidNumber: 985
homeDirectory: /var/lib/cloudera-scm-server
gecos: Cloudera Manager
dn: uid=flume,ou=People,dc=test,dc=enn,dc=cn
uid: flume
cn: Flume
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}!!
shadowLastChange: 18043
loginShell: /bin/false
uidNumber: 989
gidNumber: 983
homeDirectory: /var/lib/flume-ng
gecos: 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 = 2
services = nss,pam
domains = default
debug_level = 9
[nss]
filter_users = root,ldap
debug_level = 9
[pam]
debug_level = 9
[domain/default]
auth_provider = ldap
id_provider = ldap
chpass_provider = ldap
ldap_schema = rfc2307
ldap_uri = ldap://10.37.54.187:389
ldap_default_bind_dn = cn=Manager,dc=enn,dc=cn
ldap_default_authtok = Long,123
ldap_search_base = dc=test,dc=enn,dc=cn
ldap_access_filter = (&(objectClass=posixAccount)(uid={0}))
ldap_tls_reqcert = never
ldap_id_use_start_tls = False
ldap_tls_cacertdir = /etc/openldap/certs
cache_credentials = True
entry_cache_timeout = 600
ldap_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 sss shadow: files sss group: files sss
先从files获取,也就是/etc/passwd, /etc/shadow, /etc/group, 如果没有,就从sss获取。sss自然就是sssd服务连接的ldap了。
现在可以测试当openldap存在的用户,而os没有,通过id username的方式是否可以获取相关用户信息。



