<br><br><div class="gmail_quote">On Fri, Aug 12, 2011 at 03:44, Manuel Jung <span dir="ltr">&lt;<a href="mailto:mjung@astrophysik.uni-kiel.de" target="_blank">mjung@astrophysik.uni-kiel.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


Hi,<div><br></div><div>So i have been browsing around the sources, looking for another solution, to make my use case built in ipcluster, because i were feeling stupid for writing a script to setup the cluster, if this is, what ipcluster should do for me.</div>

</blockquote><div><br></div><div>Honestly, there are many situations for which writing a simple bash script or using screen will always be better than  ipcluster.  Since there are so many possible configurations and considerations, a general tool will always be more complicated than one that caters to a particular environment.  For instance, you should probably create only one set of tunnels per machine, rather than per engine, since 16*8 tunnels is *a lot*, and largely pointless (it is entirely workload/system dependent which is preferable).  Certainly, ipcluster should handle your case better, but that doesn&#39;t mean it&#39;s the ideal tool for you.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>So this is my solution:</div><div><br></div><div>Since we are on a totaly restricted network/pc and ports are never to be reached (execpt for ssh/22) outside of localhost, it is totally save to choose static ports like you suggested in your first post in this thread. </div>



<div><br></div><div><div><div><div>c.LocalControllerLauncher.controller_args = [&#39;--log-level=20&#39;, &#39;--ip=0.0.0.0&#39;, &#39;--location=127.0.0.1&#39;, &#39;--port=10101&#39;, &#39;--HubFactory.hb=10102,10112&#39;, &#39;HubFactory.control=10203,10103&#39;, &#39;--HubFactory.mux=10204,10104&#39;, &#39;--HubFactory.task=10205,10105&#39;]</div>



</div></div></div><div><br></div><div>For tunneling from the engines&#39; host, i have implemented an additional parameter for the SSHEngineSetLauncher. It allows to run a shell command on the engines&#39; host. In this case it is used to establish all tunnels. </div>



<div><br></div><div><div><div>tunnel = [&#39;ssh dwarf20 -N -L10101:<a href="http://127.0.0.1:10101" target="_blank">127.0.0.1:10101</a> -L10102:<a href="http://127.0.0.1:10102" target="_blank">127.0.0.1:10102</a> -L10112:<a href="http://127.0.0.1:10112" target="_blank">127.0.0.1:10112</a> -L10103:<a href="http://127.0.0.1:10103" target="_blank">127.0.0.1:10103</a> -L10104:<a href="http://127.0.0.1:10104" target="_blank">127.0.0.1:10104</a> -L10105:127.0.0.1:10105&#39;.split()]</div>



</div><div>c.SSHEngineSetLauncher.engines = {&#39;pluto&#39; : (16, None, tunnel),</div><div>                                                       &#39;merkur&#39; : (4, None, tunnel)}</div><div><br></div><div>(dwarf20 is the cluster starting client an controller hosting pc, pluto and merkur servers for number crunching, e.g. engines&#39; hosts.)</div>



<div><br></div><div><div>Let me say at this point, that establishing tunnels for all ports in one command isn&#39;t always a good idea, because they share the same tcp connections and bandwidth is restricted on a per connection basis. So maybe this may be a bottleneck under high load.</div>

</div></div></blockquote><div><br></div><div>I think it is highly unlikely that putting all the traffic of a single engine on one tcp connection would be a bottle neck, because under most normal usage, there will not be significant traffic on multiple sockets at the same time.  A case that could bottleneck would be a very large number of very short tasks that print a lot to stdout/err.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>

</div><div><br></div><div>Still this is not enough for getting all connections working. On pluto with 16 cores i experienced often less than 16 successfull connected engines. I found, that simultaneous authentications to an sshd are restricted to 10 by the MaxStartups parameter (see man sshd_config(5)). So i introduced a  new parameter for delaying consecutive ssh connections.</div>



<div><br></div><div><div>c.SSHEngineSetLauncher.delay = 0.2</div></div></div></blockquote><div><br></div><div>delay is great, I will actually add it to the LocalEngineSetLauncher, because it should even be useful at that level (SSHEngineSetLauncher will inherit it).</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><br></div><div>The complete setup from ipcluster_config.py can be found in the post scriptum. I have created a branch on github for this, see <a href="https://github.com/gzahl/ipython/tree/sshenvironment" target="_blank">https://github.com/gzahl/ipython/tree/sshenvironment</a></div>



<div><br></div><div>This works for me at the moment, what do you think about this solution.</div></div></blockquote><div><br></div><div>Thanks for working this out! I think it should be a good starting point.  Some things should probably change - We don&#39;t want to define a class n*p-times inside another, and reindenting the code so it doesn&#39;t match the rest of the file is probably not desirable.  It&#39;s possible that a simple configurable preflight script on the SSHLauncher would be a cleaner solution, and provide an avenue for more general customization.</div>


<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><br></div><div>Two last thoughts:</div><div>- It would be nice, if one wouldn&#39;t have to specify the port configuration an tunnel command explicit. It would be nice if you could only define the ports and activate tunneling=yes. But i&#39;m not sure how this could be done best - yet.</div>


</div></blockquote><div><br></div><div>Something like this would definitely be valuable.  Note that with my enginessh branch, if the Controller was launched with --enginessh=anything, then tunneling *will* be enabled by default (if the `ssh` field of the JSON file is specified, it is used. You can edit it manually after starting the controller, if you like).</div>

<div><br></div><div>The problem with just &#39;tunneling=yes&#39; is that it&#39;s extremely variable what tunneling will look like. We can support one or two simple cases (like the one I cover in enginessh).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<div>- I have to define &#39;--profile=ssh&#39; in the program_args for the SSHEngineLauncher - shouldn&#39;t this be automaticly choosen, if i&#39;m starting with &quot;ipcluster start --profile=ssh&quot;? It seems like a bug to me?</div>


</div></blockquote><div><br></div><div>This presumes that the profile exists on the remote machine and that the initial profile was specified by name and not by path, which is insufficiently general.  What should actually happen is to send the connection file and use it explicitly, with no assumptions about the remote filesystem, or remote profiles available.</div>


<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<div>- I were testing with the ControlMaster feature of SSH (version 4 or greater). It reuses a existing tcp connection and can speed up new ssh connections. But one would ran into the only-one-tcp-connection issues again. Do you know this command? I&#39;m not sure if it is of use in this case. But it could help to lower the SSHEngineSetLauncher.delay parameter.</div>


</div></blockquote><div><br></div><div>I am aware of it.  Since we can&#39;t depend on it, I&#39;m not sure how valuable it is to ipcluster in general (another case where writing against your own environment lets you make assumptions that aren&#39;t appropriate for ipcluster).</div>

<div><br></div><div>In general, the SSH launchers need to be improved.  The sshx code in 0.10.2 was better in many ways, but not in others.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div>
<div><br></div><div>Cheers</div><div>Manuel</div><div><br></div><div><br></div><div>ipcluster_config.py:</div><div><br></div><div>c = get_config()</div><div>c.IPClusterStart.engine_launcher_class = &#39;SSHEngineSetLauncher&#39;</div>



<div>c.IPClusterStart.delay = 2.0</div><div><div>c.LocalControllerLauncher.controller_args = [&#39;--log-level=20&#39;, &#39;--ip=0.0.0.0&#39;, &#39;--location=127.0.0.1&#39;, &#39;--port=10101&#39;, &#39;--HubFactory.hb=10102,10112&#39;, &#39;HubFactory.control=10203,10103&#39;, &#39;--HubFactory.mux=10204,10104&#39;, &#39;--HubFactory.task=10205,10105&#39;]</div>



</div><div># Are hard coded paths really a reasonable default? On my systems this doesn&#39;t make much sense.</div></div></blockquote><div><br></div><div>For local launchers, they absolutely are.  This means that the programs will be run from the same Python, etc. as the ipcluster script.  Otherwise there could be weird situations where &#39;ipcontroller&#39; launched in a subprocess actually points to a different Python or IPython than the one launching it (this has happened *many* times).</div>

<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>c.LocalControllerLauncher.controller_cmd = [&#39;ipcontroller&#39;]</div><div>c.SSHEngineLauncher.program = [&#39;ipengine&#39;]</div>



<div>c.SSHEngineLauncher.program_args = [&#39;--log_level=20&#39;, &#39;--profile=ssh&#39;]</div><div>c.SSHEngineSetLauncher.engine_args = [&#39;--log-level=20&#39;, &#39;--profile=ssh&#39;]</div><div>c.SSHEngineSetLauncher.delay = 0.2</div>



<div>tunnel = [&#39;ssh dwarf20 -N -L10101:<a href="http://127.0.0.1:10101" target="_blank">127.0.0.1:10101</a> -L10102:<a href="http://127.0.0.1:10102" target="_blank">127.0.0.1:10102</a> -L10112:<a href="http://127.0.0.1:10112" target="_blank">127.0.0.1:10112</a> -L10103:<a href="http://127.0.0.1:10103" target="_blank">127.0.0.1:10103</a> -L10104:<a href="http://127.0.0.1:10104" target="_blank">127.0.0.1:10104</a> -L10105:127.0.0.1:10105&#39;.split()]</div>



<div>c.SSHEngineSetLauncher.engines = {&#39;pluto&#39; : (16, None, tunnel),</div><div>                                                       &#39;merkur&#39; : (4, None, tunnel)}</div><div><br></div></div>
</blockquote></div><br>