ClouderaManager6.3.1 KERBEROS KEYTAB相关参数设定无法生效的解决办法
最近自制了一个CSD 用来支持 SPARK THRIFT SERVER 在CM上的自动化部署。单实例测试目前没有问题。为了适配生产环境,需要考虑多实例部署。前面加 LOAD BALANCER 做 HA。
在安全环境下为了支持LOAD BALANCER ,就需要将 LOAD BALANCER 的 PRINCIPAL 也要生成加入到KEYTAB中。 因此在CSD 中也将LB 的PRINCIPAL 声明也加了进去:
{
"name" : "LB_PRINCIPAL",
"primary" : "hive",
"instance" : "${thrift_server_hiveserver2_host}"
}
{
"name" : "thrift_server_hiveserver2_host",
"label" : "Spark Thrift Server HiveServer2 Host",
"description" : "The Host of the thrift server HiveServer2",
"required" : "true",
"type" : "string",
"configurableInWizard" : true,
"default" : "fqdn-of-balancer.com"
},
理论上只要 在添加服务的时候将LB 的 主机名设置到 配置参数 thrift_server_hiveserver2_host中 即可,但是事情出乎预料。 最后LB 的 PRINCIPAL,KEYTAB 是生成了,但是PRICIPAL始终是thrift_server_hiveserver2_host的初始值 'hive/fqdn-of-balancer.com@REIGN_NAME',
,无论我如何设置参数,始终是如此。连 Cloudera Manager生成丢失的凭据的功能也不起作用。这可急坏了老夫。只好向Cloudera Manager祭出了调试大法,之后发现Cloudera Manager 在添加服务界面,进行参数配置之前,CM直接读取参数的初始值,生成PRINCIPAL,KEYTAB ,而不管后面配置界面的配置参数了。而后面CM生成丢失凭据的逻辑简单而粗暴:
for (RoleHandler roleHand : servHand.getRoleHandlers()) { for (DbRole role : service.getRolesWithType(roleHand.getRoleName())) { if (requiresKeytab(cmf, roleHand, role) && role.getMergedKeytab() == null) { Collection<String> principals = roleHand.getRequiredPrincipals(role, null /* useHostName */).values(); if (principals.isEmpty()) { LOG.warn("Tried to create keytab for role " + role.getName() + " even though it doesn't require any principals"); continue; } for (String princ : principals) { result.role2Princ.put(role.getId(), princ); DbCredential cred = cmf.findCredentialByPrincipal(princ); if (cred != null) { // Store existing principals so we don't regenerate them result.existingPrincipals.put(c个red.getPrincipal(), cred.getKeytab()); } } } }
即CM 会判断是否KEYTAB数据已经为 某ROLE生成了,生成后就不管了。因此一但新服务凭据生成,即使配置发生了变化,CM也不管了,这就是为啥 CM 生成丢失的凭据功能也是实效的。为了解决问题
我也只好以暴制暴:
修改CM元数据:
update ROLES set MERGED_KEYTAB=NULL WHERE ROLE_TYPE='SPARK2_YARN_THRIFT_SERVER';
然后 在Cloudera Manager 安全页面 点击 重新生成缺失PRINCIPAL, 搞定。
浙公网安备 33010602011771号