Repository: mesos Updated Branches: refs/heads/master 74e09a82e -> e878c74fb
http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/containerizer/linux_launcher.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/linux_launcher.cpp b/src/slave/containerizer/linux_launcher.cpp index 1ce03e3..f3cc813 100644 --- a/src/slave/containerizer/linux_launcher.cpp +++ b/src/slave/containerizer/linux_launcher.cpp @@ -28,6 +28,7 @@ #include <stout/abort.hpp> #include <stout/hashset.hpp> #include <stout/path.hpp> +#include <stout/strings.hpp> #include "linux/cgroups.hpp" @@ -57,6 +58,12 @@ LinuxLauncher::LinuxLauncher( hierarchy(_hierarchy) {} +// An old glibc might not have this symbol. +#ifndef CLONE_NEWNET +#define CLONE_NEWNET 0x40000000 +#endif + + Try<Launcher*> LinuxLauncher::create(const Flags& flags) { Try<string> hierarchy = cgroups::prepare( @@ -75,6 +82,15 @@ Try<Launcher*> LinuxLauncher::create(const Flags& flags) // to use. int namespaces = 0; +#ifdef WITH_NETWORK_ISOLATOR + // The network port mapping isolator requires network (CLONE_NEWNET) + // and mount (CLONE_NEWNS) namespaces. + if (strings::contains(flags.isolation, "network/port_mapping")) { + namespaces |= CLONE_NEWNET; + namespaces |= CLONE_NEWNS; + } +#endif + return new LinuxLauncher(flags, namespaces, hierarchy.get()); } http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/containerizer/mesos/containerizer.cpp ---------------------------------------------------------------------- diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp index 2fd121f..2c394e2 100644 --- a/src/slave/containerizer/mesos/containerizer.cpp +++ b/src/slave/containerizer/mesos/containerizer.cpp @@ -40,6 +40,9 @@ #include "slave/containerizer/isolators/cgroups/mem.hpp" #include "slave/containerizer/isolators/cgroups/perf_event.hpp" #endif // __linux__ +#ifdef WITH_NETWORK_ISOLATOR +#include "slave/containerizer/isolators/network/port_mapping.hpp" +#endif #include "slave/containerizer/mesos/containerizer.hpp" #include "slave/containerizer/mesos/launch.hpp" @@ -130,6 +133,9 @@ Try<MesosContainerizer*> MesosContainerizer::create( creators["cgroups/mem"] = &CgroupsMemIsolatorProcess::create; creators["cgroups/perf_event"] = &CgroupsPerfEventIsolatorProcess::create; #endif // __linux__ +#ifdef WITH_NETWORK_ISOLATOR + creators["network/port_mapping"] = &PortMappingIsolatorProcess::create; +#endif vector<Owned<Isolator> > isolators; @@ -148,8 +154,10 @@ Try<MesosContainerizer*> MesosContainerizer::create( } #ifdef __linux__ - // Use cgroups on Linux if any cgroups isolators are used. - Try<Launcher*> launcher = strings::contains(isolation, "cgroups") + // Determine which launcher to use based on the isolation flag. + Try<Launcher*> launcher = + (strings::contains(isolation, "cgroups") || + strings::contains(isolation, "network/port_mapping")) ? LinuxLauncher::create(flags) : PosixLauncher::create(flags); #else http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/flags.hpp ---------------------------------------------------------------------- diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp index 3b8ba08..c6a970f 100644 --- a/src/slave/flags.hpp +++ b/src/slave/flags.hpp @@ -56,8 +56,10 @@ public: add(&Flags::isolation, "isolation", - "Isolation mechanisms to use, e.g., 'posix/cpu,posix/mem'\n" - "or 'cgroups/cpu,cgroups/mem' or 'external'.", + "Isolation mechanisms to use, e.g., 'posix/cpu,posix/mem', or\n" + "'cgroups/cpu,cgroups/mem', or network/port_mapping\n" + "(configure with flag: --with-network-isolator to enable),\n" + "or 'external'.", "posix/cpu,posix/mem"); add(&Flags::default_role, @@ -254,6 +256,34 @@ public: "default_container_image", "The default container image to use if not specified by a task,\n" "when using external containerizer"); + +#ifdef WITH_NETWORK_ISOLATOR + add(&Flags::ephemeral_ports_per_container, + "ephemeral_ports_per_container", + "Number of ephemeral ports allocated to a container by the network\n" + "isolator. This number has to be a power of 2.\n", + DEFAULT_EPHEMERAL_PORTS_PER_CONTAINER); + + add(&Flags::private_resources, + "private_resources", + "The resources that will be manged by the slave locally, and not\n" + "exposed to Mesos master and frameworks. It shares the same format\n" + "as the 'resources' flag. One example of such type of resources\n" + "is ephemeral ports when port mapping network isolator is enabled.\n" + "Use 'ports:[x-y]' to specify the ephemeral ports that will be\n" + "locally managed.\n"); + + add(&Flags::eth0_name, + "eth0_name", + "The name of the public network interface (e.g., eth0). If it is\n" + "not specified, the network isolator will try to guess it based\n" + "on the host default gateway."); + + add(&Flags::lo_name, + "lo_name", + "The name of the loopback network interface (e.g., lo). If it is\n" + "not specified, the network isolator will try to guess it."); +#endif // WITH_NETWORK_ISOLATOR } bool version; @@ -291,6 +321,12 @@ public: Option<std::string> credential; Option<std::string> containerizer_path; Option<std::string> default_container_image; +#ifdef WITH_NETWORK_ISOLATOR + uint16_t ephemeral_ports_per_container; + Option<std::string> private_resources; + Option<std::string> eth0_name; + Option<std::string> lo_name; +#endif }; } // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/slave/slave.cpp ---------------------------------------------------------------------- diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp index 0cb98cd..24eb8fd 100644 --- a/src/slave/slave.cpp +++ b/src/slave/slave.cpp @@ -274,11 +274,24 @@ void Slave::initialize() CHECK_SOME(os::mkdir(flags.work_dir)) << "Failed to create slave work directory '" << flags.work_dir << "'"; - Try<Resources> _resources = Containerizer::resources(flags); - if (_resources.isError()) { - EXIT(1) << "Failed to determine slave resources: " << _resources.error(); + Try<Resources> resources = Containerizer::resources(flags); + if (resources.isError()) { + EXIT(1) << "Failed to determine slave resources: " << resources.error(); } - LOG(INFO) << "Slave resources: " << _resources.get(); + LOG(INFO) << "Slave resources: " << resources.get(); + +#ifdef WITH_NETWORK_ISOLATOR + // Resources that are not exposed to the frameworks, but managed by + // the slave privately. + Try<Resources> privateResources = Resources::parse( + flags.private_resources.get(""), flags.default_role); + + if (privateResources.isError()) { + EXIT(1) << "Failed to determine slave private resources: " + << privateResources.error(); + } + LOG(INFO) << "Slave private resources: " << privateResources.get(); +#endif if (flags.attributes.isSome()) { attributes = Attributes::parse(flags.attributes.get()); @@ -302,10 +315,14 @@ void Slave::initialize() // Initialize slave info. info.set_hostname(hostname); info.set_port(self().port); - info.mutable_resources()->CopyFrom(_resources.get()); + info.mutable_resources()->CopyFrom(resources.get()); info.mutable_attributes()->CopyFrom(attributes); info.set_checkpoint(flags.checkpoint); +#ifdef WITH_NETWORK_ISOLATOR + info.mutable_private_resources()->CopyFrom(privateResources.get()); +#endif + LOG(INFO) << "Slave hostname: " << info.hostname(); LOG(INFO) << "Slave checkpoint: " << stringify(flags.checkpoint); http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/environment.cpp ---------------------------------------------------------------------- diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp index e991d57..4aaf1a4 100644 --- a/src/tests/environment.cpp +++ b/src/tests/environment.cpp @@ -144,6 +144,14 @@ static bool enable(const ::testing::TestInfo& test) } } +#ifdef WITH_NETWORK_ISOLATOR + // Currently, the network isolator does not support multiple slaves. + if (strings::contains(test.name(), "MultipleSlaves") && + os::user().isSome() && os::user().get() == "root") { + return false; + } +#endif + return true; } http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/isolator_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp index 5a141e3..6fef4e0 100644 --- a/src/tests/isolator_tests.cpp +++ b/src/tests/isolator_tests.cpp @@ -56,6 +56,7 @@ #include "tests/utils.hpp" using namespace mesos; + using namespace mesos::internal; using namespace mesos::internal::tests; http://git-wip-us.apache.org/repos/asf/mesos/blob/e878c74f/src/tests/mesos.cpp ---------------------------------------------------------------------- diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp index 216bd6f..6550673 100644 --- a/src/tests/mesos.cpp +++ b/src/tests/mesos.cpp @@ -33,6 +33,7 @@ #include "linux/cgroups.hpp" #endif +#include "slave/constants.hpp" #include "slave/containerizer/containerizer.hpp" #include "slave/containerizer/mesos/containerizer.hpp" @@ -328,6 +329,13 @@ slave::Flags ContainerizerTest<slave::MesosContainerizer>::CreateSlaveFlags() flags.isolation = "posix/cpu,posix/mem"; #endif +#ifdef WITH_NETWORK_ISOLATOR + if (user.get() == "root") { + flags.isolation += ",network/port_mapping"; + flags.private_resources = "ports:" + slave::DEFAULT_EPHEMERAL_PORTS; + } +#endif + return flags; }