commit 06cd17bdedf300996371621ded043f70eca84f6d Author: Eric Yang Date: Tue Feb 20 17:56:30 2018 -0500 YARN-7942. Fixed secure ZooKeeper setup for YARN registry. (Contributed by Eric Yang) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java index 612b8b4..bea9a76 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/client/ServiceClient.java @@ -35,6 +35,7 @@ import org.apache.hadoop.registry.client.api.RegistryOperationsFactory; import org.apache.hadoop.registry.client.binding.RegistryUtils; import org.apache.hadoop.security.Credentials; +import org.apache.hadoop.security.HadoopKerberosName; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.token.Token; import org.apache.hadoop.util.VersionInfo; @@ -83,6 +84,7 @@ import java.io.File; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; @@ -91,6 +93,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import static org.apache.hadoop.registry.client.api.RegistryConstants.KEY_REGISTRY_USER_ACCOUNTS; import static org.apache.hadoop.yarn.api.records.YarnApplicationState.*; import static org.apache.hadoop.yarn.service.conf.YarnServiceConf.*; import static org.apache.hadoop.yarn.service.utils.ServiceApiUtil.jsonSerDeser; @@ -450,11 +453,6 @@ public int actionDestroy(String serviceName) throws YarnException, + appDir); destroySucceed = false; } - try { - deleteZKNode(serviceName); - } catch (Exception e) { - throw new IOException("Could not delete zk node for " + serviceName, e); - } String registryPath = ServiceRegistryUtils.registryPathForInstance(serviceName); try { @@ -480,54 +478,46 @@ public int actionDestroy(String serviceName) throws YarnException, private synchronized RegistryOperations getRegistryClient() throws SliderException, IOException { - if (registryClient == null) { - registryClient = - RegistryOperationsFactory.createInstance("ServiceClient", getConfig()); + Configuration conf = getConfig(); + if (UserGroupInformation.isSecurityEnabled() && + !StringUtils.isEmpty(conf.get("yarn.resourcemanager.principal")) + && !StringUtils.isEmpty(conf.get("yarn.resourcemanager.keytab"))) { + // Only take the first section of the principal + // e.g. hdfs-demo@EXAMPLE.COM will take hdfs-demo + // This is because somehow zookeeper client only uses the first section + // for acl validations. + HadoopKerberosName hkn = new HadoopKerberosName(conf + .get("yarn.resourcemanager.principal")); + String username = hkn.getServiceName(); + StringBuilder sb = new StringBuilder(); + sb.append(username); + sb.append("/"); + String host = hkn.getHostName(); + if (host.equals("_HOST")) { + sb.append(InetAddress.getLocalHost().getHostName()); + } else { + sb.append(host); + } + sb.append("@"); + sb.append(hkn.getRealm()); + LOG.info("Set registry user accounts: sasl: {}, " + + "kerberos principal: {}", username, sb.toString()); + conf.set(KEY_REGISTRY_USER_ACCOUNTS, "sasl:" + username); + registryClient = RegistryOperationsFactory + .createKerberosInstance(conf, + "Client", sb.toString(), + conf.get("yarn.resourcemanager.keytab")); + } else { + registryClient = RegistryOperationsFactory + .createInstance("ServiceClient", getConfig()); + } registryClient.init(getConfig()); registryClient.start(); } return registryClient; } - private boolean deleteZKNode(String clusterName) throws Exception { - CuratorFramework curatorFramework = getCuratorClient(); - String user = RegistryUtils.currentUser(); - String zkPath = ServiceRegistryUtils.mkServiceHomePath(user, clusterName); - if (curatorFramework.checkExists().forPath(zkPath) != null) { - curatorFramework.delete().deletingChildrenIfNeeded().forPath(zkPath); - LOG.info("Deleted zookeeper path: " + zkPath); - return true; - } else { - LOG.info( - "Service '" + clusterName + "' doesn't exist at ZK path: " + zkPath); - return false; - } - } - - private synchronized CuratorFramework getCuratorClient() - throws BadConfigException { - String registryQuorum = - getConfig().get(RegistryConstants.KEY_REGISTRY_ZK_QUORUM); - - // though if neither is set: trouble - if (ServiceUtils.isUnset(registryQuorum)) { - throw new BadConfigException( - "No Zookeeper quorum provided in the" + " configuration property " - + RegistryConstants.KEY_REGISTRY_ZK_QUORUM); - } - ZookeeperUtils.splitToHostsAndPortsStrictly(registryQuorum); - - if (curatorClient == null) { - curatorClient = - CuratorFrameworkFactory.builder().connectString(registryQuorum) - .sessionTimeoutMs(10000).retryPolicy(new RetryNTimes(5, 2000)) - .build(); - curatorClient.start(); - } - return curatorClient; - } - private void verifyNoLiveAppInRM(String serviceName, String action) throws IOException, YarnException { Set types = new HashSet<>(1);