From 6efa931c518e8fdc725527e465bceb0b8fb60a4a Mon Sep 17 00:00:00 2001 From: illustris Date: Sat, 8 Jan 2022 12:48:23 +0530 Subject: nixos/hadoop: fix mkenableoption text --- nixos/modules/services/cluster/hadoop/hdfs.nix | 10 +++++----- nixos/modules/services/cluster/hadoop/yarn.nix | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index be667aa82d8..8c373968364 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -17,7 +17,7 @@ in { options.services.hadoop.hdfs = { namenode = { - enable = mkEnableOption "Whether to run the HDFS NameNode"; + enable = mkEnableOption "HDFS NameNode"; formatOnInit = mkOption { type = types.bool; default = false; @@ -37,7 +37,7 @@ in }; }; datanode = { - enable = mkEnableOption "Whether to run the HDFS DataNode"; + enable = mkEnableOption "HDFS DataNode"; inherit restartIfChanged; openFirewall = mkOption { type = types.bool; @@ -48,7 +48,7 @@ in }; }; journalnode = { - enable = mkEnableOption "Whether to run the HDFS JournalNode"; + enable = mkEnableOption "HDFS JournalNode"; inherit restartIfChanged; openFirewall = mkOption { type = types.bool; @@ -59,11 +59,11 @@ in }; }; zkfc = { - enable = mkEnableOption "Whether to run the HDFS ZooKeeper failover controller"; + enable = mkEnableOption "HDFS ZooKeeper failover controller"; inherit restartIfChanged; }; httpfs = { - enable = mkEnableOption "Whether to run the HDFS HTTPfs server"; + enable = mkEnableOption "HDFS HTTPfs server"; tempPath = mkOption { type = types.path; default = "/tmp/hadoop/httpfs"; diff --git a/nixos/modules/services/cluster/hadoop/yarn.nix b/nixos/modules/services/cluster/hadoop/yarn.nix index 37c26ea10f7..cc42d8f388a 100644 --- a/nixos/modules/services/cluster/hadoop/yarn.nix +++ b/nixos/modules/services/cluster/hadoop/yarn.nix @@ -17,7 +17,7 @@ in { options.services.hadoop.yarn = { resourcemanager = { - enable = mkEnableOption "Whether to run the Hadoop YARN ResourceManager"; + enable = mkEnableOption "Hadoop YARN ResourceManager"; inherit restartIfChanged; openFirewall = mkOption { type = types.bool; @@ -28,7 +28,7 @@ in }; }; nodemanager = { - enable = mkEnableOption "Whether to run the Hadoop YARN NodeManager"; + enable = mkEnableOption "Hadoop YARN NodeManager"; inherit restartIfChanged; addBinBash = mkOption { type = types.bool; -- cgit 1.4.1 From dd5f004b06a16e7c291bd159f792b718b7fce0b3 Mon Sep 17 00:00:00 2001 From: illustris Date: Sat, 8 Jan 2022 14:02:32 +0530 Subject: nixos/hadoop: refactor HDFS options --- nixos/modules/services/cluster/hadoop/hdfs.nix | 69 +++++++------------------- 1 file changed, 19 insertions(+), 50 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 8c373968364..9caa3d07525 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -13,71 +13,40 @@ let ''; default = false; }; + openFirewall = serviceName: mkOption { + type = types.bool; + default = true; + description = "Open firewall ports for ${serviceName}."; + }; + hadoopServiceOption = { serviceName, firewallOption ? true }: { + enable = mkEnableOption serviceName; + inherit restartIfChanged; + } // (if firewallOption then {openFirewall = openFirewall serviceName;} else {}); in { options.services.hadoop.hdfs = { - namenode = { - enable = mkEnableOption "HDFS NameNode"; + namenode = hadoopServiceOption { serviceName = "HDFS NameNode"; } // { formatOnInit = mkOption { type = types.bool; default = false; description = '' Format HDFS namenode on first start. This is useful for quickly spinning up ephemeral HDFS clusters with a single namenode. - For HA clusters, initialization involves multiple steps across multiple nodes. Follow [this guide](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html) - to initialize an HA cluster manually. - ''; - }; - inherit restartIfChanged; - openFirewall = mkOption { - type = types.bool; - default = true; - description = '' - Open firewall ports for namenode - ''; - }; - }; - datanode = { - enable = mkEnableOption "HDFS DataNode"; - inherit restartIfChanged; - openFirewall = mkOption { - type = types.bool; - default = true; - description = '' - Open firewall ports for datanode + For HA clusters, initialization involves multiple steps across multiple nodes. Follow this guide to initialize an HA cluster manually: + ''; }; }; - journalnode = { - enable = mkEnableOption "HDFS JournalNode"; - inherit restartIfChanged; - openFirewall = mkOption { - type = types.bool; - default = true; - description = '' - Open firewall ports for journalnode - ''; - }; - }; - zkfc = { - enable = mkEnableOption "HDFS ZooKeeper failover controller"; - inherit restartIfChanged; + datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; }; + journalnode = hadoopServiceOption { serviceName = "HDFS JournalNode"; }; + zkfc = hadoopServiceOption { + serviceName = "HDFS ZooKeeper failover controller"; + firewallOption = false; }; - httpfs = { - enable = mkEnableOption "HDFS HTTPfs server"; + httpfs = hadoopServiceOption { serviceName = "HDFS JournalNode"; } // { tempPath = mkOption { type = types.path; default = "/tmp/hadoop/httpfs"; - description = '' - HTTPFS_TEMP path used by HTTPFS - ''; - }; - inherit restartIfChanged; - openFirewall = mkOption { - type = types.bool; - default = true; - description = '' - Open firewall ports for HTTPFS - ''; + description = "HTTPFS_TEMP path used by HTTPFS"; }; }; }; -- cgit 1.4.1 From f6cf1ced335869002697efa8f18cb77493a38e56 Mon Sep 17 00:00:00 2001 From: illustris Date: Sat, 8 Jan 2022 16:02:32 +0530 Subject: nixos/hadoop: refactor HDFS configs --- nixos/modules/services/cluster/hadoop/hdfs.nix | 211 ++++++++++++------------- 1 file changed, 100 insertions(+), 111 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 9caa3d07525..71bd4478670 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -1,47 +1,89 @@ -{ config, lib, pkgs, ...}: +{ config, lib, pkgs, ... }: with lib; let cfg = config.services.hadoop; + + # Config files for hadoop services hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; - restartIfChanged = mkOption { - type = types.bool; - description = '' - Automatically restart the service on config change. - This can be set to false to defer restarts on clusters running critical applications. - Please consider the security implications of inadvertently running an older version, - and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option. - ''; - default = false; - }; - openFirewall = serviceName: mkOption { - type = types.bool; - default = true; - description = "Open firewall ports for ${serviceName}."; - }; + + # Generator for HDFS service options hadoopServiceOption = { serviceName, firewallOption ? true }: { enable = mkEnableOption serviceName; - inherit restartIfChanged; - } // (if firewallOption then {openFirewall = openFirewall serviceName;} else {}); + restartIfChanged = mkOption { + type = types.bool; + description = '' + Automatically restart the service on config change. + This can be set to false to defer restarts on clusters running critical applications. + Please consider the security implications of inadvertently running an older version, + and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option. + ''; + default = false; + }; + } // (optionalAttrs firewallOption { + openFirewall = mkOption { + type = types.bool; + default = true; + description = "Open firewall ports for ${serviceName}."; + }; + }); + + # Generator for HDFS service configs + hadoopServiceConfig = + { name + , serviceOptions ? cfg.hdfs."${toLower name}" + , description ? "Hadoop HDFS ${name}" + , User ? "hdfs" + , allowedTCPPorts ? [ ] + , preStart ? "" + , environment ? { } + }: ( + + mkIf serviceOptions.enable { + systemd.services."hdfs-${toLower name}" = { + inherit description preStart environment; + wantedBy = [ "multi-user.target" ]; + inherit (serviceOptions) restartIfChanged; + serviceConfig = { + inherit User; + SyslogIdentifier = "hdfs-${toLower name}"; + ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} ${toLower name}"; + Restart = "always"; + }; + }; + + networking.firewall.allowedTCPPorts = mkIf + ((builtins.hasAttr "openFirewall" serviceOptions) && serviceOptions.openFirewall) + allowedTCPPorts; + } + ); + in { options.services.hadoop.hdfs = { + namenode = hadoopServiceOption { serviceName = "HDFS NameNode"; } // { formatOnInit = mkOption { type = types.bool; default = false; description = '' - Format HDFS namenode on first start. This is useful for quickly spinning up ephemeral HDFS clusters with a single namenode. - For HA clusters, initialization involves multiple steps across multiple nodes. Follow this guide to initialize an HA cluster manually: + Format HDFS namenode on first start. This is useful for quickly spinning up + ephemeral HDFS clusters with a single namenode. + For HA clusters, initialization involves multiple steps across multiple nodes. + Follow this guide to initialize an HA cluster manually: ''; }; }; + datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; }; + journalnode = hadoopServiceOption { serviceName = "HDFS JournalNode"; }; + zkfc = hadoopServiceOption { serviceName = "HDFS ZooKeeper failover controller"; firewallOption = false; }; + httpfs = hadoopServiceOption { serviceName = "HDFS JournalNode"; } // { tempPath = mkOption { type = types.path; @@ -49,118 +91,65 @@ in description = "HTTPFS_TEMP path used by HTTPFS"; }; }; + }; config = mkMerge [ - (mkIf cfg.hdfs.namenode.enable { - systemd.services.hdfs-namenode = { - description = "Hadoop HDFS NameNode"; - wantedBy = [ "multi-user.target" ]; - inherit (cfg.hdfs.namenode) restartIfChanged; - - preStart = (mkIf cfg.hdfs.namenode.formatOnInit '' - ${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true - ''); - - serviceConfig = { - User = "hdfs"; - SyslogIdentifier = "hdfs-namenode"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} namenode"; - Restart = "always"; - }; - }; - - networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.namenode.openFirewall [ + (hadoopServiceConfig { + name = "NameNode"; + allowedTCPPorts = [ 9870 # namenode.http-address 8020 # namenode.rpc-address 8022 # namenode. servicerpc-address - ]); + ]; + preStart = (mkIf cfg.hdfs.namenode.formatOnInit + "${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true" + ); }) - (mkIf cfg.hdfs.datanode.enable { - systemd.services.hdfs-datanode = { - description = "Hadoop HDFS DataNode"; - wantedBy = [ "multi-user.target" ]; - inherit (cfg.hdfs.datanode) restartIfChanged; - - serviceConfig = { - User = "hdfs"; - SyslogIdentifier = "hdfs-datanode"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} datanode"; - Restart = "always"; - }; - }; - networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.datanode.openFirewall [ + (hadoopServiceConfig { + name = "DataNode"; + allowedTCPPorts = [ 9864 # datanode.http.address 9866 # datanode.address 9867 # datanode.ipc.address - ]); + ]; }) - (mkIf cfg.hdfs.journalnode.enable { - systemd.services.hdfs-journalnode = { - description = "Hadoop HDFS JournalNode"; - wantedBy = [ "multi-user.target" ]; - inherit (cfg.hdfs.journalnode) restartIfChanged; - - serviceConfig = { - User = "hdfs"; - SyslogIdentifier = "hdfs-journalnode"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} journalnode"; - Restart = "always"; - }; - }; - networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.journalnode.openFirewall [ + (hadoopServiceConfig { + name = "JournalNode"; + allowedTCPPorts = [ 8480 # dfs.journalnode.http-address 8485 # dfs.journalnode.rpc-address - ]); + ]; }) - (mkIf cfg.hdfs.zkfc.enable { - systemd.services.hdfs-zkfc = { - description = "Hadoop HDFS ZooKeeper failover controller"; - wantedBy = [ "multi-user.target" ]; - inherit (cfg.hdfs.zkfc) restartIfChanged; - - serviceConfig = { - User = "hdfs"; - SyslogIdentifier = "hdfs-zkfc"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} zkfc"; - Restart = "always"; - }; - }; - }) - (mkIf cfg.hdfs.httpfs.enable { - systemd.services.hdfs-httpfs = { - description = "Hadoop httpfs"; - wantedBy = [ "multi-user.target" ]; - inherit (cfg.hdfs.httpfs) restartIfChanged; - - environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath; - preStart = '' - mkdir -p $HTTPFS_TEMP - ''; + (hadoopServiceConfig { + name = "zkfc"; + description = "Hadoop HDFS ZooKeeper failover controller"; + }) - serviceConfig = { - User = "httpfs"; - SyslogIdentifier = "hdfs-httpfs"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} httpfs"; - Restart = "always"; - }; - }; - networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.httpfs.openFirewall [ + (hadoopServiceConfig { + name = "HTTPFS"; + environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath; + preStart = "mkdir -p $HTTPFS_TEMP"; + User = "httpfs"; + allowedTCPPorts = [ 14000 # httpfs.http.port - ]); + ]; }) - (mkIf ( + + (mkIf + ( cfg.hdfs.namenode.enable || cfg.hdfs.datanode.enable || cfg.hdfs.journalnode.enable || cfg.hdfs.zkfc.enable - ) { - users.users.hdfs = { - description = "Hadoop HDFS user"; - group = "hadoop"; - uid = config.ids.uids.hdfs; - }; - }) + ) + { + users.users.hdfs = { + description = "Hadoop HDFS user"; + group = "hadoop"; + uid = config.ids.uids.hdfs; + }; + }) (mkIf cfg.hdfs.httpfs.enable { users.users.httpfs = { description = "Hadoop HTTPFS user"; -- cgit 1.4.1 From 0f97c9ae82bae1d445b14483864d784e1245204e Mon Sep 17 00:00:00 2001 From: illustris Date: Sat, 8 Jan 2022 16:19:15 +0530 Subject: nixos/hadoop: disable openFirewall by default --- nixos/modules/services/cluster/hadoop/hdfs.nix | 2 +- nixos/modules/services/cluster/hadoop/yarn.nix | 4 +-- nixos/tests/hadoop/hadoop.nix | 45 ++++++++++++++++++++------ nixos/tests/hadoop/hdfs.nix | 11 +++++-- nixos/tests/hadoop/yarn.nix | 10 ++++-- 5 files changed, 56 insertions(+), 16 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 71bd4478670..451e74df712 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -22,7 +22,7 @@ let } // (optionalAttrs firewallOption { openFirewall = mkOption { type = types.bool; - default = true; + default = false; description = "Open firewall ports for ${serviceName}."; }; }); diff --git a/nixos/modules/services/cluster/hadoop/yarn.nix b/nixos/modules/services/cluster/hadoop/yarn.nix index cc42d8f388a..90ae75a44b7 100644 --- a/nixos/modules/services/cluster/hadoop/yarn.nix +++ b/nixos/modules/services/cluster/hadoop/yarn.nix @@ -21,7 +21,7 @@ in inherit restartIfChanged; openFirewall = mkOption { type = types.bool; - default = true; + default = false; description = '' Open firewall ports for resourcemanager ''; @@ -39,7 +39,7 @@ in }; openFirewall = mkOption { type = types.bool; - default = true; + default = false; description = '' Open firewall ports for nodemanager. Because containers can listen on any ephemeral port, TCP ports 1024–65535 will be opened. diff --git a/nixos/tests/hadoop/hadoop.nix b/nixos/tests/hadoop/hadoop.nix index 48737debab5..adc3c9f393c 100644 --- a/nixos/tests/hadoop/hadoop.nix +++ b/nixos/tests/hadoop/hadoop.nix @@ -55,14 +55,20 @@ import ../make-test-python.nix ({pkgs, ...}: { nn1 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.namenode.enable = true; + hdfs.namenode = { + enable = true; + openFirewall = true; + }; hdfs.zkfc.enable = true; }; }; nn2 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.namenode.enable = true; + hdfs.namenode = { + enable = true; + openFirewall = true; + }; hdfs.zkfc.enable = true; }; }; @@ -70,26 +76,38 @@ import ../make-test-python.nix ({pkgs, ...}: { jn1 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.journalnode.enable = true; + hdfs.journalnode = { + enable = true; + openFirewall = true; + }; }; }; jn2 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.journalnode.enable = true; + hdfs.journalnode = { + enable = true; + openFirewall = true; + }; }; }; jn3 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.journalnode.enable = true; + hdfs.journalnode = { + enable = true; + openFirewall = true; + }; }; }; dn1 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; - hdfs.datanode.enable = true; + hdfs.datanode = { + enable = true; + openFirewall = true; + }; }; }; @@ -98,14 +116,20 @@ import ../make-test-python.nix ({pkgs, ...}: { services.hadoop = { inherit package coreSite hdfsSite; yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; - yarn.resourcemanager.enable = true; + yarn.resourcemanager = { + enable = true; + openFirewall = true; + }; }; }; rm2 = {pkgs, options, ...}: { services.hadoop = { inherit package coreSite hdfsSite; yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; - yarn.resourcemanager.enable = true; + yarn.resourcemanager = { + enable = true; + openFirewall = true; + }; }; }; nm1 = {pkgs, options, ...}: { @@ -113,7 +137,10 @@ import ../make-test-python.nix ({pkgs, ...}: { services.hadoop = { inherit package coreSite hdfsSite; yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; - yarn.nodemanager.enable = true; + yarn.nodemanager = { + enable = true; + openFirewall = true; + }; }; }; }; diff --git a/nixos/tests/hadoop/hdfs.nix b/nixos/tests/hadoop/hdfs.nix index b63cbf48032..c5aee0d5ee7 100644 --- a/nixos/tests/hadoop/hdfs.nix +++ b/nixos/tests/hadoop/hdfs.nix @@ -7,9 +7,13 @@ import ../make-test-python.nix ({...}: { hdfs = { namenode = { enable = true; + openFirewall = true; formatOnInit = true; }; - httpfs.enable = true; + httpfs = { + enable = true; + openFirewall = true; + }; }; coreSite = { "fs.defaultFS" = "hdfs://namenode:8020"; @@ -21,7 +25,10 @@ import ../make-test-python.nix ({...}: { datanode = {pkgs, ...}: { services.hadoop = { package = pkgs.hadoop; - hdfs.datanode.enable = true; + hdfs.datanode = { + enable = true; + openFirewall = true; + }; coreSite = { "fs.defaultFS" = "hdfs://namenode:8020"; "hadoop.proxyuser.httpfs.groups" = "*"; diff --git a/nixos/tests/hadoop/yarn.nix b/nixos/tests/hadoop/yarn.nix index 09bdb35791c..fbf05b19cd2 100644 --- a/nixos/tests/hadoop/yarn.nix +++ b/nixos/tests/hadoop/yarn.nix @@ -3,14 +3,20 @@ import ../make-test-python.nix ({...}: { nodes = { resourcemanager = {pkgs, ...}: { services.hadoop.package = pkgs.hadoop; - services.hadoop.yarn.resourcemanager.enable = true; + services.hadoop.yarn.resourcemanager = { + enable = true; + openFirewall = true; + }; services.hadoop.yarnSite = { "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler"; }; }; nodemanager = {pkgs, ...}: { services.hadoop.package = pkgs.hadoop; - services.hadoop.yarn.nodemanager.enable = true; + services.hadoop.yarn.nodemanager = { + enable = true; + openFirewall = true; + }; services.hadoop.yarnSite = { "yarn.resourcemanager.hostname" = "resourcemanager"; "yarn.nodemanager.log-dirs" = "/tmp/userlogs"; -- cgit 1.4.1 From c82d48913f581a5c878e9f31075c23563f92b9a3 Mon Sep 17 00:00:00 2001 From: illustris Date: Sat, 8 Jan 2022 16:47:26 +0530 Subject: nixos/hadoop: add HADOOP_CONF_DIR to env --- nixos/modules/services/cluster/hadoop/default.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index a1a95fe31ca..0adedaf1906 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -169,6 +169,7 @@ with lib; etc."hadoop-conf".source = let hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; in "${hadoopConf}"; + variables.HADOOP_CONF_DIR = "/etc/hadoop-conf/"; }; }) -- cgit 1.4.1 From 8aeb60f034d7581245bdcb3f26e5bc3078dfe0ea Mon Sep 17 00:00:00 2001 From: illustris Date: Sun, 27 Feb 2022 10:37:35 +0530 Subject: nixos/hadoop: use FairScheduler by default --- nixos/modules/services/cluster/hadoop/default.nix | 2 +- nixos/tests/hadoop/yarn.nix | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index 0adedaf1906..9968706d5a9 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -77,7 +77,7 @@ with lib; "yarn.nodemanager.linux-container-executor.path" = "/run/wrappers/yarn-nodemanager/bin/container-executor"; "yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager"; "yarn.resourcemanager.bind-host" = "0.0.0.0"; - "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler"; + "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler"; }; type = types.attrsOf types.anything; example = literalExpression '' diff --git a/nixos/tests/hadoop/yarn.nix b/nixos/tests/hadoop/yarn.nix index c121f6556d5..ba39e257dc8 100644 --- a/nixos/tests/hadoop/yarn.nix +++ b/nixos/tests/hadoop/yarn.nix @@ -10,9 +10,6 @@ import ../make-test-python.nix ({ package, ... }: { enable = true; openFirewall = true; }; - yarnSite = { - "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler"; - }; }; }; nodemanager = { ... }: { -- cgit 1.4.1 From d39056d165c9dc480284f3bd1e63b6213f0e518d Mon Sep 17 00:00:00 2001 From: illustris Date: Sun, 27 Feb 2022 10:41:05 +0530 Subject: nixos/hadoop: fix tests for hadoop 2 and 3.2 --- nixos/modules/services/cluster/hadoop/default.nix | 1 + nixos/modules/services/cluster/hadoop/hdfs.nix | 10 ++++-- nixos/tests/hadoop/hdfs.nix | 40 +++++++++++++++-------- 3 files changed, 35 insertions(+), 16 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index 9968706d5a9..636bb406727 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -25,6 +25,7 @@ with lib; hdfsSite = mkOption { default = { "dfs.namenode.rpc-bind-host" = "0.0.0.0"; + "dfs.namenode.http-address" = "0.0.0.0:9870"; }; type = types.attrsOf types.anything; example = literalExpression '' diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 451e74df712..61d9941298a 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -100,7 +100,8 @@ in allowedTCPPorts = [ 9870 # namenode.http-address 8020 # namenode.rpc-address - 8022 # namenode. servicerpc-address + 8022 # namenode.servicerpc-address + 8019 # dfs.ha.zkfc.port ]; preStart = (mkIf cfg.hdfs.namenode.formatOnInit "${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true" @@ -109,10 +110,15 @@ in (hadoopServiceConfig { name = "DataNode"; - allowedTCPPorts = [ + # port numbers for datanode changed between hadoop 2 and 3 + allowedTCPPorts = if versionAtLeast cfg.package.version "3" then [ 9864 # datanode.http.address 9866 # datanode.address 9867 # datanode.ipc.address + ] else [ + 50075 # datanode.http.address + 50010 # datanode.address + 50020 # datanode.ipc.address ]; }) diff --git a/nixos/tests/hadoop/hdfs.nix b/nixos/tests/hadoop/hdfs.nix index e60d1410917..cc70fb8ecaf 100644 --- a/nixos/tests/hadoop/hdfs.nix +++ b/nixos/tests/hadoop/hdfs.nix @@ -1,8 +1,16 @@ # Test a minimal HDFS cluster with no HA -import ../make-test-python.nix ({ package, ... }: { +import ../make-test-python.nix ({ package, lib, ... }: +with lib; +{ name = "hadoop-hdfs"; - nodes = { + nodes = let + coreSite = { + "fs.defaultFS" = "hdfs://namenode:8020"; + "hadoop.proxyuser.httpfs.groups" = "*"; + "hadoop.proxyuser.httpfs.hosts" = "*"; + }; + in { namenode = { pkgs, ... }: { services.hadoop = { inherit package; @@ -13,15 +21,12 @@ import ../make-test-python.nix ({ package, ... }: { formatOnInit = true; }; httpfs = { - enable = true; + # The NixOS hadoop module only support webHDFS on 3.3 and newer + enable = mkIf (versionAtLeast package.version "3.3") true; openFirewall = true; }; }; - coreSite = { - "fs.defaultFS" = "hdfs://namenode:8020"; - "hadoop.proxyuser.httpfs.groups" = "*"; - "hadoop.proxyuser.httpfs.hosts" = "*"; - }; + inherit coreSite; }; }; datanode = { pkgs, ... }: { @@ -31,11 +36,7 @@ import ../make-test-python.nix ({ package, ... }: { enable = true; openFirewall = true; }; - coreSite = { - "fs.defaultFS" = "hdfs://namenode:8020"; - "hadoop.proxyuser.httpfs.groups" = "*"; - "hadoop.proxyuser.httpfs.hosts" = "*"; - }; + inherit coreSite; }; }; }; @@ -46,21 +47,32 @@ import ../make-test-python.nix ({ package, ... }: { namenode.wait_for_unit("hdfs-namenode") namenode.wait_for_unit("network.target") namenode.wait_for_open_port(8020) + namenode.succeed("ss -tulpne | systemd-cat") + namenode.succeed("cat /etc/hadoop*/hdfs-site.xml | systemd-cat") namenode.wait_for_open_port(9870) datanode.wait_for_unit("hdfs-datanode") datanode.wait_for_unit("network.target") + '' + ( if versionAtLeast package.version "3" then '' datanode.wait_for_open_port(9864) datanode.wait_for_open_port(9866) datanode.wait_for_open_port(9867) - namenode.succeed("curl -f http://namenode:9870") datanode.succeed("curl -f http://datanode:9864") + '' else '' + datanode.wait_for_open_port(50075) + datanode.wait_for_open_port(50010) + datanode.wait_for_open_port(50020) + + datanode.succeed("curl -f http://datanode:50075") + '' ) + '' + namenode.succeed("curl -f http://namenode:9870") datanode.succeed("sudo -u hdfs hdfs dfsadmin -safemode wait") datanode.succeed("echo testfilecontents | sudo -u hdfs hdfs dfs -put - /testfile") assert "testfilecontents" in datanode.succeed("sudo -u hdfs hdfs dfs -cat /testfile") + '' + optionalString ( versionAtLeast package.version "3.3" ) '' namenode.wait_for_unit("hdfs-httpfs") namenode.wait_for_open_port(14000) assert "testfilecontents" in datanode.succeed("curl -f \"http://namenode:14000/webhdfs/v1/testfile?user.name=hdfs&op=OPEN\" 2>&1") -- cgit 1.4.1 From 716b0dfaaf12afe83ff54b793dc52c022ab62155 Mon Sep 17 00:00:00 2001 From: illustris Date: Sun, 27 Feb 2022 11:52:18 +0530 Subject: nixos/hadoop: add gateway role --- nixos/modules/services/cluster/hadoop/default.nix | 31 +++++++-------- nixos/modules/services/cluster/hadoop/hdfs.nix | 21 +++++----- nixos/modules/services/cluster/hadoop/yarn.nix | 10 +++-- nixos/tests/hadoop/hadoop.nix | 47 +++++++++++++---------- 4 files changed, 57 insertions(+), 52 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index 636bb406727..5c7ea79c301 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -149,6 +149,8 @@ with lib; description = "Directories containing additional config files to be added to HADOOP_CONF_DIR"; }; + gatewayRole.enable = mkEnableOption "gateway role for deploying hadoop configs"; + package = mkOption { type = types.package; default = pkgs.hadoop; @@ -158,21 +160,16 @@ with lib; }; - config = mkMerge [ - (mkIf (builtins.hasAttr "yarn" config.users.users || - builtins.hasAttr "hdfs" config.users.users || - builtins.hasAttr "httpfs" config.users.users) { - users.groups.hadoop = { - gid = config.ids.gids.hadoop; - }; - environment = { - systemPackages = [ cfg.package ]; - etc."hadoop-conf".source = let - hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; - in "${hadoopConf}"; - variables.HADOOP_CONF_DIR = "/etc/hadoop-conf/"; - }; - }) - - ]; + config = mkIf cfg.gatewayRole.enable { + users.groups.hadoop = { + gid = config.ids.gids.hadoop; + }; + environment = { + systemPackages = [ cfg.package ]; + etc."hadoop-conf".source = let + hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; + in "${hadoopConf}"; + variables.HADOOP_CONF_DIR = "/etc/hadoop-conf/"; + }; + }; } diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 61d9941298a..1725dc62d0c 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -51,6 +51,8 @@ let }; }; + services.hadoop.gatewayRole.enable = true; + networking.firewall.allowedTCPPorts = mkIf ((builtins.hasAttr "openFirewall" serviceOptions) && serviceOptions.openFirewall) allowedTCPPorts; @@ -145,17 +147,13 @@ in ]; }) - (mkIf - ( - cfg.hdfs.namenode.enable || cfg.hdfs.datanode.enable || cfg.hdfs.journalnode.enable || cfg.hdfs.zkfc.enable - ) - { - users.users.hdfs = { - description = "Hadoop HDFS user"; - group = "hadoop"; - uid = config.ids.uids.hdfs; - }; - }) + (mkIf cfg.gatewayRole.enable { + users.users.hdfs = { + description = "Hadoop HDFS user"; + group = "hadoop"; + uid = config.ids.uids.hdfs; + }; + }) (mkIf cfg.hdfs.httpfs.enable { users.users.httpfs = { description = "Hadoop HTTPFS user"; @@ -163,5 +161,6 @@ in isSystemUser = true; }; }) + ]; } diff --git a/nixos/modules/services/cluster/hadoop/yarn.nix b/nixos/modules/services/cluster/hadoop/yarn.nix index 90ae75a44b7..9f0d3f85db7 100644 --- a/nixos/modules/services/cluster/hadoop/yarn.nix +++ b/nixos/modules/services/cluster/hadoop/yarn.nix @@ -49,10 +49,7 @@ in }; config = mkMerge [ - (mkIf ( - cfg.yarn.resourcemanager.enable || cfg.yarn.nodemanager.enable - ) { - + (mkIf cfg.gatewayRole.enable { users.users.yarn = { description = "Hadoop YARN user"; group = "hadoop"; @@ -74,6 +71,9 @@ in Restart = "always"; }; }; + + services.hadoop.gatewayRole.enable = true; + networking.firewall.allowedTCPPorts = (mkIf cfg.yarn.resourcemanager.openFirewall [ 8088 # resourcemanager.webapp.address 8030 # resourcemanager.scheduler.address @@ -119,6 +119,8 @@ in }; }; + services.hadoop.gatewayRole.enable = true; + networking.firewall.allowedTCPPortRanges = [ (mkIf (cfg.yarn.nodemanager.openFirewall) {from = 1024; to = 65535;}) ]; diff --git a/nixos/tests/hadoop/hadoop.nix b/nixos/tests/hadoop/hadoop.nix index e84a56f302f..42c238ef853 100644 --- a/nixos/tests/hadoop/hadoop.nix +++ b/nixos/tests/hadoop/hadoop.nix @@ -145,7 +145,14 @@ import ../make-test-python.nix ({ package, ... }: { }; }; }; - }; + client = { options, ... }: { + services.hadoop = { + gatewayRole.enable = true; + inherit package coreSite hdfsSite; + yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; + }; + }; + }; testScript = '' start_all() @@ -202,26 +209,26 @@ import ../make-test-python.nix ({ package, ... }: { # DN should have started by now, but confirm anyway dn1.wait_for_unit("hdfs-datanode") # Print states of namenodes - dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") + client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") # Wait for cluster to exit safemode - dn1.succeed("sudo -u hdfs hdfs dfsadmin -safemode wait") - dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") + client.succeed("sudo -u hdfs hdfs dfsadmin -safemode wait") + client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") # test R/W - dn1.succeed("echo testfilecontents | sudo -u hdfs hdfs dfs -put - /testfile") - assert "testfilecontents" in dn1.succeed("sudo -u hdfs hdfs dfs -cat /testfile") + client.succeed("echo testfilecontents | sudo -u hdfs hdfs dfs -put - /testfile") + assert "testfilecontents" in client.succeed("sudo -u hdfs hdfs dfs -cat /testfile") # Test NN failover nn1.succeed("systemctl stop hdfs-namenode") - assert "active" in dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState") - dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") - assert "testfilecontents" in dn1.succeed("sudo -u hdfs hdfs dfs -cat /testfile") + assert "active" in client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState") + client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") + assert "testfilecontents" in client.succeed("sudo -u hdfs hdfs dfs -cat /testfile") nn1.succeed("systemctl start hdfs-namenode") nn1.wait_for_open_port(9870) nn1.wait_for_open_port(8022) nn1.wait_for_open_port(8020) - assert "standby" in dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState") - dn1.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") + assert "standby" in client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState") + client.succeed("sudo -u hdfs hdfs haadmin -getAllServiceState | systemd-cat") #### YARN tests #### @@ -237,21 +244,21 @@ import ../make-test-python.nix ({ package, ... }: { nm1.wait_for_unit("yarn-nodemanager") nm1.wait_for_open_port(8042) nm1.wait_for_open_port(8040) - nm1.wait_until_succeeds("yarn node -list | grep Nodes:1") - nm1.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") - nm1.succeed("sudo -u yarn yarn node -list | systemd-cat") + client.wait_until_succeeds("yarn node -list | grep Nodes:1") + client.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") + client.succeed("sudo -u yarn yarn node -list | systemd-cat") # Test RM failover rm1.succeed("systemctl stop yarn-resourcemanager") - assert "standby" not in nm1.succeed("sudo -u yarn yarn rmadmin -getAllServiceState") - nm1.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") + assert "standby" not in client.succeed("sudo -u yarn yarn rmadmin -getAllServiceState") + client.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") rm1.succeed("systemctl start yarn-resourcemanager") rm1.wait_for_unit("yarn-resourcemanager") rm1.wait_for_open_port(8088) - assert "standby" in nm1.succeed("sudo -u yarn yarn rmadmin -getAllServiceState") - nm1.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") + assert "standby" in client.succeed("sudo -u yarn yarn rmadmin -getAllServiceState") + client.succeed("sudo -u yarn yarn rmadmin -getAllServiceState | systemd-cat") - assert "Estimated value of Pi is" in nm1.succeed("HADOOP_USER_NAME=hdfs yarn jar $(readlink $(which yarn) | sed -r 's~bin/yarn~lib/hadoop-*/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar~g') pi 2 10") - assert "SUCCEEDED" in nm1.succeed("yarn application -list -appStates FINISHED") + assert "Estimated value of Pi is" in client.succeed("HADOOP_USER_NAME=hdfs yarn jar $(readlink $(which yarn) | sed -r 's~bin/yarn~lib/hadoop-*/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar~g') pi 2 10") + assert "SUCCEEDED" in client.succeed("yarn application -list -appStates FINISHED") ''; }) -- cgit 1.4.1 From bef71d7c530aeecdcfb66290e6c0b4948d1fb223 Mon Sep 17 00:00:00 2001 From: illustris Date: Mon, 28 Feb 2022 20:41:43 +0530 Subject: nixos/hadoop: use CGroups to enforce container limits by default --- nixos/modules/services/cluster/hadoop/default.nix | 5 +++++ nixos/modules/services/cluster/hadoop/yarn.nix | 3 ++- nixos/tests/hadoop/yarn.nix | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index 5c7ea79c301..57b1d7a90d7 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -79,6 +79,10 @@ with lib; "yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager"; "yarn.resourcemanager.bind-host" = "0.0.0.0"; "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler"; + "yarn.nodemanager.linux-container-executor.cgroups.hierarchy" = "/hadoop-yarn"; + "yarn.nodemanager.linux-container-executor.resources-handler.class" = "org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler"; + "yarn.nodemanager.linux-container-executor.cgroups.mount" = "true"; + "yarn.nodemanager.linux-container-executor.cgroups.mount-path" = "/run/wrappers/yarn-nodemanager/cgroup"; }; type = types.attrsOf types.anything; example = literalExpression '' @@ -124,6 +128,7 @@ with lib; "yarn.nodemanager.linux-container-executor.group"="hadoop"; "min.user.id"=1000; "feature.terminal.enabled"=1; + "feature.mount-cgroup.enabled" = 1; }; type = types.attrsOf types.anything; example = literalExpression '' diff --git a/nixos/modules/services/cluster/hadoop/yarn.nix b/nixos/modules/services/cluster/hadoop/yarn.nix index 9f0d3f85db7..373d8a70a12 100644 --- a/nixos/modules/services/cluster/hadoop/yarn.nix +++ b/nixos/modules/services/cluster/hadoop/yarn.nix @@ -101,8 +101,9 @@ in chown yarn:hadoop /var/log/hadoop/yarn/nodemanager # set up setuid container executor binary + umount /run/wrappers/yarn-nodemanager/cgroup/cpu || true rm -rf /run/wrappers/yarn-nodemanager/ || true - mkdir -p /run/wrappers/yarn-nodemanager/{bin,etc/hadoop} + mkdir -p /run/wrappers/yarn-nodemanager/{bin,etc/hadoop,cgroup/cpu} cp ${cfg.package}/lib/${cfg.package.untarDir}/bin/container-executor /run/wrappers/yarn-nodemanager/bin/ chgrp hadoop /run/wrappers/yarn-nodemanager/bin/container-executor chmod 6050 /run/wrappers/yarn-nodemanager/bin/container-executor diff --git a/nixos/tests/hadoop/yarn.nix b/nixos/tests/hadoop/yarn.nix index ba39e257dc8..1bf8e3831f6 100644 --- a/nixos/tests/hadoop/yarn.nix +++ b/nixos/tests/hadoop/yarn.nix @@ -12,14 +12,14 @@ import ../make-test-python.nix ({ package, ... }: { }; }; }; - nodemanager = { ... }: { + nodemanager = { options, lib, ... }: { services.hadoop = { inherit package; yarn.nodemanager = { enable = true; openFirewall = true; }; - yarnSite = { + yarnSite = options.services.hadoop.yarnSite.default // { "yarn.resourcemanager.hostname" = "resourcemanager"; "yarn.nodemanager.log-dirs" = "/tmp/userlogs"; }; -- cgit 1.4.1 From e1017adb328da98e7942ec08354dd686653370a4 Mon Sep 17 00:00:00 2001 From: illustris Date: Wed, 2 Mar 2022 12:50:01 +0530 Subject: nixos/hadoop: add module options for commonly used service configs --- nixos/modules/services/cluster/hadoop/conf.nix | 22 +++---- nixos/modules/services/cluster/hadoop/default.nix | 67 ++++++++++++++++---- nixos/modules/services/cluster/hadoop/hdfs.nix | 52 ++++++++++++--- nixos/modules/services/cluster/hadoop/yarn.nix | 77 +++++++++++++++++++++-- nixos/tests/hadoop/hadoop.nix | 21 ++----- nixos/tests/hadoop/hdfs.nix | 4 ++ 6 files changed, 194 insertions(+), 49 deletions(-) (limited to 'nixos/modules/services/cluster/hadoop') diff --git a/nixos/modules/services/cluster/hadoop/conf.nix b/nixos/modules/services/cluster/hadoop/conf.nix index 0caec5cfc20..e3c26a0d550 100644 --- a/nixos/modules/services/cluster/hadoop/conf.nix +++ b/nixos/modules/services/cluster/hadoop/conf.nix @@ -1,6 +1,6 @@ { cfg, pkgs, lib }: let - propertyXml = name: value: '' + propertyXml = name: value: lib.optionalString (value != null) '' ${name} ${builtins.toString value} @@ -29,16 +29,16 @@ let export HADOOP_LOG_DIR=/tmp/hadoop/$USER ''; in -pkgs.runCommand "hadoop-conf" {} '' +pkgs.runCommand "hadoop-conf" {} (with cfg; '' mkdir -p $out/ - cp ${siteXml "core-site.xml" cfg.coreSite}/* $out/ - cp ${siteXml "hdfs-site.xml" cfg.hdfsSite}/* $out/ - cp ${siteXml "mapred-site.xml" cfg.mapredSite}/* $out/ - cp ${siteXml "yarn-site.xml" cfg.yarnSite}/* $out/ - cp ${siteXml "httpfs-site.xml" cfg.httpfsSite}/* $out/ - cp ${cfgFile "container-executor.cfg" cfg.containerExecutorCfg}/* $out/ + cp ${siteXml "core-site.xml" (coreSite // coreSiteInternal)}/* $out/ + cp ${siteXml "hdfs-site.xml" (hdfsSiteDefault // hdfsSite // hdfsSiteInternal)}/* $out/ + cp ${siteXml "mapred-site.xml" (mapredSiteDefault // mapredSite)}/* $out/ + cp ${siteXml "yarn-site.xml" (yarnSiteDefault // yarnSite // yarnSiteInternal)}/* $out/ + cp ${siteXml "httpfs-site.xml" httpfsSite}/* $out/ + cp ${cfgFile "container-executor.cfg" containerExecutorCfg}/* $out/ cp ${pkgs.writeTextDir "hadoop-user-functions.sh" userFunctions}/* $out/ cp ${pkgs.writeTextDir "hadoop-env.sh" hadoopEnv}/* $out/ - cp ${cfg.log4jProperties} $out/log4j.properties - ${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") cfg.extraConfDirs} -'' + cp ${log4jProperties} $out/log4j.properties + ${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") extraConfDirs} +'') diff --git a/nixos/modules/services/cluster/hadoop/default.nix b/nixos/modules/services/cluster/hadoop/default.nix index 57b1d7a90d7..a4fdea81037 100644 --- a/nixos/modules/services/cluster/hadoop/default.nix +++ b/nixos/modules/services/cluster/hadoop/default.nix @@ -21,25 +21,50 @@ with lib; ''; }; + coreSiteInternal = mkOption { + default = {}; + type = types.attrsOf types.anything; + internal = true; + description = '' + Internal option to add configs to core-site.xml based on module options + ''; + }; - hdfsSite = mkOption { + hdfsSiteDefault = mkOption { default = { "dfs.namenode.rpc-bind-host" = "0.0.0.0"; "dfs.namenode.http-address" = "0.0.0.0:9870"; + "dfs.namenode.servicerpc-bind-host" = "0.0.0.0"; + "dfs.namenode.http-bind-host" = "0.0.0.0"; }; type = types.attrsOf types.anything; + description = '' + Default options for hdfs-site.xml + ''; + }; + hdfsSite = mkOption { + default = {}; + type = types.attrsOf types.anything; example = literalExpression '' { "dfs.nameservices" = "namenode1"; } ''; description = '' - Hadoop hdfs-site.xml definition + Additional options and overrides for hdfs-site.xml ''; }; + hdfsSiteInternal = mkOption { + default = {}; + type = types.attrsOf types.anything; + internal = true; + description = '' + Internal option to add configs to hdfs-site.xml based on module options + ''; + }; - mapredSite = mkOption { + mapredSiteDefault = mkOption { default = { "mapreduce.framework.name" = "yarn"; "yarn.app.mapreduce.am.env" = "HADOOP_MAPRED_HOME=${cfg.package}/lib/${cfg.package.untarDir}"; @@ -55,18 +80,25 @@ with lib; } ''; type = types.attrsOf types.anything; + description = '' + Default options for mapred-site.xml + ''; + }; + mapredSite = mkOption { + default = {}; + type = types.attrsOf types.anything; example = literalExpression '' - options.services.hadoop.mapredSite.default // { + { "mapreduce.map.java.opts" = "-Xmx900m -XX:+UseParallelGC"; } ''; description = '' - Hadoop mapred-site.xml definition + Additional options and overrides for mapred-site.xml ''; }; - yarnSite = mkOption { + yarnSiteDefault = mkOption { default = { "yarn.nodemanager.admin-env" = "PATH=$PATH"; "yarn.nodemanager.aux-services" = "mapreduce_shuffle"; @@ -79,22 +111,33 @@ with lib; "yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager"; "yarn.resourcemanager.bind-host" = "0.0.0.0"; "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler"; - "yarn.nodemanager.linux-container-executor.cgroups.hierarchy" = "/hadoop-yarn"; - "yarn.nodemanager.linux-container-executor.resources-handler.class" = "org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler"; - "yarn.nodemanager.linux-container-executor.cgroups.mount" = "true"; - "yarn.nodemanager.linux-container-executor.cgroups.mount-path" = "/run/wrappers/yarn-nodemanager/cgroup"; }; type = types.attrsOf types.anything; + description = '' + Default options for yarn-site.xml + ''; + }; + yarnSite = mkOption { + default = {}; + type = types.attrsOf types.anything; example = literalExpression '' - options.services.hadoop.yarnSite.default // { + { "yarn.resourcemanager.hostname" = "''${config.networking.hostName}"; } ''; description = '' - Hadoop yarn-site.xml definition + Additional options and overrides for yarn-site.xml ''; }; + yarnSiteInternal = mkOption { + default = {}; + type = types.attrsOf types.anything; + internal = true; + description = '' + Internal option to add configs to yarn-site.xml based on module options + ''; + }; httpfsSite = mkOption { default = { }; diff --git a/nixos/modules/services/cluster/hadoop/hdfs.nix b/nixos/modules/services/cluster/hadoop/hdfs.nix index 1725dc62d0c..325a002ad32 100644 --- a/nixos/modules/services/cluster/hadoop/hdfs.nix +++ b/nixos/modules/services/cluster/hadoop/hdfs.nix @@ -7,7 +7,7 @@ let hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; # Generator for HDFS service options - hadoopServiceOption = { serviceName, firewallOption ? true }: { + hadoopServiceOption = { serviceName, firewallOption ? true, extraOpts ? null }: { enable = mkEnableOption serviceName; restartIfChanged = mkOption { type = types.bool; @@ -19,13 +19,27 @@ let ''; default = false; }; + extraFlags = mkOption{ + type = with types; listOf str; + default = []; + description = "Extra command line flags to pass to ${serviceName}"; + example = [ + "-Dcom.sun.management.jmxremote" + "-Dcom.sun.management.jmxremote.port=8010" + ]; + }; + extraEnv = mkOption{ + type = with types; attrsOf str; + default = {}; + description = "Extra environment variables for ${serviceName}"; + }; } // (optionalAttrs firewallOption { openFirewall = mkOption { type = types.bool; default = false; description = "Open firewall ports for ${serviceName}."; }; - }); + }) // (optionalAttrs (extraOpts != null) extraOpts); # Generator for HDFS service configs hadoopServiceConfig = @@ -36,17 +50,19 @@ let , allowedTCPPorts ? [ ] , preStart ? "" , environment ? { } + , extraConfig ? { } }: ( - mkIf serviceOptions.enable { + mkIf serviceOptions.enable ( mkMerge [{ systemd.services."hdfs-${toLower name}" = { - inherit description preStart environment; + inherit description preStart; + environment = environment // serviceOptions.extraEnv; wantedBy = [ "multi-user.target" ]; inherit (serviceOptions) restartIfChanged; serviceConfig = { inherit User; SyslogIdentifier = "hdfs-${toLower name}"; - ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} ${toLower name}"; + ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} ${toLower name} ${escapeShellArgs serviceOptions.extraFlags}"; Restart = "always"; }; }; @@ -56,7 +72,7 @@ let networking.firewall.allowedTCPPorts = mkIf ((builtins.hasAttr "openFirewall" serviceOptions) && serviceOptions.openFirewall) allowedTCPPorts; - } + } extraConfig]) ); in @@ -77,7 +93,27 @@ in }; }; - datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; }; + datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; } // { + dataDirs = mkOption { + default = null; + description = "Tier and path definitions for datanode storage."; + type = with types; nullOr (listOf (submodule { + options = { + type = mkOption { + type = enum [ "SSD" "DISK" "ARCHIVE" "RAM_DISK" ]; + description = '' + Storage types ([SSD]/[DISK]/[ARCHIVE]/[RAM_DISK]) for HDFS storage policies. + ''; + }; + path = mkOption { + type = path; + example = [ "/var/lib/hadoop/hdfs/dn" ]; + description = "Determines where on the local filesystem a data node should store its blocks."; + }; + }; + })); + }; + }; journalnode = hadoopServiceOption { serviceName = "HDFS JournalNode"; }; @@ -122,6 +158,8 @@ in 50010 # datanode.address 50020 # datanode.ipc.address ]; + extraConfig.services.hadoop.hdfsSiteInternal."dfs.datanode.data.dir" = let d = cfg.hdfs.datanode.dataDirs; in + if (d!= null) then (concatMapStringsSep "," (x: "["+x.type+"]file://"+x.path) cfg.hdfs.datanode.dataDirs) else d; }) (hadoopServiceConfig { diff --git a/nixos/modules/services/cluster/hadoop/yarn.nix b/nixos/modules/services/cluster/hadoop/yarn.nix index 373d8a70a12..74e16bdec68 100644 --- a/nixos/modules/services/cluster/hadoop/yarn.nix +++ b/nixos/modules/services/cluster/hadoop/yarn.nix @@ -13,12 +13,27 @@ let ''; default = false; }; + extraFlags = mkOption{ + type = with types; listOf str; + default = []; + description = "Extra command line flags to pass to the service"; + example = [ + "-Dcom.sun.management.jmxremote" + "-Dcom.sun.management.jmxremote.port=8010" + ]; + }; + extraEnv = mkOption{ + type = with types; attrsOf str; + default = {}; + description = "Extra environment variables"; + }; in { options.services.hadoop.yarn = { resourcemanager = { enable = mkEnableOption "Hadoop YARN ResourceManager"; - inherit restartIfChanged; + inherit restartIfChanged extraFlags extraEnv; + openFirewall = mkOption { type = types.bool; default = false; @@ -29,7 +44,46 @@ in }; nodemanager = { enable = mkEnableOption "Hadoop YARN NodeManager"; - inherit restartIfChanged; + inherit restartIfChanged extraFlags extraEnv; + + resource = { + cpuVCores = mkOption { + description = "Number of vcores that can be allocated for containers."; + type = with types; nullOr ints.positive; + default = null; + }; + maximumAllocationVCores = mkOption { + description = "The maximum virtual CPU cores any container can be allocated."; + type = with types; nullOr ints.positive; + default = null; + }; + memoryMB = mkOption { + description = "Amount of physical memory, in MB, that can be allocated for containers."; + type = with types; nullOr ints.positive; + default = null; + }; + maximumAllocationMB = mkOption { + description = "The maximum physical memory any container can be allocated."; + type = with types; nullOr ints.positive; + default = null; + }; + }; + + useCGroups = mkOption { + type = types.bool; + default = true; + description = '' + Use cgroups to enforce resource limits on containers + ''; + }; + + localDir = mkOption { + description = "List of directories to store localized files in."; + type = with types; nullOr (listOf path); + example = [ "/var/lib/hadoop/yarn/nm" ]; + default = null; + }; + addBinBash = mkOption { type = types.bool; default = true; @@ -62,12 +116,13 @@ in description = "Hadoop YARN ResourceManager"; wantedBy = [ "multi-user.target" ]; inherit (cfg.yarn.resourcemanager) restartIfChanged; + environment = cfg.yarn.resourcemanager.extraEnv; serviceConfig = { User = "yarn"; SyslogIdentifier = "yarn-resourcemanager"; ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " + - " resourcemanager"; + " resourcemanager ${escapeShellArgs cfg.yarn.resourcemanager.extraFlags}"; Restart = "always"; }; }; @@ -94,6 +149,7 @@ in description = "Hadoop YARN NodeManager"; wantedBy = [ "multi-user.target" ]; inherit (cfg.yarn.nodemanager) restartIfChanged; + environment = cfg.yarn.nodemanager.extraEnv; preStart = '' # create log dir @@ -115,13 +171,26 @@ in SyslogIdentifier = "yarn-nodemanager"; PermissionsStartOnly = true; ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " + - " nodemanager"; + " nodemanager ${escapeShellArgs cfg.yarn.nodemanager.extraFlags}"; Restart = "always"; }; }; services.hadoop.gatewayRole.enable = true; + services.hadoop.yarnSiteInternal = with cfg.yarn.nodemanager; { + "yarn.nodemanager.local-dirs" = localDir; + "yarn.scheduler.maximum-allocation-vcores" = resource.maximumAllocationVCores; + "yarn.scheduler.maximum-allocation-mb" = resource.maximumAllocationMB; + "yarn.nodemanager.resource.cpu-vcores" = resource.cpuVCores; + "yarn.nodemanager.resource.memory-mb" = resource.memoryMB; + } // mkIf useCGroups { + "yarn.nodemanager.linux-container-executor.cgroups.hierarchy" = "/hadoop-yarn"; + "yarn.nodemanager.linux-container-executor.resources-handler.class" = "org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler"; + "yarn.nodemanager.linux-container-executor.cgroups.mount" = "true"; + "yarn.nodemanager.linux-container-executor.cgroups.mount-path" = "/run/wrappers/yarn-nodemanager/cgroup"; + }; + networking.firewall.allowedTCPPortRanges = [ (mkIf (cfg.yarn.nodemanager.openFirewall) {from = 1024; to = 65535;}) ]; diff --git a/nixos/tests/hadoop/hadoop.nix b/nixos/tests/hadoop/hadoop.nix index 42c238ef853..b132f4fa58b 100644 --- a/nixos/tests/hadoop/hadoop.nix +++ b/nixos/tests/hadoop/hadoop.nix @@ -10,15 +10,10 @@ import ../make-test-python.nix ({ package, ... }: { "fs.defaultFS" = "hdfs://ns1"; }; hdfsSite = { - "dfs.namenode.rpc-bind-host" = "0.0.0.0"; - "dfs.namenode.http-bind-host" = "0.0.0.0"; - "dfs.namenode.servicerpc-bind-host" = "0.0.0.0"; - # HA Quorum Journal Manager configuration "dfs.nameservices" = "ns1"; "dfs.ha.namenodes.ns1" = "nn1,nn2"; - "dfs.namenode.shared.edits.dir.ns1.nn1" = "qjournal://jn1:8485;jn2:8485;jn3:8485/ns1"; - "dfs.namenode.shared.edits.dir.ns1.nn2" = "qjournal://jn1:8485;jn2:8485;jn3:8485/ns1"; + "dfs.namenode.shared.edits.dir.ns1" = "qjournal://jn1:8485;jn2:8485;jn3:8485/ns1"; "dfs.namenode.rpc-address.ns1.nn1" = "nn1:8020"; "dfs.namenode.rpc-address.ns1.nn2" = "nn2:8020"; "dfs.namenode.servicerpc-address.ns1.nn1" = "nn1:8022"; @@ -32,7 +27,7 @@ import ../make-test-python.nix ({ package, ... }: { "dfs.ha.fencing.methods" = "shell(true)"; "ha.zookeeper.quorum" = "zk1:2181"; }; - yarnSiteHA = { + yarnSite = { "yarn.resourcemanager.zk-address" = "zk1:2181"; "yarn.resourcemanager.ha.enabled" = "true"; "yarn.resourcemanager.ha.rm-ids" = "rm1,rm2"; @@ -116,8 +111,7 @@ import ../make-test-python.nix ({ package, ... }: { # YARN cluster rm1 = { options, ... }: { services.hadoop = { - inherit package coreSite hdfsSite; - yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; + inherit package coreSite hdfsSite yarnSite; yarn.resourcemanager = { enable = true; openFirewall = true; @@ -126,8 +120,7 @@ import ../make-test-python.nix ({ package, ... }: { }; rm2 = { options, ... }: { services.hadoop = { - inherit package coreSite hdfsSite; - yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; + inherit package coreSite hdfsSite yarnSite; yarn.resourcemanager = { enable = true; openFirewall = true; @@ -137,8 +130,7 @@ import ../make-test-python.nix ({ package, ... }: { nm1 = { options, ... }: { virtualisation.memorySize = 2048; services.hadoop = { - inherit package coreSite hdfsSite; - yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; + inherit package coreSite hdfsSite yarnSite; yarn.nodemanager = { enable = true; openFirewall = true; @@ -148,8 +140,7 @@ import ../make-test-python.nix ({ package, ... }: { client = { options, ... }: { services.hadoop = { gatewayRole.enable = true; - inherit package coreSite hdfsSite; - yarnSite = options.services.hadoop.yarnSite.default // yarnSiteHA; + inherit package coreSite hdfsSite yarnSite; }; }; }; diff --git a/nixos/tests/hadoop/hdfs.nix b/nixos/tests/hadoop/hdfs.nix index cc70fb8ecaf..9415500463d 100644 --- a/nixos/tests/hadoop/hdfs.nix +++ b/nixos/tests/hadoop/hdfs.nix @@ -35,6 +35,10 @@ with lib; hdfs.datanode = { enable = true; openFirewall = true; + dataDirs = [{ + type = "DISK"; + path = "/tmp/dn1"; + }]; }; inherit coreSite; }; -- cgit 1.4.1