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:
50  static Try<mesos::slave::Isolator*> create(const Flags& flags);
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  : containerNetworks (_containerNetworks),
97  rootfs(_rootfs),
98  hostname(_hostname) {}
99 
100  // CNI network information keyed by network name.
101  //
102  // NOTE: For nested containers, since the container shares the
103  // network namespace with the root container of its hierarchy,
104  // this should simply be a copy of the `containerNetworks` of its
105  // root container.
106  hashmap<std::string, ContainerNetwork> containerNetworks;
107 
108  // Rootfs of the container file system. In case the container uses
109  // the host file system, this will be `None`.
110  const Option<std::string> rootfs;
111 
113  };
114 
115  // Reads each CNI config present in `configDir`, validates if the
116  // `plugin` is present in the search path associated with
117  // `pluginDir` and adds the CNI network config to `networkConfigs`
118  // if the validation passes. If there is an error while reading the
119  // CNI config, or if the plugin is not found, we log an error and the
120  // CNI network config is not added to `networkConfigs`.
121  static Try<hashmap<std::string, std::string>> loadNetworkConfigs(
122  const std::string& configDir,
123  const std::string& pluginDir);
124 
125  NetworkCniIsolatorProcess(
126  const Flags& _flags,
127  const hashmap<std::string, std::string>& _networkConfigs,
129  const Option<ContainerDNSInfo::MesosInfo>& _defaultCniDNS = None(),
130  const Option<std::string>& _rootDir = None(),
131  const Option<std::string>& _pluginDir = None())
132  : ProcessBase(process::ID::generate("mesos-network-cni-isolator")),
133  flags(_flags),
134  networkConfigs(_networkConfigs),
135  cniDNSMap(_cniDNSMap),
136  defaultCniDNS(_defaultCniDNS),
137  rootDir(_rootDir),
138  pluginDir(_pluginDir) {}
139 
140  process::Future<Nothing> _isolate(
141  const ContainerID& containerId,
142  pid_t pid,
143  const list<process::Future<Nothing>>& attaches);
144 
145  process::Future<Nothing> __isolate(
146  const NetworkCniIsolatorSetup& setup);
147 
148  Try<Nothing> _recover(
149  const ContainerID& containerId,
150  const Option<mesos::slave::ContainerState>& state = None());
151 
153  const ContainerID& containerId,
154  const std::string& networkName,
155  const std::string& netNsHandle);
156 
157  process::Future<Nothing> _attach(
158  const ContainerID& containerId,
159  const std::string& networkName,
160  const std::string& plugin,
161  const std::tuple<
165 
167  const ContainerID& containerId,
168  const std::string& networkName);
169 
170  process::Future<Nothing> _detach(
171  const ContainerID& containerId,
172  const std::string& networkName,
173  const std::string& plugin,
174  const std::tuple<
178 
179  process::Future<Nothing> _cleanup(
180  const ContainerID& containerId,
181  const std::list<process::Future<Nothing>>& detaches);
182 
183  // Searches the `networkConfigs` hashmap for a CNI network. If the
184  // hashmap doesn't contain the network, will try to load all the CNI
185  // configs from `flags.network_cni_config_dir`, and will then
186  // perform another search of the `networkConfigs` hashmap to see if
187  // the missing network was present on disk.
188  Try<JSON::Object> getNetworkConfigJSON(const std::string& network);
189 
190  // Given a network name and the path for the CNI network
191  // configuration file, reads the file, parses the JSON and
192  // validates the name of the network to which this configuration
193  // file belongs.
194  Try<JSON::Object> getNetworkConfigJSON(
195  const std::string& network,
196  const std::string& path);
197 
198  const Flags flags;
199 
200  // A map storing the path to CNI network configuration files keyed
201  // by the network name.
202  hashmap<std::string, std::string> networkConfigs;
203 
204  // DNS informations of CNI networks keyed by CNI network name.
206 
207  // Default DNS information for all CNI networks.
208  const Option<ContainerDNSInfo::MesosInfo> defaultCniDNS;
209 
210  // CNI network information root directory.
211  const Option<std::string> rootDir;
212 
213  // CNI plugins directory.
214  const Option<std::string> pluginDir;
215 
216  // Information of CNI networks that each container joins.
218 };
219 
220 
221 // A subcommand to setup container hostname and mount the hosts,
222 // resolv.conf and hostname from the host file system into the
223 // container's file system. The hostname needs to be setup in the
224 // container's UTS namespace, and the files need to be bind mounted in
225 // the container's mnt namespace.
227 {
228 public:
229  static const char* NAME;
230 
231  struct Flags : public virtual flags::FlagsBase
232  {
233  Flags();
234 
243  };
244 
246 
248 
249 protected:
250  virtual int execute();
251  virtual flags::FlagsBase* getFlags() { return &flags; }
252 };
253 
254 } // namespace slave {
255 } // namespace internal {
256 } // namespace mesos {
257 
258 #endif // __NETWORK_CNI_ISOLATOR_HPP__
std::string generate(const std::string &prefix="")
Returns &#39;prefix(N)&#39; where N represents the number of instances where the same prefix (wrt...
ProcessBase(const std::string &id="")
NetworkCniIsolatorSetup()
Definition: cni.hpp:245
Definition: try.hpp:34
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:240
Definition: subcommand.hpp:41
Definition: flags.hpp:44
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:238
Option< std::string > rootfs
Definition: cni.hpp:237
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
virtual ~NetworkCniIsolatorProcess()
Definition: cni.hpp:52
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
virtual process::Future< Nothing > isolate(const ContainerID &containerId, pid_t pid)
Definition: none.hpp:27
virtual process::Future< Nothing > cleanup(const ContainerID &containerId)
Option< std::string > hostname
Definition: cni.hpp:236
virtual flags::FlagsBase * getFlags()
Definition: cni.hpp:251
Option< pid_t > pid
Definition: cni.hpp:235
virtual process::Future< Nothing > recover(const std::list< mesos::slave::ContainerState > &states, const hashset< ContainerID > &orphans)
Option< std::string > etc_hostname_path
Definition: cni.hpp:239
static const char * NAME
Definition: cni.hpp:229