注,本次使用腾讯云EMR的 EMR-V3.5.0 版本。
涉及组件版本为:hdfs-3.2.2,yarn-3.2.2,openldap-2.4.44,spark-3.2.2,krb5-1.15.1
工作原理
本文操作的主要对象是SSSD(System Security Services Dameon,官网地址:https://sssd.io),它是一个工作在Linux系统上与LDAP/AD对接进行身份认证和账号缓存的服务,与直接同LDAP对接相比,SSSD有如下一些优点:
- 支持离线认证:当本地主机与LDAP服务器断网的情况下,用户依然可以登录
- 减轻LDAP服务器的负载:通过SSSD,一台Linux主机仅与LDAP服务器建立一个连接
- 支持多个LDAP/AD:通过SSSD,可以同时配置多个LDAP/AD作为认证源
配置完成后,linux的认证都通过sssd代理来实现,故ldap上的用户不会在linux系统上(/etc/passwd)。
操作步骤
说明:本文所有命令均以root用户身份执行。
创建SSSD的Bind DN
在emr的任一一个master上执行
由于SSSD需要登录OpenLDAP检索账号,所以需要为其在OpenLDAP上创建一个专职账号:cn=sssd,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com,其中该用户密码为Admin1234!
。操作命令如下:
代码语言:javascript复制cat << EOF | ldapadd -D "cn=hadoop,dc=emr,dc=cloud,dc=tencent,dc=com" -w ldap密码
dn: cn=sssd,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com
sn: sssd
cn: sssd
objectClass: top
objectclass: person
userPassword: Admin1234!
EOF
说明: 配置: "cn=hadoop,dc=emr,dc=cloud,dc=tencent,dc=com" 、"ou=People,dc=emr,dc=cloud,dc=tencent,dc=com" 为emr中的默认的配置,需要根据实际情况进行修改。
emr中ldap的密码为购买emr集群时候设置的密码。
安装软件包
在emr的全部节点上执行
安装sssd服务,命令如下:
代码语言:javascript复制yum -y install openldap-clients sssd sssd-client sssd-ldap sssd-tools authconfig nss-pam-ldapd oddjob-mkhomedir
配置文件
在emr的全部节点上执行
使用 authconfig 来修改部分的SSSD配置,命令如下:
代码语言:javascript复制authconfig --enablesssd --enablesssdauth --enablemkhomedir --enablerfc2307bis --enableldap --enableldapauth --disableldaptls --disableforcelegacy --disablekrb5 --ldapserver ldap://172.16.48.31 --ldapbasedn "dc=emr,dc=cloud,dc=tencent,dc=com" --updateall
说明:需要根据实际情况修改–ldapserver 、 --ldapbasedn的参数值
执行成功后, /etc/sssd/sssd.conf 文件中已经有了部分配置内容。再进行修改文件 /etc/sssd/sssd.conf ,添加的配置为:
代码语言:javascript复制ldap_tls_reqcert = never
ldap_default_bind_dn = cn=sssd,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com
ldap_default_authtok_type = password
ldap_default_authtok = Admin1234!
override_homedir = /home/%u
default_shell = /bin/bash
修改完成后 /etc/sssd/sssd.conf 如下:
代码语言:javascript复制[domain/default]
autofs_provider = ldap
ldap_schema = rfc2307bis
krb5_realm = EMR-J457ZFNT
ldap_search_base = dc=emr,dc=cloud,dc=tencent,dc=com
krb5_server = 172.16.48.31:88
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
ldap_uri = ldap://172.16.48.31
ldap_id_use_start_tls = False
cache_credentials = True
ldap_tls_reqcert = never
ldap_tls_cacertdir = /etc/openldap/cacerts
ldap_default_bind_dn = cn=sssd,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com
ldap_default_authtok_type = password
ldap_default_authtok = Admin1234!
override_homedir = /home/%u
default_shell = /bin/bash
[sssd]
services = nss, pam, autofs
domains = default
[nss]
homedir_substring = /home
[pam]
[sudo]
[autofs]
[ssh]
[pac]
[ifp]
[secrets]
[session_recording]
修改SSH服务(可选)
在emr的全部节点上执行
emr集群节点默认已经修改完成了,可以跳过。
将 /etc/ssh/sshd_config 文件中的“UsePAM no”和“PasswordAuthentication no”注释掉(如果有的话),并设置添加“UsePAM yes”和“PasswordAuthentication yes”。
代码语言:javascript复制#UsePAM no
UsePAM yes
#PasswordAuthentication no
PasswordAuthentication yes
重启服务
在emr的全部节点上执行
让 sssd、oddjobd 服务开机自启,同时重启sssd、oddjobd、sshd
代码语言:javascript复制systemctl enable sssd oddjobd
systemctl restart sssd oddjobd sshd
systemctl status sssd oddjobd sshd
验证
在ldap上创建一个用户,该用户不在linux中。具体操作如下:
代码语言:javascript复制#先创建一个ldap用户信息文件
[root@172 ~]# vim user1.ldif
[root@172 ~]# cat user1.ldif
dn: uid=user1,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com
uid: user1
cn: user1
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: Admin1234!
loginShell: /bin/bash
uidNumber: 1001
gidNumber: 1000
homeDirectory: /home/user1
#添加用户
[root@172 ~]# ldapadd -x -W -D "cn=hadoop,dc=emr,dc=cloud,dc=tencent,dc=com" -f user1.ldif
Enter LDAP Password:
adding new entry "uid=user1,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com"
确认该用户只在ldap中。
代码语言:javascript复制[root@172 ~]# more /etc/passwd |grep user1
[root@172 ~]# id user1
uid=1001(user1) gid=1000(hadoop) groups=1000(hadoop)
切换登陆验证
使用 user1 用户进行切换登陆验证
代码语言:javascript复制#su切换到 user1
[root@172 ~]# su user1
[user1@172 /root]$ cd
[user1@172 ~]$ pwd
/home/user1
[user1@172 ~]$ id user1
uid=1001(user1) gid=1000(hadoop) groups=1000(hadoop)
#使用user1 用户登陆本机
[root@172 ~]# hostname
172.16.48.31
[root@172 ~]# ssh user1@localhost
user1@localhost's password:
Last login: Wed Feb 1 19:46:09 2023 from ::1
Welcome to tlinux 2.4 (tkernel4) for x86_64
Version 2.4 20221101
tlinux2.4-64bit-5.4.119-19.0009-20221101
[user1@172 ~]$ hostname
172.16.48.31
#使用user1 用户登陆其他节点
[user1@172 ~]$ hostname
172.16.48.31
[user1@172 ~]$ ssh user1@172.16.48.42
Warning: Permanently added '172.16.48.42' (ECDSA) to the list of known hosts.
user1@172.16.48.42's password:
Creating home directory for user1.
Welcome to tlinux 2.4 (tkernel4) for x86_64
Version 2.4 20221101
tlinux2.4-64bit-5.4.119-19.0009-20221101
[user1@172 ~]$ hostname
172.16.48.42
[user1@172 ~]$ id user1
uid=1001(user1) gid=1000(hadoop) groups=1000(hadoop)
[user1@172 ~]$ ssh user1@172.16.48.7
Warning: Permanently added '172.16.48.7' (ECDSA) to the list of known hosts.
user1@172.16.48.7's password:
Creating home directory for user1.
Welcome to tlinux 2.4 (tkernel4) for x86_64
Version 2.4 20221101
tlinux2.4-64bit-5.4.119-19.0009-20221101
[user1@172 ~]$ hostname
172.16.48.7
删除ldap用户验证
同上,再创建一个ldap测试账号 user2 。先验证 user1 和 user2 相互切换,并ssh登陆。
代码语言:javascript复制[user1@172 ~]$ su user2
Password:
[user2@172 /home/user1]$ cd
[user2@172 ~]$ pwd
/home/user2
[user2@172 ~]$ id user2
uid=1003(user2) gid=1000(hadoop) groups=1000(hadoop)
[user2@172 ~]$ ssh 172.16.48.49
Warning: Permanently added '172.16.48.49' (ECDSA) to the list of known hosts.
user2@172.16.48.49's password:
Creating home directory for user2.
Welcome to tlinux 2.4 (tkernel4) for x86_64
Version 2.4 20221101
tlinux2.4-64bit-5.4.119-19.0009-20221101
[user2@172 ~]$ pwd
/home/user2
[user2@172 ~]$ id user2
uid=1003(user2) gid=1000(hadoop) groups=1000(hadoop)
[user2@172 ~]$ su user1
Password:
[user1@172 /home/user2]$ cd
[user1@172 ~]$ pwd
/home/user1
验证将user2账号删除后,再尝试切换和登陆
代码语言:javascript复制#将用户user2 在ldap中删除,由于删除无明显返回,故执行2次来验证是否删除成功。
[root@172 ~]# ldapdelete -x -h 172.16.48.35 -D "cn=hadoop,dc=emr,dc=cloud,dc=tencent,dc=com" -w ldap密码
> "uid=user2,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com"
[root@172 ~]# ldapdelete -x -h 172.16.48.35 -D "cn=hadoop,dc=emr,dc=cloud,dc=tencent,dc=com" -w ldap密码
> "uid=user2,ou=People,dc=emr,dc=cloud,dc=tencent,dc=com"
ldap_delete: No such object (32)
matched DN: ou=People,dc=emr,dc=cloud,dc=tencent,dc=com
#确认删除成功后,在进行切换和登陆验证
[user2@172 ~]$ su user2
su: user user2 does not exist
[user2@172 ~]$ su user1
Password:
[user1@172 /home/user2]$ cd
[user1@172 ~]$ ssh user2@172.16.48.49
Warning: Permanently added '172.16.48.49' (ECDSA) to the list of known hosts.
user2@172.16.48.49's password:
Permission denied, please try again.
user2@172.16.48.49's password:
Permission denied, please try again.
user2@172.16.48.49's password:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
[user1@172 ~]$ su use2
su: user use2 does not exist
[user1@172 ~]$ ls -l /home/
total 16
drwx------ 2 hadoop hadoop 4096 Feb 2 10:21 hadoop
drwx------ 3 user1 hadoop 4096 Feb 2 11:12 user1
drwx------ 2 1003 hadoop 4096 Feb 2 10:50 user2
drwx------ 2 wang hadoop 4096 Feb 2 10:09 wang
提交任务验证
设置用户相关权限,具体操作如下:
代码语言:javascript复制#本地hdfs日志权限,根据用户设置
chmod 775 /data/emr/hdfs/logs
#hdfs相关权限
#因为提交的是spark任务,所以需要设置spark-history权限
su hadoop
hadoop fs -chmod 777 /spark-history
提交测试任务命令,具体操作如下:
代码语言:javascript复制#先做Kerberos认证
[user1@172 ~]$ kinit -kt emr-hd8hb6pt_wang.keytab wang@EMR-HD8HB6PT
[user1@172 ~]$ klist
Ticket cache: FILE:/tmp/krb5cc_1001
Default principal: wang@EMR-HD8HB6PT
Valid starting Expires Service principal
02/02/2023 10:44:04 02/02/2023 22:44:04 krbtgt/EMR-HD8HB6PT@EMR-HD8HB6PT
renew until 02/09/2023 10:44:04
#提交本地spark任务
[user1@172 ~]$ run-example SparkPi 10
Pi is roughly 3.141995141995142
#提交spark on yarnrenw
[user1@172 ~]$ spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode client
--driver-memory 2G --executor-memory 2G --executor-cores 2 --num-executors 3 /usr/local/service/spark/examples/jars/spark-examples_2.12-3.2.2.jar 100
2023-02-02 10:45:27,446 [WARN] [main] Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME. (org.apache.spark.deploy.yarn.Client(org.apache.spark.internal.Logging.logWarning:69))
Pi is roughly 3.1416419141641914
[user1@172 ~]$