diff --git a/hadoop-yarn-project/hadoop-yarn/bin/yarn b/hadoop-yarn-project/hadoop-yarn/bin/yarn index 022287a..41b89e1 100755 --- a/hadoop-yarn-project/hadoop-yarn/bin/yarn +++ b/hadoop-yarn-project/hadoop-yarn/bin/yarn @@ -45,6 +45,7 @@ function hadoop_usage hadoop_add_subcommand "nodemanager" daemon "run a nodemanager on each worker" hadoop_add_subcommand "proxyserver" daemon "run the web app proxy server" hadoop_add_subcommand "queue" client "prints queue information" + hadoop_add_subcommand "registrydns" daemon "run the registry DNS server" hadoop_add_subcommand "resourcemanager" daemon "run the ResourceManager" hadoop_add_subcommand "rmadmin" admin "admin tools" hadoop_add_subcommand "router" daemon "run the Router daemon" @@ -141,6 +142,11 @@ ${HADOOP_COMMON_HOME}/${HADOOP_COMMON_LIB_JARS_DIR}" queue) HADOOP_CLASSNAME=org.apache.hadoop.yarn.client.cli.QueueCLI ;; + registrydns) + HADOOP_SUBCMD_SUPPORTDAEMONIZATION="true" + HADOOP_SECURE_CLASSNAME='org.apache.hadoop.registry.server.dns.PrivilegedRegistryDNSStarter' + HADOOP_CLASSNAME='org.apache.hadoop.registry.server.dns.RegistryDNSServer' + ;; resourcemanager) HADOOP_SUBCMD_SUPPORTDAEMONIZATION="true" HADOOP_CLASSNAME='org.apache.hadoop.yarn.server.resourcemanager.ResourceManager' diff --git a/hadoop-yarn-project/hadoop-yarn/conf/yarn-env.sh b/hadoop-yarn-project/hadoop-yarn/conf/yarn-env.sh index 90a87bf..4bd1d3e 100644 --- a/hadoop-yarn-project/hadoop-yarn/conf/yarn-env.sh +++ b/hadoop-yarn-project/hadoop-yarn/conf/yarn-env.sh @@ -160,3 +160,15 @@ # See ResourceManager for some examples # #export YARN_APISERVER_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:${HADOOP_LOG_DIR}/gc-apiserver.log-$(date +'%Y%m%d%H%M')" + +### +# Registry DNS specific parameters +### +# For privileged registry DNS, user to run as after dropping privileges +# This will replace the hadoop.id.str Java property in secure mode. +# export YARN_REGISTRYDNS_SECURE_USER=yarn + +# Supplemental options for privileged registry DNS +# By default, Hadoop uses jsvc which needs to know to launch a +# server jvm. +# export YARN_REGISTRYDNS_SECURE_EXTRA_OPTS="-jvm server" diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/pom.xml index e083312..4e805cd 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/pom.xml +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/pom.xml @@ -34,6 +34,21 @@ + org.slf4j + slf4j-api + + + + org.apache.hadoop + hadoop-auth + + + + org.apache.hadoop + hadoop-annotations + + + org.apache.hadoop hadoop-yarn-api @@ -70,14 +85,68 @@ + org.apache.zookeeper + zookeeper + + + + org.apache.curator + curator-client + + + org.apache.curator curator-framework org.apache.curator - curator-test - test + curator-recipes + + + + commons-cli + commons-cli + + + + commons-daemon + commons-daemon + + + + commons-io + commons-io + + + + commons-lang + commons-lang + + + + commons-net + commons-net + + + + com.fasterxml.jackson.core + jackson-annotations + + + + com.fasterxml.jackson.core + jackson-core + + + + com.fasterxml.jackson.core + jackson-databind + + + + com.google.guava + guava diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/PrivilegedRegistryDNSStarter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/PrivilegedRegistryDNSStarter.java new file mode 100644 index 0000000..dd4e1b8 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/PrivilegedRegistryDNSStarter.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.registry.server.dns; + +import org.apache.commons.daemon.Daemon; +import org.apache.commons.daemon.DaemonContext; +import org.apache.hadoop.registry.client.api.DNSOperationsFactory; +import org.apache.hadoop.util.GenericOptionsParser; +import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.conf.YarnConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.hadoop.registry.client.api.RegistryConstants.DEFAULT_DNS_PORT; +import static org.apache.hadoop.registry.client.api.RegistryConstants.KEY_DNS_PORT; + +/** + * This class is used to allow the RegistryDNSServer to run on a privileged + * port (e.g. 53). + */ +public class PrivilegedRegistryDNSStarter implements Daemon { + private static final Logger LOG = + LoggerFactory.getLogger(PrivilegedRegistryDNSStarter.class); + + private YarnConfiguration conf; + private RegistryDNS registryDNS; + private RegistryDNSServer registryDNSServer; + + @Override + public void init(DaemonContext context) throws Exception { + String[] args = context.getArguments(); + StringUtils.startupShutdownMessage(RegistryDNSServer.class, args, LOG); + conf = new YarnConfiguration(); + new GenericOptionsParser(conf, args); + + int port = conf.getInt(KEY_DNS_PORT, DEFAULT_DNS_PORT); + if (port < 1 || port > 1023) { + throw new RuntimeException("Must start privileged registry DNS server " + + "with '" + KEY_DNS_PORT + "' configured to a privileged port."); + } + + try { + registryDNS = (RegistryDNS) DNSOperationsFactory.createInstance(conf); + registryDNS.initializeChannels(conf); + } catch (Exception e) { + LOG.error("Error initializing Registry DNS", e); + throw e; + } + } + + @Override + public void start() throws Exception { + registryDNSServer = RegistryDNSServer.launchDNSServer(conf, registryDNS); + } + + @Override + public void stop() throws Exception { + } + + @Override + public void destroy() { + registryDNSServer.stop(); + } + +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java index 51139be..d7a415d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java @@ -82,6 +82,7 @@ import java.util.Collection; import java.util.Date; import java.util.Iterator; +import java.util.Map; import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; @@ -130,6 +131,8 @@ private ConcurrentMap zones = new ConcurrentHashMap<>(); private Name bindHost; + private boolean channelsInitialized = false; + /** * Construct the service. * @@ -150,6 +153,24 @@ public Thread newThread(Runnable r) { }); } + public void initializeChannels(Configuration conf) throws Exception { + if (channelsInitialized) { + return; + } + channelsInitialized = true; + int port = conf.getInt(KEY_DNS_PORT, DEFAULT_DNS_PORT); + InetAddress addr = InetAddress.getLocalHost(); + + String bindAddress = conf.get(KEY_DNS_BIND_ADDRESS); + if (bindAddress != null) { + addr = InetAddress.getByName(bindAddress); + } + + LOG.info("Opening TCP and UDP channels on {} port {}", addr, port); + addNIOUDP(addr, port); + addNIOTCP(addr, port); + } + /** * Initializes the registry. * @@ -164,17 +185,9 @@ protected void serviceInit(Configuration conf) throws Exception { try { setDomainName(conf); - int port = initializeZones(conf); - - InetAddress addr = InetAddress.getLocalHost(); - - String bindAddress = conf.get(KEY_DNS_BIND_ADDRESS); - if (bindAddress != null) { - addr = InetAddress.getByName(bindAddress); - } - addNIOUDP(addr, port); - addNIOTCP(addr, port); + initializeZones(conf); + initializeChannels(conf); } catch (IOException e) { LOG.error("Error initializing Registry DNS Server", e); throw e; @@ -189,8 +202,7 @@ protected void serviceInit(Configuration conf) throws Exception { * @return the listener port * @throws IOException */ - int initializeZones(Configuration conf) throws IOException { - int port = conf.getInt(KEY_DNS_PORT, DEFAULT_DNS_PORT); + void initializeZones(Configuration conf) throws IOException { ttl = conf.getTimeDuration(KEY_DNS_TTL, 1L, TimeUnit.SECONDS); RecordCreatorFactory.setTtl(ttl); @@ -203,7 +215,12 @@ int initializeZones(Configuration conf) throws IOException { initializeReverseLookupZone(conf); - return port; + StringBuilder builder = new StringBuilder(); + builder.append("DNS zones: ").append(System.lineSeparator()); + for (Map.Entry entry : zones.entrySet()) { + builder.append(System.lineSeparator()).append(entry.getValue()); + } + LOG.info(builder.toString()); } /** @@ -1412,7 +1429,7 @@ private void op(String path, ServiceRecord record, RegistryCommand command) } processor.manageDNSRecords(command); } else { - LOG.warn("Yarn Resgistry record {} does not contain {} attribute ", + LOG.warn("Yarn Registry record {} does not contain {} attribute ", record.toString(), YarnRegistryAttributes.YARN_PERSISTENCE); } } catch (Exception e) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNSServer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNSServer.java index faa5fe1..c7f6831 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNSServer.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNSServer.java @@ -17,11 +17,6 @@ package org.apache.hadoop.registry.server.dns; import com.google.common.base.Preconditions; -import org.apache.commons.cli.BasicParser; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.PathNotFoundException; import org.apache.hadoop.registry.client.api.DNSOperationsFactory; @@ -65,9 +60,11 @@ /** * Creates the DNS server. * @param name the server name. + * @param registryDNS the registry DNS instance. */ - public RegistryDNSServer(String name) { + public RegistryDNSServer(String name, final RegistryDNS registryDNS) { super(name); + this.registryDNS = registryDNS; } /** @@ -83,8 +80,9 @@ protected void serviceInit(Configuration conf) throws Exception { registryOperations = new RegistryOperationsService("RegistryDNSOperations"); addService(registryOperations); - // probably need to populate with existing apps? - registryDNS = (RegistryDNS) DNSOperationsFactory.createInstance(conf); + if (registryDNS == null) { + registryDNS = (RegistryDNS) DNSOperationsFactory.createInstance(conf); + } addService(registryDNS); super.serviceInit(conf); @@ -231,24 +229,21 @@ private void processServiceRecord(String path, ServiceRecord record, /** * Launch the server. - * @param args command line args. + * @param conf configuration + * @param rdns registry dns instance * @return */ - static RegistryDNSServer launchDNSServer(String[] args) { + static RegistryDNSServer launchDNSServer(Configuration conf, + RegistryDNS rdns) { RegistryDNSServer dnsServer = null; Thread .setDefaultUncaughtExceptionHandler(new YarnUncaughtExceptionHandler()); - StringUtils.startupShutdownMessage(RegistryDNSServer.class, args, - LOG); try { - dnsServer = new RegistryDNSServer("RegistryDNSServer"); + dnsServer = new RegistryDNSServer("RegistryDNSServer", rdns); ShutdownHookManager.get().addShutdownHook( new CompositeService.CompositeServiceShutdownHook(dnsServer), SHUTDOWN_HOOK_PRIORITY); - YarnConfiguration conf = new YarnConfiguration(); - processCommandLine(args, conf); - new GenericOptionsParser(conf, args); dnsServer.init(conf); dnsServer.start(); } catch (Throwable t) { @@ -259,32 +254,14 @@ static RegistryDNSServer launchDNSServer(String[] args) { } /** - * Process input command line arguments. - * @param args the command line argument array. - * @param conf the configuration. - */ - private static void processCommandLine(String[] args, - YarnConfiguration conf) { - Options options = new Options(); - options.addOption("p", "port", true, - "the server listening port (override)"); - - CommandLineParser parser = new BasicParser(); - try { - CommandLine cmd = parser.parse(options, args); - if (cmd.hasOption("p")) { - conf.set(RegistryConstants.KEY_DNS_PORT, cmd.getOptionValue("p")); - } - } catch (ParseException e) { - LOG.error("Error parsing the command line options", e); - } - } - - /** * Lanches the server instance. * @param args the command line args. + * @throws IOException if command line options can't be parsed */ - public static void main(String[] args) { - launchDNSServer(args); + public static void main(String[] args) throws IOException { + StringUtils.startupShutdownMessage(RegistryDNSServer.class, args, LOG); + YarnConfiguration conf = new YarnConfiguration(); + new GenericOptionsParser(conf, args); + launchDNSServer(conf, null); } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnCommands.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnCommands.md index e464d54..2a6d1e7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnCommands.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/YarnCommands.md @@ -316,9 +316,17 @@ Usage: `yarn timelineserver` Start the TimeLineServer ### apiserver + Usage: `yarn apiserver` + Start the API-server for deploying/managing services on YARN +### registrydns + +Usage: `yarn registrydns` + +Start the RegistryDNS server + Files ----- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/RegistryDNS.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/RegistryDNS.md index ef395fc..b868138 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/RegistryDNS.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/RegistryDNS.md @@ -15,7 +15,7 @@ # Registry DNS Server - +The document describes the internals of Registry DNS server. ## Introduction The Registry DNS Server provides a standard DNS interface to the information posted into the YARN Registry by deployed applications. The DNS service serves the following functions: @@ -153,6 +153,7 @@ The Registry DNS server reads its configuration properties from the yarn-site.xm | Name | Description | | ------------ | ------------- | +|hadoop.registry.zk.quorum| A comma separated list of hostname:port pairs defining the zookeeper quorum for the [YARN registry](../registry/registry-configuration.md). | | hadoop.registry.dns.enabled | The DNS functionality is enabled for the cluster. Default is false. | | hadoop.registry.dns.domain-name | The domain name for Hadoop cluster associated records. | | hadoop.registry.dns.bind-address | Address associated with the network interface to which the DNS listener should bind. | diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/ServiceDiscovery.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/ServiceDiscovery.md index a5dd0d2..96ed6c3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/ServiceDiscovery.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/yarn-service/ServiceDiscovery.md @@ -73,6 +73,7 @@ assigned `0` since it is the first and only instance for the `hbasemaster` compo Below is the set of configurations in `yarn-site.xml` required for enabling Registry DNS. A full list of properties can be found in the Configuration section of [Registry DNS](RegistryDNS.md). + ``` The domain name for Hadoop cluster associated records. @@ -84,7 +85,7 @@ section of [Registry DNS](RegistryDNS.md). The port number for the DNS listener. The default port is 5353. If the standard privileged port 53 is used, make sure start the DNS with jsvc support. hadoop.registry.dns.bind-port - 53 + 5353 @@ -92,7 +93,21 @@ section of [Registry DNS](RegistryDNS.md). hadoop.registry.dns.enabled true - + + + Address associated with the network interface to which the DNS listener should bind. + hadoop.registry.dns.bind-address + localhost + + + + A comma separated list of hostname:port pairs defining the zookeeper quorum for the YARN registry + hadoop.registry.zk.quorum + localhost + +``` +To configure Registry DNS to serve reverse lookup for `172.17.0.0/24` +``` The network mask associated with the zone IP range. If specified, it is utilized to ascertain the IP range possible and come up with an appropriate reverse zone name. @@ -104,11 +119,9 @@ section of [Registry DNS](RegistryDNS.md). An indicator of the IP range associated with the cluster containers. The setting is utilized for the generation of the reverse zone name. hadoop.registry.dns.zone-subnet - 172.17.0 + 172.17.0.0 - ``` - ## Start the DNS Server By default, the DNS server runs on non-privileged port `5353`. Start the server with: