Apache Mesos
cni.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __NETWORK_CNI_ISOLATOR_HPP__
18 #define __NETWORK_CNI_ISOLATOR_HPP__
19 
20 #include <process/id.hpp>
21 #include <process/subprocess.hpp>
22 
23 #include <stout/subcommand.hpp>
24 
25 #include "slave/flags.hpp"
26 
28 
31 
32 namespace mesos {
33 namespace internal {
34 namespace slave {
35 
36 // Forward declarations.
37 class NetworkCniIsolatorSetup;
38 
39 
40 // This isolator implements support for Container Network Interface (CNI)
41 // specification <https://github.com/appc/cni/blob/master/SPEC.md> . It
42 // provides network isolation to containers by creating a network namespace
43 // for each container, and then adding the container to the CNI network
44 // specified in the NetworkInfo for the container. It adds the container to
45 // a CNI network by using CNI plugins specified by the operator for the
46 // corresponding CNI network.
48 {
49 public:
51 
53 
54  virtual bool supportsNesting();
55 
57  const std::list<mesos::slave::ContainerState>& states,
58  const hashset<ContainerID>& orphans);
59 
61  const ContainerID& containerId,
62  const mesos::slave::ContainerConfig& containerConfig);
63 
65  const ContainerID& containerId,
66  pid_t pid);
67 
69  const ContainerID& containerId);
70 
72  const ContainerID& containerId);
73 
74 private:
75  struct ContainerNetwork
76  {
77  // CNI network name.
78  std::string networkName;
79 
80  // Interface name.
81  std::string ifName;
82 
83  // NetworkInfo copied from the ExecutorInfo.containerInfo.network_infos
84  // in 'prepare()' and '_recover()'.
85  Option<mesos::NetworkInfo> networkInfo;
86 
87  // Protobuf of CNI network information returned by CNI plugin.
88  Option<cni::spec::NetworkInfo> cniNetworkInfo;
89  };
90 
91  struct Info
92  {
93  Info (const hashmap<std::string, ContainerNetwork>& _containerNetworks,
94  const Option<std::string>& _rootfs = None(),
95  const Option<std::string>& _hostname = None(),
96  bool _joinsParentsNetwork = false)
97  : containerNetworks (_containerNetworks),
98  rootfs(_rootfs),
99  hostname(_hostname),
100  joinsParentsNetwork(_joinsParentsNetwork) {}
101 
102  // CNI network information keyed by network name.
103  //
104  // NOTE: For nested containers, since the container shares the
105  // network namespace with the root container of its hierarchy,
106  // this should simply be a copy of the `containerNetworks` of its
107  // root container.
108  hashmap<std::string, ContainerNetwork> containerNetworks;
109 
110  // Rootfs of the container file system. In case the container uses
111  // the host file system, this will be `None`.
112  const Option<std::string> rootfs;
113 
115  const bool joinsParentsNetwork;
116  };
117 
118  // Reads each CNI config present in `configDir`, validates if the
119  // `plugin` is present in the search path associated with
120  // `pluginDir` and adds the CNI network config to `networkConfigs`
121  // if the validation passes. If there is an error while reading the
122  // CNI config, or if the plugin is not found, we log an error and the
123  // CNI network config is not added to `networkConfigs`.
124  static Try<hashmap<std::string, std::string>> loadNetworkConfigs(
125  const std::string& configDir,
126  const std::string& pluginDir);
127 
129  const Flags& _flags,
130  const hashmap<std::string, std::string>& _networkConfigs,
132  const Option<ContainerDNSInfo::MesosInfo>& _defaultCniDNS = None(),
133  const Option<std::string>& _rootDir = None(),
134  const Option<std::string>& _pluginDir = None())
135  : ProcessBase(process::ID::generate("mesos-network-cni-isolator")),
136  flags(_flags),
137  networkConfigs(_networkConfigs),
138  cniDNSMap(_cniDNSMap),
139  defaultCniDNS(_defaultCniDNS),
140  rootDir(_rootDir),
141  pluginDir(_pluginDir) {}
142 
143  process::Future<Nothing> _isolate(
144  const ContainerID& containerId,
145  pid_t pid,
146  const std::list<process::Future<Nothing>>& attaches);
147 
148  process::Future<Nothing> __isolate(
149  const NetworkCniIsolatorSetup& setup);
150 
151  Try<Nothing> _recover(
152  const ContainerID& containerId,
153  const Option<mesos::slave::ContainerState>& state = None());
154 
156  const ContainerID& containerId,
157  const std::string& networkName,
158  const std::string& netNsHandle);
159 
160  process::Future<Nothing> _attach(
161  const ContainerID& containerId,
162  const std::string& networkName,
163  const std::string& plugin,
164  const std::tuple<
168 
170  const ContainerID& containerId,
171  const std::string& networkName);
172 
173  process::Future<Nothing> _detach(
174  const ContainerID& containerId,
175  const std::string& networkName,
176  const std::string& plugin,
177  const std::tuple<
181 
182  process::Future<Nothing> _cleanup(
183  const ContainerID& containerId,
184  const std::list<process::Future<Nothing>>& detaches);
185 
186  // Searches the `networkConfigs` hashmap for a CNI network. If the
187  // hashmap doesn't contain the network, will try to load all the CNI
188  // configs from `flags.network_cni_config_dir`, and will then
189  // perform another search of the `networkConfigs` hashmap to see if
190  // the missing network was present on disk.
191  Try<JSON::Object> getNetworkConfigJSON(const std::string& network);
192 
193  // Given a network name and the path for the CNI network
194  // configuration file, reads the file, parses the JSON and
195  // validates the name of the network to which this configuration
196  // file belongs.
197  Try<JSON::Object> getNetworkConfigJSON(
198  const std::string& network,
199  const std::string& path);
200 
201  const Flags flags;
202 
203  // A map storing the path to CNI network configuration files keyed
204  // by the network name.
205  hashmap<std::string, std::string> networkConfigs;
206 
207  // DNS informations of CNI networks keyed by CNI network name.
209 
210  // Default DNS information for all CNI networks.
211  const Option<ContainerDNSInfo::MesosInfo> defaultCniDNS;
212 
213  // CNI network information root directory.
214  const Option<std::string> rootDir;
215 
216  // CNI plugins directory.
217  const Option<std::string> pluginDir;
218 
219  // Information of CNI networks that each container joins.
221 };
222 
223 
224 // A subcommand to setup container hostname and mount the hosts,
225 // resolv.conf and hostname from the host file system into the
226 // container's file system. The hostname needs to be setup in the
227 // container's UTS namespace, and the files need to be bind mounted in
228 // the container's mnt namespace.
230 {
231 public:
232  static const char* NAME;
233 
234  struct Flags : public virtual flags::FlagsBase
235  {
236  Flags();
237 
246  };
247 
249 
251 
252 protected:
253  virtual int execute();
254  virtual flags::FlagsBase* getFlags() { return &flags; }
255 };
256 
257 } // namespace slave {
258 } // namespace internal {
259 } // namespace mesos {
260 
261 #endif // __NETWORK_CNI_ISOLATOR_HPP__
Definition: path.hpp:26
std::string generate(const std::string &prefix="")
Returns &#39;prefix(N)&#39; where N represents the number of instances where the same prefix (wrt...
void execute(const std::string &script)
ProcessBase(const std::string &id="")
NetworkCniIsolatorSetup()
Definition: cni.hpp:248
Definition: check.hpp:33
virtual process::Future< ContainerStatus > status(const ContainerID &containerId)
Definition: flags.hpp:39
virtual process::Future< Option< mesos::slave::ContainerLaunchInfo > > prepare(const ContainerID &containerId, const mesos::slave::ContainerConfig &containerConfig)
DWORD pid_t
Definition: windows.hpp:187
Option< std::string > etc_resolv_conf
Definition: cni.hpp:243
Definition: subcommand.hpp:41
Definition: flags.hpp:44
Definition: spec.hpp:30
static Try< mesos::slave::Isolator * > create(const Flags &flags)
Try< std::string > hostname()
Definition: net.hpp:154
Option< std::string > etc_hosts_path
Definition: cni.hpp:241
Option< std::string > rootfs
Definition: cni.hpp:240
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
virtual ~NetworkCniIsolatorProcess()
Definition: cni.hpp:52
virtual process::Future< Nothing > isolate(const ContainerID &containerId, pid_t pid)
Definition: none.hpp:27
Definition: attributes.hpp:24
virtual process::Future< Nothing > cleanup(const ContainerID &containerId)
Option< std::string > hostname
Definition: cni.hpp:239
virtual flags::FlagsBase * getFlags()
Definition: cni.hpp:254
Option< pid_t > pid
Definition: cni.hpp:238
virtual process::Future< Nothing > recover(const std::list< mesos::slave::ContainerState > &states, const hashset< ContainerID > &orphans)
Definition: parse.hpp:33
Option< std::string > etc_hostname_path
Definition: cni.hpp:242
static const char * NAME
Definition: cni.hpp:232