/usr/share/doc/ganeti/html/design-node-add.html is in ganeti-doc 2.16.0~rc2-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Design for adding a node to a cluster — Ganeti 2.16.0~rc2 documentation</title>
<link rel="stylesheet" href="_static/style.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '2.16.0~rc2',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Improvements of Node Security" href="design-node-security.html" />
<link rel="prev" title="Network management" href="design-network.html" />
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="design-node-security.html" title="Improvements of Node Security"
accesskey="N">next</a></li>
<li class="right" >
<a href="design-network.html" title="Network management"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="design-for-adding-a-node-to-a-cluster">
<h1><a class="toc-backref" href="#id1">Design for adding a node to a cluster</a><a class="headerlink" href="#design-for-adding-a-node-to-a-cluster" title="Permalink to this headline">¶</a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Created:</th><td class="field-body">2012-Oct-16</td>
</tr>
<tr class="field-even field"><th class="field-name">Status:</th><td class="field-body">Implemented</td>
</tr>
<tr class="field-odd field"><th class="field-name">Ganeti-Version:</th><td class="field-body">2.7.0</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#design-for-adding-a-node-to-a-cluster" id="id1">Design for adding a node to a cluster</a><ul>
<li><a class="reference internal" href="#note" id="id2">Note</a></li>
<li><a class="reference internal" href="#current-state-and-shortcomings" id="id3">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes" id="id4">Proposed changes</a><ul>
<li><a class="reference internal" href="#ssh" id="id5">SSH</a></li>
<li><a class="reference internal" href="#node-daemon" id="id6">Node daemon</a></li>
</ul>
</li>
<li><a class="reference internal" href="#data-structures" id="id7">Data structures</a><ul>
<li><a class="reference internal" href="#json-structure-for-ssh-setup" id="id8">JSON structure for SSH setup</a></li>
<li><a class="reference internal" href="#json-structure-for-node-daemon-setup" id="id9">JSON structure for node daemon setup</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="note">
<h2><a class="toc-backref" href="#id2">Note</a><a class="headerlink" href="#note" title="Permalink to this headline">¶</a></h2>
<p>Closely related to this design is the more recent design
<a class="reference internal" href="design-node-security.html"><span class="doc">node security</span></a> which extends and changes
some of the aspects mentioned in this document. Make sure that you
read the more recent design as well to get an up to date picture of
Ganeti’s procedure for adding new nodes.</p>
</div>
<div class="section" id="current-state-and-shortcomings">
<h2><a class="toc-backref" href="#id3">Current state and shortcomings</a><a class="headerlink" href="#current-state-and-shortcomings" title="Permalink to this headline">¶</a></h2>
<p>Before a node can be added to a cluster, its SSH daemon must be
re-configured to use the cluster-wide SSH host key. Ganeti 2.3.0 changed
the way this is done by moving all related code to a separate script,
<code class="docutils literal"><span class="pre">tools/setup-ssh</span></code>, using Paramiko. Before all such configuration was
done from <code class="docutils literal"><span class="pre">lib/bootstrap.py</span></code> using the system’s own SSH client and a
shell script given to said client through parameters.</p>
<p>Both solutions controlled all actions on the connecting machine; the
newly added node was merely executing commands. This implies and
requires a tight coupling and equality between nodes (e.g. paths to
files being the same). Most of the logic and error handling is also done
on the connecting machine.</p>
<p>Once a node’s SSH daemon has been configured, more than 25 files need to
be copied using <code class="docutils literal"><span class="pre">scp</span></code> before the node daemon can be started. No
verification is being done before files are copied. Once the node daemon
is started, an opcode is submitted to the master daemon, which will then
copy more files, such as the configuration and job queue for master
candidates, using RPC. This process is somewhat fragile and requires
initiating many SSH connections.</p>
</div>
<div class="section" id="proposed-changes">
<h2><a class="toc-backref" href="#id4">Proposed changes</a><a class="headerlink" href="#proposed-changes" title="Permalink to this headline">¶</a></h2>
<div class="section" id="ssh">
<h3><a class="toc-backref" href="#id5">SSH</a><a class="headerlink" href="#ssh" title="Permalink to this headline">¶</a></h3>
<p>The main goal is to move more logic to the newly added node. Instead of
having a relatively large script executed on the master node, most of it
is moved over to the added node.</p>
<p>A new script named <code class="docutils literal"><span class="pre">prepare-node-join</span></code> is added. It receives a JSON
data structure (defined <a class="reference internal" href="#prepare-node-join-json"><span class="std std-ref">below</span></a>) on its
standard input. Once the data has been successfully decoded, it proceeds
to configure the local node’s SSH daemon and root’s SSH settings, after
which the SSH daemon is restarted.</p>
<p>All the master node has to do to add a new node is to gather all
required data, build the data structure, and invoke the script on the
node to be added. This will enable us to once again use the system’s own
SSH client and to drop the dependency on Paramiko for Ganeti itself
(<code class="docutils literal"><span class="pre">ganeti-listrunner</span></code> is going to continue using Paramiko).</p>
<p>Eventually <code class="docutils literal"><span class="pre">setup-ssh</span></code> can be removed.</p>
</div>
<div class="section" id="node-daemon">
<h3><a class="toc-backref" href="#id6">Node daemon</a><a class="headerlink" href="#node-daemon" title="Permalink to this headline">¶</a></h3>
<p>Similar to SSH setup changes, the process of copying files and starting
the node daemon will be moved into a dedicated program. On its standard
input it will receive a standardized JSON structure (defined <a class="reference internal" href="#node-daemon-setup-json"><span class="std std-ref">below</span></a>). Once the input data has been successfully
decoded and the received values were verified for sanity, the program
proceeds to write the values to files and then starts the node daemon
(<code class="docutils literal"><span class="pre">ganeti-noded</span></code>).</p>
<p>To add a new node to the cluster, the master node will have to gather
all values, build the data structure, and then invoke the newly added
<code class="docutils literal"><span class="pre">node-daemon-setup</span></code> program via SSH. In this way only a single SSH
connection is needed and the values can be verified before being written
to files.</p>
<p>If the program exits successfully, the node is ready to be added to the
master daemon’s configuration. The node daemon will be running, but
<code class="docutils literal"><span class="pre">OpNodeAdd</span></code> needs to be run before it becomes a full node. The opcode
will copy more files, such as the <a class="reference internal" href="rapi.html"><span class="doc">RAPI certificate</span></a>.</p>
</div>
</div>
<div class="section" id="data-structures">
<h2><a class="toc-backref" href="#id7">Data structures</a><a class="headerlink" href="#data-structures" title="Permalink to this headline">¶</a></h2>
<div class="section" id="json-structure-for-ssh-setup">
<span id="prepare-node-join-json"></span><h3><a class="toc-backref" href="#id8">JSON structure for SSH setup</a><a class="headerlink" href="#json-structure-for-ssh-setup" title="Permalink to this headline">¶</a></h3>
<p>The data is given in an object containing the keys described below.
Unless specified otherwise, all entries are optional.</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">cluster_name</span></code></dt>
<dd>Required string with the cluster name. If a local cluster name is
found, the join process is aborted unless the passed cluster name
matches the local name.</dd>
<dt><code class="docutils literal"><span class="pre">node_daemon_certificate</span></code></dt>
<dd>Public part of cluster’s node daemon certificate in PEM format. If a
local node certificate and key is found, the join process is aborted
unless this passed public part can be verified with the local key.</dd>
<dt><code class="docutils literal"><span class="pre">ssh_host_key</span></code></dt>
<dd>List containing public and private parts of SSH host key. See below
for definition.</dd>
<dt><code class="docutils literal"><span class="pre">ssh_root_key</span></code></dt>
<dd>List containing public and private parts of root’s key for SSH
authorization. See below for definition.</dd>
</dl>
<p>Lists of SSH keys use a tuple with three values. The first describes the
key variant (<code class="docutils literal"><span class="pre">rsa</span></code> or <code class="docutils literal"><span class="pre">dsa</span></code>). The second and third are the private
and public part of the key. Example:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span></span><span class="p">[</span>
<span class="p">(</span><span class="s2">"rsa"</span><span class="p">,</span> <span class="s2">"-----BEGIN RSA PRIVATE KEY-----..."</span><span class="p">,</span> <span class="s2">"ssh-rss AAAA..."</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"dsa"</span><span class="p">,</span> <span class="s2">"-----BEGIN DSA PRIVATE KEY-----..."</span><span class="p">,</span> <span class="s2">"ssh-dss AAAA..."</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="json-structure-for-node-daemon-setup">
<span id="node-daemon-setup-json"></span><h3><a class="toc-backref" href="#id9">JSON structure for node daemon setup</a><a class="headerlink" href="#json-structure-for-node-daemon-setup" title="Permalink to this headline">¶</a></h3>
<p>The data is given in an object containing the keys described below.
Unless specified otherwise, all entries are optional.</p>
<dl class="docutils">
<dt><code class="docutils literal"><span class="pre">cluster_name</span></code></dt>
<dd>Required string with the cluster name. If a local cluster name is
found, the join process is aborted unless the passed cluster name
matches the local name. The cluster name is also included in the
dictionary given via the <code class="docutils literal"><span class="pre">ssconf</span></code> entry.</dd>
<dt><code class="docutils literal"><span class="pre">node_daemon_certificate</span></code></dt>
<dd>Public and private part of cluster’s node daemon certificate in PEM
format. If a local node certificate is found, the process is aborted
unless it matches.</dd>
<dt><code class="docutils literal"><span class="pre">ssconf</span></code></dt>
<dd><p class="first">Dictionary with ssconf names and their values. Both are strings.
Example:</p>
<div class="last highlight-javascript"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="s2">"cluster_name"</span><span class="o">:</span> <span class="s2">"cluster.example.com"</span><span class="p">,</span>
<span class="s2">"master_ip"</span><span class="o">:</span> <span class="s2">"192.168.2.1"</span><span class="p">,</span>
<span class="s2">"master_netdev"</span><span class="o">:</span> <span class="s2">"br0"</span><span class="p">,</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</dd>
<dt><code class="docutils literal"><span class="pre">start_node_daemon</span></code></dt>
<dd>Boolean denoting whether the node daemon should be started (or
restarted if it was running for some reason).</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Design for adding a node to a cluster</a><ul>
<li><a class="reference internal" href="#note">Note</a></li>
<li><a class="reference internal" href="#current-state-and-shortcomings">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes">Proposed changes</a><ul>
<li><a class="reference internal" href="#ssh">SSH</a></li>
<li><a class="reference internal" href="#node-daemon">Node daemon</a></li>
</ul>
</li>
<li><a class="reference internal" href="#data-structures">Data structures</a><ul>
<li><a class="reference internal" href="#json-structure-for-ssh-setup">JSON structure for SSH setup</a></li>
<li><a class="reference internal" href="#json-structure-for-node-daemon-setup">JSON structure for node daemon setup</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="design-network.html"
title="previous chapter">Network management</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="design-node-security.html"
title="next chapter">Improvements of Node Security</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/design-node-add.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<div><input type="text" name="q" /></div>
<div><input type="submit" value="Go" /></div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="design-node-security.html" title="Improvements of Node Security"
>next</a></li>
<li class="right" >
<a href="design-network.html" title="Network management"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> »</li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2018, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Google Inc..
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.7.
</div>
</body>
</html>
|