<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Virgo</title>
<link>https://hpc.gsi.de/virgo/blog/</link>
<atom:link href="https://hpc.gsi.de/virgo/blog/index.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.8.24</generator>
<lastBuildDate>Tue, 04 Jun 2024 22:00:00 GMT</lastBuildDate>
<item>
  <title>JupyterLab with Apptainer</title>
  <dc:creator>Victor Penso</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2024-05-06-apptainer-jupyterlab/</link>
  <description><![CDATA[ 






<section id="why-use-jupyterlab" class="level2">
<h2 class="anchored" data-anchor-id="why-use-jupyterlab">Why Use JupyterLab?</h2>
<p>JupyterLab <sup>1</sup> is an excellent choice for scientific computing due to its flexibility, customization options, and ability to support a wide range of programming languages, libraries, and tools. Here are some reasons why you might choose to use JupyterLab and <strong>Jupyter Notebooks</strong> <sup>2</sup> in scientific computing:</p>
<ol type="1">
<li><strong>Ease of Use</strong>: JupyterLab is designed to be user-friendly, with features like auto-completion, syntax highlighting, and debugging capabilities that can help reduce the learning curve for new users.</li>
<li><strong>Reproducibility</strong>: Jupyter Notebooks (<code>.ipynb</code> files) are self-contained documents that include code, output, and visualizations, making it easy to reproduce results and share them with others.</li>
<li><strong>Easy Data Exploration</strong>: You can load and visualize various data formats, such as CSV, Excel, JSON, and more, using popular libraries like Pandas, NumPy, and Matplotlib.</li>
<li><strong>Interactive Visualizations</strong>: Jupyter notebooks integrate with popular visualization libraries like Plotly, Bokeh, and Altair, enabling you to create interactive, web-based visualizations of your data.</li>
<li><strong>Flexibility</strong>: Support of a wide range of programming languages, including Python, R, Julia, and MATLAB, allowing you to use the language that best suits your needs.</li>
<li><strong>Version Control</strong>: You can use version control systems like Git to manage changes to your notebooks and collaborate with others.</li>
<li><strong>Extensions for Specific Domains</strong>: There are many extensions available for JupyterLab that can help with specific tasks in scientific computing.</li>
</ol>
</section>
<section id="jupyter-containers" class="level2">
<h2 class="anchored" data-anchor-id="jupyter-containers">Jupyter Containers</h2>
<p>The Jupyter team maintains the Jupyter Docker Stack <sup>3</sup> with corresponding public container images on DockerHub <sup>4</sup> and Quay <sup>5</sup>. These container images can be use on any compute-cluster.</p>
<p><strong>Login to a cluster <a href="../../../user-guide/access/submit-nodes.html">submit node</a> and start a JupyterLab container:</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> run docker://jupyter/base-notebook</span></code></pre></div></div>
<p>The JupyterLab service daemon will print log information to the Terminal, including the connection address and a so called access token described in the next section.</p>
<p><strong>Stop JupyterLab by pressing <code>CTRL</code>-<code>C</code> once you have finished working.</strong></p>
<section id="access-token" class="level3">
<h3 class="anchored" data-anchor-id="access-token">Access Token</h3>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>stdout</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" data-filename="stdout" style="background: #f1f3f5;"><pre class="sourceCode txt code-with-copy"><code class="sourceCode default"><span id="cb2-1"># Information from the logs of the JupyterLab service</span>
<span id="cb2-2">Or copy and paste one of these URLs:</span>
<span id="cb2-3">    http://lxbk0725:12345/lab?token=598fb99446ce46996e9a74ea28bea3d2c7fd2591be4431f6</span>
<span id="cb2-4">    http://127.0.0.1:12345/lab?token=598fb99446ce46996e9a74ea28bea3d2c7fd2591be4431f6</span></code></pre></div></div>
</div>
<p>A Jupyter Access Token <sup>6</sup> like the example above is a secure, randomly generated string that authenticates and authorizes users to access JupyterLab notebooks and resources, providing an additional layer of security and control over notebook sharing and collaboration.</p>
<p><strong>The access token includes the host name and port number required by the user to connect</strong>.</p>
<p>In the simplest case you can use the HTTP address which includes the host name of the executing node (<code>lxbk0725</code> in the example above) to connect to JupyterLab with your web browser. In case you accessed the cluster from an external network you will need to setup SSH port forwarding as explained in the next section.</p>
</section>
<section id="remote-access" class="level3">
<h3 class="anchored" data-anchor-id="remote-access">Remote Access</h3>
<p>Access to JupyterLab from outside networks requires an additional step. SSH Port Forwarding is a technique that creates a secure, encrypted tunnel between your local machine and a remote server, allowing you to access the remote server’s services or applications as if they were running locally by forwarding specific ports from the remote server to your local machine.</p>
<p><strong>Use <a href="../../../user-guide/access/submit-nodes.html#secure-shell">SSH</a> to configure port forwarding to Jupyter running on the cluster:</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ssh</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-vv</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-N</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-L</span> localhost:12345:lxbk0725.gsi.de:12345 virgo.hpc.gsi.de</span>
<span id="cb3-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># …logs will be print to the terminal …use ctrl-c to close</span></span></code></pre></div></div>
<p>Once port forwarding has been started use the HTTP address with the IP address <code>127.0.0.1</code> (localhost) to connect to JupyterLab.</p>
</section>
</section>
<section id="build-a-container" class="level2">
<h2 class="anchored" data-anchor-id="build-a-container">Build a Container</h2>
<p>The following section implies that you want to add Jupyter to an existing container. Alternatively you could use the Jupyter Docker Stack as foundation and build from there by adding your components on top.</p>
<p>To integrate JupyterLab into your Apptainer container, you’ll typically extend an existing configuration that includes your working environment. Following assumes you have Python 3 available in our container and uses a Python virtual environment <sup>7</sup> to install JupyterLab.</p>
<p><strong>Adding JupyterLab to an Apptainer Container Definition File</strong> <sup>8</sup>:</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>apptainer.def</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" data-filename="apptainer.def" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%post</span></span>
<span id="cb4-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># …add in an appropriate place in the post-section</span></span>
<span id="cb4-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mkdir</span> /app</span>
<span id="cb4-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> /app</span>
<span id="cb4-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">python3</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-m</span> venv venv</span>
<span id="cb4-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">.</span> venv/bin/activate</span>
<span id="cb4-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># install JupyterLab including some extensions</span></span>
<span id="cb4-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">pip3</span> install <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-9">        jupyter <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-10">        jupyterlab-spellchecker <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-11">        jupyterlab-git <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-12">        jupyterlab-lsp <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-13">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'python-lsp-server[all]'</span></span>
<span id="cb4-14"></span>
<span id="cb4-15"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%environment</span></span>
<span id="cb4-16"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">JUPYTERLAB_PORT</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>54321</span>
<span id="cb4-17"></span>
<span id="cb4-18"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%runscript</span></span>
<span id="cb4-19"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">.</span> /app/venv/bin/activate</span>
<span id="cb4-20"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> jupyter lab <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--no-browser</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--ip</span> 0.0.0.0 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--port</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$JUPYTERLAB_PORT</span></span>
<span id="cb4-21"></span>
<span id="cb4-22"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%startscript</span></span>
<span id="cb4-23"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">.</span> /app/venv/bin/activate</span>
<span id="cb4-24"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> jupyter lab <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--no-browser</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--ip</span> 0.0.0.0 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--port</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$JUPYTERLAB_PORT</span></span></code></pre></div></div>
</div>
<p>The example above prepares the use of <code>apptainer instance</code> <sup>9</sup> to manage your JupyterLab installation:</p>
<blockquote class="blockquote">
<p>Apptainer, also allows you to run containers in a “detached” or “daemon” mode where the container runs a service. A “service” is essentially a process running in the background…</p>
</blockquote>
<p>Following environment variables is used to set the service port:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 39%">
<col style="width: 60%">
</colgroup>
<thead>
<tr class="header">
<th>Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>JUPYTERLAB_PORT</code></td>
<td>This defines the default port used when a JupyterLab instance is started. The configuration above sets the port to <code>54321</code>. Note that in case you share a host with other users you may be required to adjust the port number to avoid collisions.</td>
</tr>
</tbody>
</table>
<p><strong>Build the container and copy the image to <a href="../../../user-guide/storage.html#shared-storage">shared storage</a></strong>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="annotated-cell-5" style="background: #f1f3f5;"><pre class="sourceCode bash code-annotation-code code-with-copy code-annotated"><code class="sourceCode bash"><a class="code-annotation-anchor" data-target-cell="annotated-cell-5" data-target-annotation="1" onclick="event.preventDefault();">1</a><span id="annotated-cell-5-1" class="code-annotation-target"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build apptainer.sif apptainer.def</span>
<span id="annotated-cell-5-2"></span>
<span id="annotated-cell-5-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Make sure to store the container image on persistent storage for example Lustre</span></span>
<span id="annotated-cell-5-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">LUSTRE_HOME</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">id</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-ng</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span>/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span></span>
<span id="annotated-cell-5-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINERS</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LUSTRE_HOME</span>/containers</span>
<a class="code-annotation-anchor" data-target-cell="annotated-cell-5" data-target-annotation="2" onclick="event.preventDefault();">2</a><span id="annotated-cell-5-6" class="code-annotation-target"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cp</span> apptainer.sif <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINERS</span>/jupyterlab.sif</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div></div>
<dl class="code-annotation-container-grid">
<dt data-target-cell="annotated-cell-5" data-target-annotation="1">1</dt>
<dd>
<span data-code-cell="annotated-cell-5" data-code-lines="1" data-code-annotation="1">Build the Apptainer container image from the definition file <sup>10</sup></span>
</dd>
<dt data-target-cell="annotated-cell-5" data-target-annotation="2">2</dt>
<dd>
<span data-code-cell="annotated-cell-5" data-code-lines="6" data-code-annotation="2">Copy the JupyterLab container images to your Lustre directory</span>
</dd>
</dl>
<p><strong>Start the container instance on the current host:</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="annotated-cell-6" style="background: #f1f3f5;"><pre class="sourceCode bash code-annotation-code code-with-copy code-annotated"><code class="sourceCode bash"><a class="code-annotation-anchor" data-target-cell="annotated-cell-6" data-target-annotation="1" onclick="event.preventDefault();">1</a><span id="annotated-cell-6-1" class="code-annotation-target"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINERENV_JUPYTERLAB_PORT</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>12345</span>
<a class="code-annotation-anchor" data-target-cell="annotated-cell-6" data-target-annotation="2" onclick="event.preventDefault();">2</a><span id="annotated-cell-6-2" class="code-annotation-target"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> run <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINERS</span>/jupyterlab.sif</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div></div>
<dl class="code-annotation-container-grid">
<dt data-target-cell="annotated-cell-6" data-target-annotation="1">1</dt>
<dd>
<span data-code-cell="annotated-cell-6" data-code-lines="1" data-code-annotation="1">Overwrite the default port configuration with an environment variable</span>
</dd>
<dt data-target-cell="annotated-cell-6" data-target-annotation="2">2</dt>
<dd>
<span data-code-cell="annotated-cell-6" data-code-lines="2" data-code-annotation="2">Start your JupyterLab instance on the local node</span>
</dd>
</dl>
<p><strong>Start a JupyterLab instance on a cluster node:</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="annotated-cell-7" style="background: #f1f3f5;"><pre class="sourceCode bash code-annotation-code code-with-copy code-annotated"><code class="sourceCode bash"><a class="code-annotation-anchor" data-target-cell="annotated-cell-7" data-target-annotation="1" onclick="event.preventDefault();">1</a><span id="annotated-cell-7-1" class="code-annotation-target"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">LUSTRE_HOME</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">id</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-ng</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span>/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LUSTRE_HOME</span></span>
<a class="code-annotation-anchor" data-target-cell="annotated-cell-7" data-target-annotation="2" onclick="event.preventDefault();">2</a><span id="annotated-cell-7-2" class="code-annotation-target"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">srun</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--nodes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>1 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--ntasks-per-node</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>1 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--time</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>01:00:00 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--pty</span> bash <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-i</span></span>
<span id="annotated-cell-7-3"></span>
<span id="annotated-cell-7-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># …once your allocation has been granted</span></span>
<a class="code-annotation-anchor" data-target-cell="annotated-cell-7" data-target-annotation="3" onclick="event.preventDefault();">3</a><span id="annotated-cell-7-5" class="code-annotation-target"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONFIGDIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LUSTRE_HOME</span>/.apptainer</span>
<a class="code-annotation-anchor" data-target-cell="annotated-cell-7" data-target-annotation="4" onclick="event.preventDefault();">4</a><span id="annotated-cell-7-6" class="code-annotation-target"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> instance start <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LUSTRE_HOME</span>/jupyterlab.sif jupyterlab</span><div class="code-annotation-gutter-bg"></div><div class="code-annotation-gutter"></div></code></pre></div></div>
<dl class="code-annotation-container-grid">
<dt data-target-cell="annotated-cell-7" data-target-annotation="1">1</dt>
<dd>
<span data-code-cell="annotated-cell-7" data-code-lines="1" data-code-annotation="1">Configure your working directory, typically on shared storage</span>
</dd>
<dt data-target-cell="annotated-cell-7" data-target-annotation="2">2</dt>
<dd>
<span data-code-cell="annotated-cell-7" data-code-lines="2" data-code-annotation="2">Allocate an interactive session on a compute node with <code>srun</code></span>
</dd>
<dt data-target-cell="annotated-cell-7" data-target-annotation="3">3</dt>
<dd>
<span data-code-cell="annotated-cell-7" data-code-lines="5" data-code-annotation="3">Make sure the Apptainer configuration path is located on writable storage</span>
</dd>
<dt data-target-cell="annotated-cell-7" data-target-annotation="4">4</dt>
<dd>
<span data-code-cell="annotated-cell-7" data-code-lines="6" data-code-annotation="4">Start your JupyterLab instance on the compute node</span>
</dd>
</dl>
<p>Read the access token from the log-files of your JupyterLab instance:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> cat <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONFIGDIR</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/instances/logs/</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">hostname</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/jupyterlab.err</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb5-2">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-o</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'http.*lab?token.*'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sort</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">uniq</span></span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">http://127.0.0.1:54321/lab?token=041ded5856f8bfe5202c5118027016f990390729ff7d0433</span></span>
<span id="cb5-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">http://lxbk0724:54321/lab?token=041ded5856f8bfe5202c5118027016f990390729ff7d0433</span></span></code></pre></div></div>


<!-- -->

</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Project Jupyter Documentation<br>
<a href="https://docs.jupyter.org/en/latest" class="uri">https://docs.jupyter.org/en/latest</a>↩︎</p></li>
<li id="fn2"><p>Jupyter Notebook Documentation<br>
<a href="https://jupyter-notebook.readthedocs.io" class="uri">https://jupyter-notebook.readthedocs.io</a>↩︎</p></li>
<li id="fn3"><p>Jupyter Docker Stacks<br>
<a href="https://jupyter-docker-stacks.readthedocs.io" class="uri">https://jupyter-docker-stacks.readthedocs.io</a><br>
<a href="https://github.com/jupyter/docker-stacks" class="uri">https://github.com/jupyter/docker-stacks</a>↩︎</p></li>
<li id="fn4"><p>Jupyter Project, DockerHub<br>
<a href="https://hub.docker.com/u/jupyter" class="uri">https://hub.docker.com/u/jupyter</a>↩︎</p></li>
<li id="fn5"><p>Project Jupyter, Quay.io<br>
<a href="https://quay.io/organization/jupyter" class="uri">https://quay.io/organization/jupyter</a>↩︎</p></li>
<li id="fn6"><p>Security in the Jupyter Server<br>
<a href="https://jupyter-server.readthedocs.io/en/stable/operators/security.html" class="uri">https://jupyter-server.readthedocs.io/en/stable/operators/security.html</a>↩︎</p></li>
<li id="fn7"><p>Virtual Environments, Python Documentation<br>
<a href="https://docs.python.org/3/library/venv.html" class="uri">https://docs.python.org/3/library/venv.html</a>↩︎</p></li>
<li id="fn8"><p>Apptainer Definition Files, Apptainer User Manual<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html" class="uri">https://apptainer.org/docs/user/main/definition_files.html</a>↩︎</p></li>
<li id="fn9"><p>Instances - Running Service, Apptainer User Manual<br>
<a href="https://apptainer.org/docs/user/main/running_services.html" class="uri">https://apptainer.org/docs/user/main/running_services.html</a>↩︎</p></li>
<li id="fn10"><p>Build a Container, Apptainer User Manual<br>
<a href="https://apptainer.org/docs/user/main/build_a_container.html" class="uri">https://apptainer.org/docs/user/main/build_a_container.html</a>↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Container</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2024-05-06-apptainer-jupyterlab/</guid>
  <pubDate>Tue, 04 Jun 2024 22:00:00 GMT</pubDate>
</item>
<item>
  <title>Apptainer Containers Overview</title>
  <dc:creator>Victor Penso</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2023-11-29-apptainer-containers/</link>
  <description><![CDATA[ 






<div class="quarto-layout-panel" data-layout-ncol="2">
<div class="quarto-layout-row">
<section id="questions" class="level4 quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<h4 class="anchored" data-anchor-id="questions">Questions</h4>
<ul>
<li>Why use containers?</li>
<li>What are container images?</li>
</ul>
</section>
<section id="objectives" class="level4 quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<h4 class="anchored" data-anchor-id="objectives">Objectives</h4>
<ul>
<li>Learn how to use exiting containers</li>
<li>Understand container definition files</li>
</ul>
</section>
</div>
</div>
<section id="using-apptainer" class="level1">
<h1>Using Apptainer</h1>
<p>Apptainer <sup>1</sup> enables users to interact with containers transparently. Execute programs inside a container (as if running on the host). Redirect I/O, use command pipes, pass arguments, access files, sockets and ports. Apptainer is updated regularly <sup>2</sup> and most Linux distributions have packages available in their repositories. On Fedora for example, install Apptainer using the official <code>apptainer</code> package <sup>3</sup>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># install apptainer</span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> dnf install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-y</span> apptainer</span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># verify functionality</span></span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> run docker://alpine</span></code></pre></div></div>
<p>Users of MacOS and Windows can execute Linux containers in a virtual environment on their computer. It is not necessarily required to have Apptainer installed on your machine. Many HPC systems will have the <code>apptainer</code> command pre-installed, including the capability to build container images on the cluster nodes. However it is often preferable to use container images in the local environment as well, and copy them on-demand to a target HPC system. This approach ensures that you work with the exact same environment under all circumstance.</p>
<section id="why-use-containers" class="level4 unlisted">
<h4 class="unlisted anchored" data-anchor-id="why-use-containers">Why use containers?</h4>
<ol type="1">
<li>Many applications in the HPC environment have become very complex in regards to software dependencies and details of configuration. For many years HPC infrastructure providers have struggled to build a common environment to facilitate the requirements of all user-communities on a single host platform. Containers enable complete decoupling of application environments from the host platform and other users. In addition containerization prevents any interference between user environments, an issue that created a lot of friction for cluster operations in the past.</li>
<li>Containers change the user environment into a swappable component. Allowing users to have a custom application environment “packaged” into a container image. This container image can be executed within any host that provides container support. Which includes their own computer and a growing number of HPC systems.</li>
<li>The most important benefit for users is the complete independence from the HPC host environment. This allows the freedom of choice to select any Linux distribution as a foundation for the container image. Furthermore users can install any combination of compilers, libraries and other software components in versions they require.</li>
<li>Most container images are build programmatically using definition files. This ties into the concepts and goals of reproducible science. Images can not only be preserved without any ties to the host infrastructure used for execution, but are based on a recipe detailing how the image was build in the first place.</li>
<li>Updates to both containerized applications and the host infrastructure are not interrelated. This benefits HPC administrators by enabling them to select the most suitable host environment to support the growing complexity of hardware. At the same time users can make changes to container images aligned with their scientific schedule and other boundary conditions.</li>
</ol>
</section>
</section>
<section id="container-images" class="level1">
<h1>Container Images</h1>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Sub-Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>pull</code></td>
<td>Download a container image from a remote resource</td>
</tr>
</tbody>
</table>
<section id="what-are-container-images" class="level4 unlisted">
<h4 class="unlisted anchored" data-anchor-id="what-are-container-images">What are container images?</h4>
<ul>
<li>A container images stores a file-system tree containing a software environment (compilers, frameworks, libraries, etc.) for a given application.</li>
<li>Additionally container images store configuration metadata used during container launch to create a desired application run-time environment.</li>
<li>Container images are typically read-only (immutable) snapshots, which makes them host independent and portable. They can be moved freely between different infrastructures, and are published in container registries.</li>
<li>New images are often derived from an existing image. Usually the container definition is maintained with a version control system.</li>
<li>It is easy to switch between multiple versions of container images simplifying the roll-out of updates and roll-back in case of problems.</li>
</ul>
<p>The container image default format for Apptainer is called <strong>SIF (Singularity Image File)</strong>, a compressed read-only container file, by convention suffixed with <code>.sif</code>. Download container images <sup>4</sup> from a remote location, for example a container registry like DockerHub, with <code>apptainer pull</code>. This downloads all require container layers and combines those layers into an image file stored to the container cache in the path <code>~/.apptainer/cache</code> by default.</p>
<p>Many use-cases can build on an existing container images. Pre-build images are published by many organizations in a public container registry. A registry is centralized storage for container images. All container runtime systems (like Apptainer) have a standard way to download images from a registry. The most popular image registry is is DockerHub <sup>5</sup>, the origin of a common protocol used to communicate with a container registry.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 42%">
<col style="width: 57%">
</colgroup>
<thead>
<tr class="header">
<th>Environment Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>APPTAINER_CONTAINER</code></td>
<td>Absolute path to storage location for container images</td>
</tr>
</tbody>
</table>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Set the path to a directoy storing container images...</span></span>
<span id="cb2-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LUSTRE_HOME</span>/containers</span>
<span id="cb2-3"></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...download a container image from a container registry</span></span>
<span id="cb2-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> pull <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/jupyter.sif docker://quay.io/datascience-notebook:latest</span></code></pre></div></div>
<p>Above example shows the download of a container image provided by Project Jupyter <sup>6</sup>, pulled from a container registry called Quay (by RedHat) using the standard <code>docker://</code> protocol. It is up to the users to select an appropriate image for their application. The recommendation is to use container images provided by the developer community of a given software ecosystem.</p>
</section>
</section>
<section id="interact-with-containers" class="level1">
<h1>Interact with Containers</h1>
<table class="caption-top table">
<colgroup>
<col style="width: 40%">
<col style="width: 60%">
</colgroup>
<thead>
<tr class="header">
<th>Sub-Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>exec</code></td>
<td>Execute a command within a containerized environment</td>
</tr>
<tr class="even">
<td><code>shell</code></td>
<td>Start an interactive shell session in a containerized environment</td>
</tr>
</tbody>
</table>
<p>The Jupyter <code>datascience-notebook</code> container image downloaded in the previous section includes a Python environment supporting the NumPy package <sup>7</sup> for scientific computing. Users interact with container images <sup>8</sup> using a selection of Apptainer sub-commands. The sub-command <code>exec</code> executes a specified command within a container. Below a very simple Python program utilizing the NumPy package:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/usr/bin/env python</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb3-4"></span>
<span id="cb3-5">array <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([</span>
<span id="cb3-6">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb3-7">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>],</span>
<span id="cb3-8">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]</span>
<span id="cb3-9">])</span>
<span id="cb3-10"></span>
<span id="cb3-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(np.sort(array, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Implement the NumPy program above in an example file...</span></span>
<span id="cb4-2"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$EDITOR</span> example.py</span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...make the example file an executable program</span></span>
<span id="cb4-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">chmod</span> +x example.py</span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Execute the Python program in the downloaded container image</span></span>
<span id="cb4-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> exec <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/jupyter.sif ./example.py</span></code></pre></div></div>
<p>The <code>shell</code> sub-command starts an interactive shell within a container:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> apptainer <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">shell</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/jupyter.sif         </span>
<span id="cb5-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Apptainer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> ipython</span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Python</span> 3.11.6 <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">packaged</span> by conda-forge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">main,</span> Oct  3 2023, 10:40:35<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[GCC</span> 12.3.0]</span>
<span id="cb5-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Type</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'copyright'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'credits'</span> or <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'license'</span> for more information</span>
<span id="cb5-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">IPython</span> 8.16.1 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--</span> An enhanced Interactive Python. Type <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'?'</span> for help.</span>
<span id="cb5-6"></span>
<span id="cb5-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">In</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">1</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span>: </span></code></pre></div></div>
</section>
<section id="build-containers" class="level1">
<h1>Build Containers</h1>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Sub-Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>build</code></td>
<td>Build a new container image from a definition file</td>
</tr>
</tbody>
</table>
<p>Create a new container image <sup>9</sup> with the help of a container <strong>definition file</strong> (or “def file” for short). The following example builds a container image for the GNU Hello <sup>10</sup> software, based on a definition file called <code>hello.def</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">BootStrap:</span> docker</span>
<span id="cb6-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">From:</span> quay.io/fedora/fedora:latest</span>
<span id="cb6-3"></span>
<span id="cb6-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%labels</span></span>
<span id="cb6-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Maintainer</span> John Snow <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>j.snow@example.com<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-6"></span>
<span id="cb6-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%post</span></span>
<span id="cb6-8"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">version</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>2.12.1</span>
<span id="cb6-9"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">archive</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>hello-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$version</span>.tar.gz</span>
<span id="cb6-10"></span>
<span id="cb6-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">dnf</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-y</span> wget tar gzip gcc make</span>
<span id="cb6-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">dnf</span> clean all</span>
<span id="cb6-13"></span>
<span id="cb6-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wget</span> https://ftp.gnu.org/gnu/hello/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span></span>
<span id="cb6-15"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tar</span> xvzf <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-C</span> /opt</span>
<span id="cb6-16"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rm</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span></span>
<span id="cb6-17"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> /opt/hello-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$version</span></span>
<span id="cb6-18"></span>
<span id="cb6-19"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./configure</span></span>
<span id="cb6-20"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span></span>
<span id="cb6-21"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> install</span>
<span id="cb6-22"></span>
<span id="cb6-23"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%runscript</span></span>
<span id="cb6-24"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/usr/local/bin/hello</span></span></code></pre></div></div>
<p>Run the following command providing the container image name and the definition file as arguments to build a container image:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/hello.sif hello.def</span></code></pre></div></div>
<p>Test the functionality of the container image by executing the <code>hello</code> application in the container:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> apptainer <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">run</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/hello.sif                </span>
<span id="cb8-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Hello,</span> world!</span>
<span id="cb8-3"></span>
<span id="cb8-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> apptainer <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span>/hello.sif hello <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--version</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n1</span></span>
<span id="cb8-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hello</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">GNU</span> Hello<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2.12.1</span></span></code></pre></div></div>
<section id="definition-files" class="level2">
<h2 class="anchored" data-anchor-id="definition-files">Definition Files</h2>
<p>Container images are build from a definition file <sup>11</sup>, basically a blueprint listing each step to install software components within the container. The files are divided into two parts:</p>
<ol type="1">
<li>The <strong>header</strong> defines the Linux distribution used as foundation to build the container image (root) file-system. We recommend to select the distribution best supported by the software you want to use.</li>
<li>The rest of the definition is comprised of <strong>sections</strong> to install additional software and configure the container run-time environment.</li>
</ol>
<section id="header" class="level3">
<h3 class="anchored" data-anchor-id="header">Header</h3>
<p>The header at the top defines the base operating system used to build the container. The <code>Bootstrap</code> keyword is mandatory in the first line. This keyword supports multiple <strong>bootstrap agents</strong> <sup>12</sup>, for example the <code>docker</code> agent enables access to compatible container registries like DockerHub:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...from DockerHub</span></span>
<span id="cb9-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">BootStrap:</span> docker</span>
<span id="cb9-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">From:</span> fedora:latest</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...from Quay (RedHat)</span></span>
<span id="cb10-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">BootStrap:</span> docker</span>
<span id="cb10-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">From:</span> quay.io/rockylinux/rockylinux:8</span></code></pre></div></div>
</section>
<section id="sections" class="level3">
<h3 class="anchored" data-anchor-id="sections">Sections</h3>
<p>The second part of the definition file is broken into sections <sup>13</sup>. Each section adds different content or executes commands at different times during the container image build (note that multiple sections of the same name can be included). The build option <code>--section</code> allows to limit execution to a specific section or sections. The table below presents a brief overview of all possible sections:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Section</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>%setup</code></td>
<td>…executed on the host…before container build</td>
</tr>
<tr class="even">
<td><code>%files</code></td>
<td>…copy files into the container before <code>%post</code></td>
</tr>
<tr class="odd">
<td><code>%post</code></td>
<td>…install software…create configurations</td>
</tr>
<tr class="even">
<td><code>%test</code></td>
<td>…validate the container</td>
</tr>
<tr class="odd">
<td><code>%environment</code></td>
<td>…define environment variables <sup>14</sup> (not made available at build time)</td>
</tr>
<tr class="even">
<td><code>%startscript</code></td>
<td>…executed at <code>instance start</code> command</td>
</tr>
<tr class="odd">
<td><code>%runscript</code></td>
<td>…executed at <code>run</code> command</td>
</tr>
<tr class="even">
<td><code>%labels</code></td>
<td>…add metadata to the file <code>/.singularity.d/labels.json</code></td>
</tr>
<tr class="odd">
<td><code>%help</code></td>
<td>…help text…</td>
</tr>
</tbody>
</table>
<p>The definition file below illustrates many sections as examples:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%setup</span></span>
<span id="cb11-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">touch</span> /file1</span>
<span id="cb11-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">touch</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${APPTAINER_ROOTFS}</span>/file2</span>
<span id="cb11-4"></span>
<span id="cb11-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%files</span></span>
<span id="cb11-6">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/file1</span></span>
<span id="cb11-7">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/file1</span> /opt</span>
<span id="cb11-8"></span>
<span id="cb11-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%environment</span></span>
<span id="cb11-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">LISTEN_PORT</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>12345</span>
<span id="cb11-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">LC_ALL</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>C</span>
<span id="cb11-12"></span>
<span id="cb11-13"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%post</span></span>
<span id="cb11-14">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apt-get</span> update <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apt-get</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-y</span> netcat</span>
<span id="cb11-15">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">NOW</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">date</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span></span>
<span id="cb11-16">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"export NOW=</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${NOW}</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_ENVIRONMENT</span></span>
<span id="cb11-17"></span>
<span id="cb11-18"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%runscript</span></span>
<span id="cb11-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Container was created </span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$NOW</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb11-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Arguments received: </span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$*</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb11-21">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> echo <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$@</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb11-22"></span>
<span id="cb11-23"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%startscript</span></span>
<span id="cb11-24">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">nc</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-lp</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LISTEN_PORT</span></span>
<span id="cb11-25"></span>
<span id="cb11-26"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%test</span></span>
<span id="cb11-27">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-q</span> NAME=<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\"</span>Ubuntu<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\"</span> /etc/os-release</span>
<span id="cb11-28">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">[</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$?</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">-eq</span> 0 <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">]</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb11-29">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Container base is Ubuntu as expected."</span></span>
<span id="cb11-30">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb11-31">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Container base is not Ubuntu."</span></span>
<span id="cb11-32">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exit</span> 1</span>
<span id="cb11-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fi</span></span>
<span id="cb11-34"></span>
<span id="cb11-35"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%labels</span></span>
<span id="cb11-36">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Author</span> alice</span>
<span id="cb11-37">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Version</span> v0.0.1</span>
<span id="cb11-38"></span>
<span id="cb11-39"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%help</span></span>
<span id="cb11-40">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">This</span> is a demo container used to illustrate a def file that uses all</span>
<span id="cb11-41">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">supported</span> sections.</span></code></pre></div></div>
</section>
</section>
<section id="local-images" class="level2">
<h2 class="anchored" data-anchor-id="local-images">Local Images</h2>
<p>Repeatedly building containers can become a time consuming process. Apptainer supports to build containers from local images. This enables to maintain a list of base containers as foundation for later reuse. Following definition builds a base-container from the latest Fedora release including developer tools, compilers and a selection of additional useful packages.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb12-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">BootStrap:</span> docker</span>
<span id="cb12-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">From:</span> quay.io/fedora/fedora:latest</span>
<span id="cb12-3"></span>
<span id="cb12-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">%post</span></span>
<span id="cb12-5"></span>
<span id="cb12-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">dnf</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-y</span> @development-tools <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-7">      gcc-c++ gcc gcc-gfortran git git-delta gnupg2 <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-8">      python3 python3-pip python3-setuptools python3-boto3 <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-9">      psmisc rsync tmux tree wget unzip <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-10">      bat curl fd-find fzf findutils <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-11">      hostname iproute netcat neovim make patch <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb12-12">dnf clean all</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...build the container image</span></span>
<span id="cb13-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build fedora-base.sif fedora-base.def</span></code></pre></div></div>
<p>Another container definition file can then reuse a local image with the following bootstrap configuration <sup>15</sup>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb14-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Bootstrap:</span> localimage</span>
<span id="cb14-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">From:</span> fedora-base.sif</span></code></pre></div></div>
<p>Note that Apptainer supports another mechanism called multi-stage build <sup>16</sup> in a single container definition file.</p>
</section>
</section>
<section id="container-cache" class="level1">
<h1>Container Cache</h1>
<table class="caption-top table">
<colgroup>
<col style="width: 38%">
<col style="width: 61%">
</colgroup>
<thead>
<tr class="header">
<th>Environment Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>APPTAINER_CACHEDIR</code></td>
<td>Cache folder for images from a container registry.</td>
</tr>
<tr class="even">
<td><code>APPTAINER_TMPDIR</code></td>
<td>Temporary directory to build container file-systems.</td>
</tr>
</tbody>
</table>
<p>By default the container build cache is located in the directory <code>$HOME/.apptainer</code>. Details about the container build environment are available in the Apptainer User Guide <sup>17</sup>. Pay attention to the storage consumed by the container cache, since the amount of available space may be limited depending on your environment.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb15-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># show storage capacity used by the cache</span></span>
<span id="cb15-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> cache list</span>
<span id="cb15-3"></span>
<span id="cb15-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ..detailed view</span></span>
<span id="cb15-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> cache list <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-v</span></span>
<span id="cb15-6"></span>
<span id="cb15-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># clean up everything</span></span>
<span id="cb15-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> cache clean</span></code></pre></div></div>
<p>The environment variable listed in the table on top are used to configure the paths to the container caches. Following example stores all container artifacts on volatile storage in the <code>/var/tmp</code> directory by setting both variables:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># create a user working directory</span></span>
<span id="cb16-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">pushd</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mktemp</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span> /var/tmp/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span>-apptainer-XXXXXX<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-3"></span>
<span id="cb16-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># locate all artifacts within this directory</span></span>
<span id="cb16-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_TMPDIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$PWD</span></span>
<span id="cb16-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CACHEDIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$PWD</span></span></code></pre></div></div>
<p>This is useful in make sure that all build-artifact don’t linger in your environment.</p>
</section>
<section id="test-sandboxes" class="level1">
<h1>Test Sandboxes</h1>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Option</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>--sandbox</code></td>
<td>Work with a container image (root)-filesystem</td>
</tr>
</tbody>
</table>
<p>A sandbox provides a writable (ch)root directory to interactively work with a container image. This is obviously not a reproducible method to build an image, but it is helps testing during implementation of definition files:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...create a container within a writable directory</span></span>
<span id="cb17-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--fix-perms</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--sandbox</span> rootfs/ docker://quay.io/rockylinux/rockylinux:8</span>
<span id="cb17-3"></span>
<span id="cb17-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...make changes within the container</span></span>
<span id="cb17-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> shell <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--writable</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--fakeroot</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--home</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$PWD</span> rootfs/</span>
<span id="cb17-6"></span>
<span id="cb17-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...build a new container from the sandbox</span></span>
<span id="cb17-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build apptainer.sif rootfs/</span></code></pre></div></div>
<p>Do not forget to delete the <code>rootfs</code> directory afterwards, since these can consume multiple Gigabytes of storage.</p>
</section>
<section id="docker-compatibility" class="level1">
<h1>Docker Compatibility</h1>
<p>Container build and runtime tools have a complex interrelationship and overlap of functionality. The most widely used container tools outside of HPC are Docker <sup>18</sup> and Podman <sup>19</sup>, which are mostly compatible to each other. Chances are high that you will encounter projects providing a <code>Dockerfile</code> <sup>20</sup> as container definition. Consider the example below for GNU Hello introduced previously:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode dockerfile code-with-copy"><code class="sourceCode dockerfile"><span id="cb18-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> quay.io/fedora/fedora:latest</span>
<span id="cb18-2"></span>
<span id="cb18-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ARG</span> version=2.12.1</span>
<span id="cb18-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ARG</span> archive=hello-$version.tar.gz</span>
<span id="cb18-5"></span>
<span id="cb18-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">dnf</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-y</span> wget tar gzip gcc make</span>
<span id="cb18-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">dnf</span> clean all</span>
<span id="cb18-8"></span>
<span id="cb18-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wget</span> https://ftp.gnu.org/gnu/hello/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span></span>
<span id="cb18-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tar</span> xvzf <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-C</span> /opt</span>
<span id="cb18-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rm</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$archive</span></span>
<span id="cb18-12"></span>
<span id="cb18-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">WORKDIR</span> /opt/hello-$version</span>
<span id="cb18-14"></span>
<span id="cb18-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./configure</span></span>
<span id="cb18-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span></span>
<span id="cb18-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">RUN</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> install</span>
<span id="cb18-18"></span>
<span id="cb18-19"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ENTRYPOINT</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/usr/local/bin/hello</span></span></code></pre></div></div>
<p>The notation above differs significantly from an Apptainer definition file. In order to build a container image from a <code>Dockerfile</code>, use the <code>build</code> sub-command <sup>21</sup> of Podman. Please consult the corresponding documentations for more details.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb19-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Build a container image using a `Dockerfile` in the working directory...</span></span>
<span id="cb19-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">podman</span> build <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-t</span> hello .</span>
<span id="cb19-3"></span>
<span id="cb19-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...and execute the container image to test its functionality</span></span>
<span id="cb19-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">podman</span> run <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--rm</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-it</span> localhost/hello:latest</span></code></pre></div></div>
<p>For the purpose of this article it is interesting to understand the compatibility of Apptainer and Docker container images. Apptainer uses a different container format SIF, as discussed above. Fortunately it is easy to convert between both formats:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Create an OCI container archive...</span></span>
<span id="cb20-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">podman</span> push localhost/hello:latest oci-archive:/tmp/hello-latest.tar</span>
<span id="cb20-3"></span>
<span id="cb20-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...and use this archive to create a SIF container image</span></span>
<span id="cb20-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> build hello.sif oci-archive:/tmp/hello-latest.tar</span></code></pre></div></div>
<p>The two commands above use an standardized container image format called OCI Image Layout <sup>22</sup> as intermediate step during conversion. There is a lot more details to the conversion then described here. We leave it to the reader to continue to investigate this.</p>


<!-- -->

</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Apptainer<br>
<a href="https://apptainer.org" class="uri">https://apptainer.org</a>↩︎</p></li>
<li id="fn2"><p>List of Apptainer Releases, GitHub<br>
<a href="https://github.com/apptainer/apptainer/releases" class="uri">https://github.com/apptainer/apptainer/releases</a>↩︎</p></li>
<li id="fn3"><p>Fedora Apptainer Package<br>
<a href="https://src.fedoraproject.org/rpms/apptainer" class="uri">https://src.fedoraproject.org/rpms/apptainer</a>↩︎</p></li>
<li id="fn4"><p>Downloading Images, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/latest/quick_start.html#downloading-images" class="uri">https://apptainer.org/docs/user/latest/quick_start.html#downloading-images</a>↩︎</p></li>
<li id="fn5"><p>Container Registry, Docker Manual<br>
<a href="https://docs.docker.com/registry/" class="uri">https://docs.docker.com/registry/</a>↩︎</p></li>
<li id="fn6"><p>Project Jupyter, Quay.io<br>
<a href="https://quay.io/organization/jupyter" class="uri">https://quay.io/organization/jupyter</a>↩︎</p></li>
<li id="fn7"><p>Numpy Package<br>
<a href="https://numpy.org/" class="uri">https://numpy.org/</a>↩︎</p></li>
<li id="fn8"><p>Interacting with Images, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/quick_start.html#interacting-with-images" class="uri">https://apptainer.org/docs/user/main/quick_start.html#interacting-with-images</a>↩︎</p></li>
<li id="fn9"><p>Build a Container, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/build_a_container.html" class="uri">https://apptainer.org/docs/user/main/build_a_container.html</a>↩︎</p></li>
<li id="fn10"><p>GNU Hello<br>
<a href="https://www.gnu.org/software/hello" class="uri">https://www.gnu.org/software/hello</a>↩︎</p></li>
<li id="fn11"><p>Definition Files, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html" class="uri">https://apptainer.org/docs/user/main/definition_files.html</a>↩︎</p></li>
<li id="fn12"><p>Bootstrap Agents, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html#other-bootstrap-agents" class="uri">https://apptainer.org/docs/user/main/definition_files.html#other-bootstrap-agents</a>↩︎</p></li>
<li id="fn13"><p>Sections, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html#sections" class="uri">https://apptainer.org/docs/user/main/definition_files.html#sections</a>↩︎</p></li>
<li id="fn14"><p>Environment and Metadata, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/environment_and_metadata.html#environment-and-metadata" class="uri">https://apptainer.org/docs/user/main/environment_and_metadata.html#environment-and-metadata</a>↩︎</p></li>
<li id="fn15"><p>Build Modules, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/appendix.html#build-localimage" class="uri">https://apptainer.org/docs/user/main/appendix.html#build-localimage</a>↩︎</p></li>
<li id="fn16"><p>Multi-Stage Builds, Apptainer User Guides<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html#multi-stage-builds" class="uri">https://apptainer.org/docs/user/main/definition_files.html#multi-stage-builds</a>↩︎</p></li>
<li id="fn17"><p>Apptainer User Guide - Build Environment<br>
<a href="http://apptainer.org/docs/user/main/build_env.html#cache-folders" class="uri">http://apptainer.org/docs/user/main/build_env.html#cache-folders</a>↩︎</p></li>
<li id="fn18"><p>Docker Documentation<br>
<a href="https://docs.docker.com/" class="uri">https://docs.docker.com/</a>↩︎</p></li>
<li id="fn19"><p>Podman Documentation<br>
<a href="https://podman.io/docs" class="uri">https://podman.io/docs</a>↩︎</p></li>
<li id="fn20"><p>Dockerfile Reference, Docker Documentation<br>
<a href="https://docs.docker.com/engine/reference/builder/" class="uri">https://docs.docker.com/engine/reference/builder/</a>↩︎</p></li>
<li id="fn21"><p>Podman Build Manual Page<br>
<a href="https://docs.podman.io/en/latest/markdown/podman-build.1.html" class="uri">https://docs.podman.io/en/latest/markdown/podman-build.1.html</a>↩︎</p></li>
<li id="fn22"><p>OCI Image Layout Specification, Open Containers Initiative<br>
<a href="https://github.com/opencontainers/image-spec/blob/main/image-layout.md" class="uri">https://github.com/opencontainers/image-spec/blob/main/image-layout.md</a>↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Container</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2023-11-29-apptainer-containers/</guid>
  <pubDate>Tue, 28 Nov 2023 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Policy-based routing on the cluster at GSI</title>
  <dc:creator>Sören Fleischer</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2023-11-24-policy-based-routing/</link>
  <description><![CDATA[ 






<section id="the-cluster-at-gsi" class="level2">
<h2 class="anchored" data-anchor-id="the-cluster-at-gsi">The cluster at GSI</h2>
<p>GSI has a cluster located within the Green IT Cube.</p>
<p>It features</p>
<ul>
<li>A number of worker nodes a.k.a. execution nodes a.k.a. number crunchers</li>
<li>A number of storage machines which constitute a <code>Lustre</code> file system, which is mounted on the worker nodes</li>
<li>A <code>Slurm</code> instance to manage computing workloads.</li>
</ul>
<p>All of these machines are connected to an IPoverIB <code>InfiniBand</code> network with private IPs.</p>
<p>This cluster is meant to be serving multiple computing/storage use cases, for example for</p>
<ul>
<li>Current experiments at GSI</li>
<li>Future experiments at GSI/FAIR</li>
<li>Individual users at GSI/FAIR</li>
<li>Short-lived or long-lived collaborations with remote institutions</li>
</ul>
<p>There is typically no partitioning of the worker nodes by user/group/experiment. Which means anyone’s computing payload can be executed on any worker node.</p>
<p>In general, the network policy for the cluster machines’ network is:</p>
<ul>
<li>Nothing in</li>
<li>Nothing out</li>
</ul>
</section>
<section id="the-problem" class="level2">
<h2 class="anchored" data-anchor-id="the-problem">The problem</h2>
<p>However, some experiments, such as ALICE at CERN, have, for better or worse, designed their computing workflows in such way that the computing payload requires to connect to the outside world during runtime.</p>
<p>Since the collaboration with ALICE is too important to be subject to the cluster’s network policy, an exception needed to be implemented.</p>
<p>A solution needs to fulfil at least the following requirements</p>
<ul>
<li>The outgoing connections from ALICE computing payloads MUST be permitted</li>
<li>Any outgoing connection from other processes MUST fall into the default routing workflow</li>
<li>Outgoing connections MUST be NATed for internet-routability.</li>
<li>The mechanism MUST be transparent for ALICE as well as for other users of the cluster</li>
<li>The mechanism SHOULD be efficient</li>
<li>The mechanism SHOULD be fault-tolerant</li>
</ul>
</section>
<section id="the-solution" class="level2">
<h2 class="anchored" data-anchor-id="the-solution">The solution</h2>
<p>The following is an extremely simplified illustration of the default network situation around the cluster.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-24-policy-based-routing/alinat_simplified_1.png" class="img-fluid figure-img"></p>
<figcaption>Diagram showing worker nodes connected to a single default gateway router, with a firewall blocking outgoing traffic</figcaption>
</figure>
</div>
<p>There is only one router, and it each worker node has configured it as its <strong>default gateway</strong>.</p>
<p>That router sends the packets it received to its default gateway, heading for the firewall, which drops packets attempting to connect to the outside.</p>
<p>The solution is a mechanism which consists of two parts.</p>
<section id="worker-node-configuration" class="level3">
<h3 class="anchored" data-anchor-id="worker-node-configuration">Worker Node Configuration</h3>
<p>On each worker node</p>
<ul>
<li>The connections made by the ALICE computing payload are <strong>marked</strong> (<code>iptables</code> terminology) by selecting by the <code>UID</code> or <code>GID</code> of the process</li>
<li>The <code>Linux</code> kernel gets instructed to use a different routing table for packets with that specific mark</li>
<li>The special routing table most importantly involves a <strong>different default gateway</strong></li>
</ul>
<p>Specifically, we configure a special routing table:</p>
<p><code>/etc/iproute2/rt_tables</code></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># reserved values</span></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb1-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">255</span> local</span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">254</span> main</span>
<span id="cb1-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">253</span> default</span>
<span id="cb1-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">0</span>   unspec</span>
<span id="cb1-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb1-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># local</span></span>
<span id="cb1-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#</span></span>
<span id="cb1-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#1  inr.ruhep</span></span>
<span id="cb1-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">201</span> alinat</span></code></pre></div></div>
<p>We set the <code>iptables</code> marking mechanism as well as the <code>ip rule</code> mechanism in a <code>systemd</code> unit file.</p>
<p><code>/etc/systemd/system/route.service</code></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode ini code-with-copy"><code class="sourceCode ini"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[Unit]</span></span>
<span id="cb2-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Description</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Routing Configuration</span></span>
<span id="cb2-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Requires</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">network-online.target</span></span>
<span id="cb2-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Wants</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">systemd-networkd-wait-online.service sssd.service</span></span>
<span id="cb2-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">After</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">network-online.target sssd.service</span></span>
<span id="cb2-6"></span>
<span id="cb2-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[Service]</span></span>
<span id="cb2-8"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Type</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">oneshot</span></span>
<span id="cb2-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">RemainAfterExit</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span></span>
<span id="cb2-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner aliprod  -j MARK --set-mark 1</span></span>
<span id="cb2-11"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner alise    -j MARK --set-mark 1</span></span>
<span id="cb2-12"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --gid-owner alice    -j MARK --set-mark 1</span></span>
<span id="cb2-13"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner aliprod  -j MARK --set-mark 1</span></span>
<span id="cb2-14"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner alise    -j MARK --set-mark 1</span></span>
<span id="cb2-15"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/iptables -t mangle -A OUTPUT -p tcp -m owner --gid-owner alice    -j MARK --set-mark 1</span></span>
<span id="cb2-16"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/ip rule del fwmark 1 table alinat</span></span>
<span id="cb2-17"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/ip r flush table alinat</span></span>
<span id="cb2-18"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip rule add fwmark 1 table alinat</span></span>
<span id="cb2-19"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add 10.20.0.0/16 dev ib0 table alinat</span></span>
<span id="cb2-20"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add 10.20.1.0/24 dev ib0 table alinat</span></span>
<span id="cb2-21"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add 10.10.24.0/24 via 10.20.0.1 dev ib0 table alinat</span></span>
<span id="cb2-22"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add 140.181.2.0/24 via 10.20.0.1 dev ib0 table alinat</span></span>
<span id="cb2-23"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add 140.181.60.0/24 via 10.20.0.1 dev ib0 table alinat</span></span>
<span id="cb2-24"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStart</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r add default via 10.20.3.227 dev ib0 table alinat</span></span>
<span id="cb2-25"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStop</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner aliprod  -j MARK --set-mark 1</span></span>
<span id="cb2-26"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStop</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --uid-owner alise    -j MARK --set-mark 1</span></span>
<span id="cb2-27"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStop</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">-/usr/sbin/iptables -t mangle -D OUTPUT -p tcp -m owner --gid-owner alice    -j MARK --set-mark 1</span></span>
<span id="cb2-28"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStop</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip rule del fwmark 1 table alinat</span></span>
<span id="cb2-29"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ExecStop</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/usr/sbin/ip r flush table alinat</span></span>
<span id="cb2-30"></span>
<span id="cb2-31"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[Install]</span></span>
<span id="cb2-32"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">WantedBy</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">multi-user.target</span></span></code></pre></div></div>
<p>You can see that in the unit file above in the <code>ExecStart</code> lines, we first perform the actions of <code>ExecStop</code> there, but we allow them to fail without letting the unit fail by using <code>systemd</code>’s <code>=-</code> syntax.</p>
<p>Using that trick, the unit file gets the desirable property of <strong>idempotence</strong>, which means it can be executed any number of times and will always achieve the same desired state of the specified items.</p>
<p>Consequently,</p>
<ul>
<li>The unit does not fail it it gets <code>start</code>ed or <code>restart</code>ed while <code>iptables</code> and <code>ip</code> are already configured correctly</li>
<li>In case the configuration of <code>iptables</code> or <code>ip</code> gets changed (for example if a network interface goes down and up again) and the <code>systemd</code> unit does of course not notice it, a <code>restart</code> of the unit will recover the configuration of <code>iptables</code> and <code>ip</code>.</li>
</ul>
</section>
<section id="nat-router-configuration" class="level3">
<h3 class="anchored" data-anchor-id="nat-router-configuration">NAT Router Configuration</h3>
<p>The second part is a machine functioning as a router. Routers <strong>connect networks</strong>, so that machine needs to have at least 2 network interfaces. One in the network with the worker nodes, and one in a network with public IPs. In our case, that network is <code>140.181.2.0/24</code> and we call it <code>brokernetz</code>.</p>
<p>That machine must be configured to act as a router. From a <code>Linux</code> point of view, that means that IP forwarding needs to be enabled. It may be desirable to restrict it to the network interface combinations that you want to allow. In our case, we want to allow forwarding between the <code>IPoverIB</code> network on interface <code>ib0</code> and the 10GbE interface <code>eth9</code>.</p>
<p>Specifically, we configure IP forwarding:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[root@alinat1</span> ~]# cat /etc/sysctl.d/10-alinat.conf </span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">net.ipv4.ip_forward</span> = 1</span></code></pre></div></div>
<p>And use <code>nftables</code> to define between which interfaces we want to route packets.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[root@alinat1</span> ~]# nft list ruleset</span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">table</span> inet table1 {</span>
<span id="cb4-3">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">chain</span> input {</span>
<span id="cb4-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> filter hook input priority filter<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">policy</span> accept<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb4-5">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-6"></span>
<span id="cb4-7">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">chain</span> forward {</span>
<span id="cb4-8">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> filter hook forward priority filter<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">policy</span> drop<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb4-9">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">iifname</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ib0"</span> oifname <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"eth9"</span> accept</span>
<span id="cb4-10">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">iifname</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"eth9"</span> oifname <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ib0"</span> accept</span>
<span id="cb4-11">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-12"></span>
<span id="cb4-13">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">chain</span> output {</span>
<span id="cb4-14">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> filter hook output priority filter<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">policy</span> accept<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb4-15">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-16"><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-17"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">table</span> ip tablenat {</span>
<span id="cb4-18">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">chain</span> postrouting {</span>
<span id="cb4-19">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> nat hook postrouting priority srcnat<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">policy</span> accept<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb4-20">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">oifname</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"eth9"</span> masquerade</span>
<span id="cb4-21">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-22"></span>
<span id="cb4-23">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">chain</span> prerouting {</span>
<span id="cb4-24">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> nat hook prerouting priority dstnat<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">policy</span> accept<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb4-25">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-26"><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>That way we have a special router which routes the packets originating from the ALICE payloads on the cluster headed for the internet.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-24-policy-based-routing/alinat_simplified_2.png" class="img-fluid figure-img"></p>
<figcaption>Diagram showing an additional NAT router handling ALICE traffic alongside the default gateway</figcaption>
</figure>
</div>
<p>For ALICE we have several <code>xrootd</code> data servers which are dual-homed as well. They have an <code>IPoverIB</code> interface to be able to access <code>Lustre</code>, as well as a 10GbE interface in the <code>brokernetz</code> to be reachable from the Internet.</p>
<p>That happens to be just the network configuration of our NAT router.</p>
<p>To increase fault tolerance, we configured each of them to be a NAT router as well. However, only at most one of them is active at a given time. Under normal circumstances, that means exactly one machine plays the role of the NAT router.</p>
<p>For that we use <code>keepalived</code>. It is a daemon that utilizes the Virtual Router Redundancy Protocol (VRRP).</p>
<p>We configure <code>keepalived</code> on each of these machines to define a <code>virtual router</code> (<code>keepalived</code> terminology) with exactly one “virtual” IP address. Each <code>keepalived</code> daemon gets configured to have a specific priority. They then communicate with one another and figure out which one of the alive daemons has the highest priority. The one with the highest priority will claim the virtual IP, which is the IP configured on all worker nodes on the cluster.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-24-policy-based-routing/alinat_simplified_3.png" class="img-fluid figure-img"></p>
<figcaption>Diagram showing multiple redundant NAT routers managed by keepalived, sharing a virtual IP</figcaption>
</figure>
</div>
<p>That way, even when the primary NAT router fails, the machine with the at that point in time highest priority will take over.</p>
<p>Any of the NAT routers can be rebooted or otherwise taken offline without resulting in any unavailability of the NAT mechanism as long as at least one of them is still operational.</p>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>This setup has proven to have an excellent specificity and sensitivity, which is to say there have not been any observed false positives or false negatives w.r.t. which packets get routed to our NAT router vs the normal default gateway.</p>
<p>Secondly, it is extremely efficient. Even when saturating the 10GbE link there is hardly any noticable CPU usage on the NAT router.</p>
<p>Also, it is reliable and probably the most fault-tolerant component in our ALICE setup.</p>
<p>There is slight operational room for improvement on the worker node side. In case the <code>InfiniBand</code> network goes down and up again, the IP address disappears and all routes with it. Currently we do not automatically recover from that fault, but we detect it and manually need to restart <code>route.service</code>. This could theoretically be further automated.</p>


<!-- -->

</section>

 ]]></description>
  <category>Network</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2023-11-24-policy-based-routing/</guid>
  <pubDate>Thu, 23 Nov 2023 23:00:00 GMT</pubDate>
</item>
<item>
  <title>The ALICE Analysis Facility at GSI</title>
  <dc:creator>Raffaele Grosso</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2023-11-15-AF-at-GSI/</link>
  <description><![CDATA[ 






<section id="the-context" class="level2">
<h2 class="anchored" data-anchor-id="the-context">The context</h2>
<p>High Energy Physics experiments at big accelerators require to search for special signals in a “haystack” of background noise. The whole of the RAW data (data read out from the detectors’ electronics) is firstly processed by complex algorithms in order to be interpreted as tracks of primary particles or of their decay products and the actual physics analysis later consists on applying clever cuts for selecting interesting candidates, for example combinations of two tracks, in the whole track background, for example in the huge combinatorial background of all track pairs of a collision event (proton-proton, lead-lead, proton-ion, …). For the results to be significant the search has to be carried over a huge amount of collisions, which is the reason why accelerators are challenged to provide an always higher rate of collisions and the computing infrastructure is challenged to be capable to process always bigger volumes of data per unit of time.</p>
<p>To efficiently store and process such huge amount of data, computing resources distributed worldwide have been organized in a hierarchy of sites playing different roles according to the computing model of the pertaining experiment with the aim of finding the best trade-off between centralization and distribution of resources to minimize data storage and data processing costs.</p>
<p>Moving from Run 2 to Run 3 (started in summer 2023) the ALICE experiment <sup>1</sup> at the CERN LHC is facing the challenge of processing a raw data throughput from the detector bigger than 1.1 TB/s, twenty times bigger then in Run 2, due to the increased luminosity – a way to measure the collision rate per cross section unit – provided by the accelerator and to the continuous readout, that is to taking data without a trigger upstream of the detector. The peak data rate of 1.1 TB/s is reached in lead-lead collisions at 50 kHz interaction rate. This is the setting for big changes in the ALICE computing model for Run 3, based on the necessity to maximize the compression of the data volume read out from the detectors synchronously with data taking, that is performing a first calibration and reconstruction pass online in order to drastically reduce the the amount of data to be stored (down to 50 GB/s).</p>
</section>
<section id="the-gsi-contribution-to-alice-computing-in-run-3" class="level2">
<h2 class="anchored" data-anchor-id="the-gsi-contribution-to-alice-computing-in-run-3">The GSI contribution to ALICE computing in Run 3</h2>
<p>GSI is one of the ALICE Grid sites and provides computing and storage resources (several PB and several thousands cores) to the ALICE experiment. The amount and mode of integration of these resources in the global framework of the experiment results from the computing requirements <sup>2</sup> and is reviewed on a yearly bases to account for the current needs and possibilities. As anticipated above the data throughput from the detector has drastically increased from Run 2 to Run 3 leading to big changes in the ALICE data processing model in particular to anticipate as much as possible the calibration and reconstruction just after the read out, before storing and archiving the data. This has also implied a reorganization of the role played by the Grid sites, in particular to minimize the displacement of data and to maximize the proximity of computing jobs to their input data. In Run 2 the GSI site has been a <strong>Tier 2</strong> in the ALICE Grid, meaning a site at the second level in the Grid hierarchy, where the first level – <strong>Tier 1</strong> – includes some big computing facilities (GridKA in the case of Germany) and the upper level – <strong>Tier 0</strong> – are the central facilities very closed to the detector itself. As a Tier 2 site GSI resources have been used in the context of the Run 2 computing model for central simulations, central analysis and user analysis jobs. In the data processing of Run 3 the role of the different sites is more specialized and GSI becomes an <strong>Analysis Facility</strong> (<strong>AF</strong>), whose focus is in being able to process a large amount of data in a short time (up to 5 PB in 12 hours, or equivalently 100 GB/s) providing fast analysis validation an cut tuning.</p>
</section>
<section id="how-are-gsi-resources-integrated-in-the-alice-grid" class="level2">
<h2 class="anchored" data-anchor-id="how-are-gsi-resources-integrated-in-the-alice-grid">How are GSI resources integrated in the ALICE Grid</h2>
<p>As the other big High Energy Physics experiments at the LHC, ALICE generates data volumes whose storage and processing require to be distributed on many sites. The ALICE Grid middleware <strong>JAliEn</strong> <sup>3</sup> allows to represent world-wide spread resources under a single interface transparently to the user, who sees a single namespace for files and a single resource manager for computing jobs. For this to happen each Grid site maintains dedicated services and servers which make the storage and computing resources at the site (<strong>Storage Element</strong> and <strong>Computing Element</strong>) centrally accessible.</p>
<section id="local-and-global-storage" class="level3">
<h3 class="anchored" data-anchor-id="local-and-global-storage">Local and global storage</h3>
<p>The following analogy can help to visualize the software stack: a file system local to a machine represents bits on the storage device as logical entities (files) occupying a place in a logical structure (file tree). Similarly, one level above, a parallel file system manages data distributed on several storage devices transparently presenting to the user a single global namespace. Similarly, and as the next level of abstraction, a Grid file system reads and writes data to Storage Elements distributed world wide presenting the underlying files under a single global namespace to the user, who does not need to be aware of anything about the physical location of files. This upper level of abstraction is based on centrally maintained databases which map the files’ name and logical position in the global namespace, the <strong>Logical File Name</strong> (LFN), to the files’ name at the underlying, the <strong>Physical File Name</strong>s (PFN) of one or more replicas at one or more Storage Elements corresponding to that LFN. It is also based on local services at each SE to “bridge” the local distributed file system to the central services. User queries for LFNs translate into remote queries to replicas at GSI and are served by locally maintained XRootD <sup>4</sup> redirectors and data servers which in turn query the local parallel file system Lustre <sup>5</sup>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-15-AF-at-GSI/ALICEnamespace.svg" title="Title: Files in the global namespace" class="img-fluid figure-img"></p>
<figcaption>Global namespace for ALICE files</figcaption>
</figure>
</div>
</section>
<section id="local-and-global-jobs" class="level3">
<h3 class="anchored" data-anchor-id="local-and-global-jobs">Local and global jobs</h3>
<p>With respect to jobs and compute resources another similar analogy holds: a job scheduler in the operating system of a machine allocates resources (RAM and CPU) to many different processes organized in prioritized queues. One level above a resource manager does the same with jobs submitted by users on the resources of a cluster. And, one level above, the Grid services of the experiment queue, distribute and monitor jobs submitted by users who don’t need to know on which CPUs at which site their job has run.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-15-AF-at-GSI/ALICErm.svg" title="Title: ALICE jobs' queue" class="img-fluid figure-img"></p>
<figcaption>ALICE jobs queue</figcaption>
</figure>
</div>
<p>This additional level of abstraction requires of course some services to communicate requests and availability between the global ALICE Grid instance and the single computing sites. It also requires users to submit jobs via a small file describing in a standardized way the job’s needs, as for example input files to be processed, required packages, single or multi core execution, required memory, expected time to live. The central services interact with servers at the sites called <strong>VoBox</strong>es which in turn spawn ALICE <strong>jobagent</strong>s on the local workload manager, in the form of Slurm <sup>6</sup> jobs in our case. Finally the job agents communicate with the central services in particular to pull ALICE jobs.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hpc.gsi.de/virgo/blog/posts/2023-11-15-AF-at-GSI/VoBox.svg" title="Title: Simplified view of the VoBox" class="img-fluid figure-img"></p>
<figcaption>VoBox and job submission</figcaption>
</figure>
</div>
<p>The detailed and more precise workflow of how AliEn jobs are run on worker nodes is detailed in the second part of <a href="https://indico.cern.ch/event/877541/contributions/3697557/attachments/1967641/4324980/T1T2_2022.pdf">this presentation</a><sup>7</sup>. One can see that actually the <code>JobAgent</code> is launched by a <code>JobRunner</code> to account for multicore execution. The JobAgent in turn launches a <code>JobWrapper</code> which finally executes the actual AliEn job. The main duty of the JobAgent is to ask the Task Queue for a matching job and launch <em>in a container</em> if possible a JobWrapper according to the “payload” (job ID, JDL and job token) received from the central services. If you are still not lost in the many layers of abstraction presented up to now, it is worth mentioning that the startup script executed on the WN is encrypted and embedded in the <code>slurm-submit script</code> received by the VoBox and submitted to Slurm. Here it is modified before being sent in order to accommodate it to the network configuration specific to our cluster by unsetting the proxy-related environment variables.</p>
</section>
</section>
<section id="some-technical-challenges-and-our-solutions" class="level2">
<h2 class="anchored" data-anchor-id="some-technical-challenges-and-our-solutions">Some technical challenges and our solutions</h2>
<p>The aim of the middleware is to link local resources and central services transparently for the users and painlessly for the local and central admins. Nevertheless we had some issues to be solved, mostly related to the peculiarity of providing resources on shared, non-dedicated systems (our storage instance of Lustre and our cluster Virgo). Hereafter we mention a couple of these issues and describe how we solved them.</p>
<section id="the-vobox-is-not-in-the-cluster" class="level3">
<h3 class="anchored" data-anchor-id="the-vobox-is-not-in-the-cluster">The VoBox is not in the cluster</h3>
<p>An assumption of the experiment’s middleware is that the VoBox is internal to the cluster and in particular that it runs on a machine where the Slurm client is installed. The VoBox however runs services which require to be accessible from the Internet, which is not the case for the GSI cluster’s network. Therefore the VoBoxes of the GSI site run on a machines outside of the cluster’s network on which the Slurm client is not installed. The Slurm commands issued by the VoBox (<code>squeue</code>, <code>sbatch</code>, …) must be somehow sent to a node which is instead able to query the Slurm servers. Our solution is to “wrap” these commands in a corresponding executable which prepends them with an ssh to a submit node of the cluster. These executables are located in <code>/usr/local/bin</code> so that they are found in the <code>$PATH</code> and as first instances.</p>
</section>
<section id="remaining-space-on-lustre" class="level3">
<h3 class="anchored" data-anchor-id="remaining-space-on-lustre">Remaining space on Lustre</h3>
<p>The space for the ALICE SE at GSI is made available on the local shared storage of Lustre and reserved by means of its <em>quota</em> administration tools (<code>lfs setquota</code>). However the assumption of the middleware is to query the space on a dedicated storage. To overcome this problem an XRootD plug-in was implemented and is installed, which overwrites the XRootD implementation of space usage queries with queries to the Lustre quota API. In this way the available space on Lustre is checked correctly accounting for the quota reserved to ALICE.</p>
</section>
<section id="the-worker-nodes-are-firewalled" class="level3">
<h3 class="anchored" data-anchor-id="the-worker-nodes-are-firewalled">The worker nodes are firewalled</h3>
<p>ALICE jobs running on the worker nodes need to access the Internet to communicate with the central services and to get files from remote storage elements. This queries however would be blocked by the firewall. Therefore this outgoing traffic has to be redirected bypassing the firewall. Our solution is to make use of policy based routing and natting as described in one of the next blog contributions.</p>
</section>
<section id="optimize-file-access-at-the-local-storage-element" class="level3">
<h3 class="anchored" data-anchor-id="optimize-file-access-at-the-local-storage-element">Optimize file access at the local Storage Element</h3>
<p>Access to the local storage resources by jobs on the Grid is provided by local services and in particular by the <strong>XRootD redirectors</strong> and <strong>data servers</strong>. When a read or write query from a client for a file located at Storage Element at GSI reaches the redirector, it queries in turn the data servers, it gets back possibly the reply by at least one of them and forwards the data server’s address to the client. The client can then communicate directly with the data server which get the file from the underlying storage (Lustre) to ship it to the client. In this data flow there is room for improvement when the client and the SE storing the file are at the same site. This important optimization has been implemented in an XRootD plug-in as described in another blog contribution.</p>


<!-- -->

</section>
</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>The ALICE Experiment at the LHC<br>
<a href="https://home.web.cern.ch/science/experiments/alice" class="uri">https://home.web.cern.ch/science/experiments/alice</a>↩︎</p></li>
<li id="fn2"><p>ALICE upgrades during the LHC Long Shutdown 2<br>
<a href="https://arxiv.org/pdf/2302.01238.pdf#subsubsection.5.4.3" class="uri">https://arxiv.org/pdf/2302.01238.pdf#subsubsection.5.4.3</a>↩︎</p></li>
<li id="fn3"><p>JAliEn<br>
<a href="https://jalien.docs.cern.ch/" class="uri">https://jalien.docs.cern.ch/</a>↩︎</p></li>
<li id="fn4"><p>XRootD<br>
<a href="https://xrootd.slac.stanford.edu/" class="uri">https://xrootd.slac.stanford.edu/</a>↩︎</p></li>
<li id="fn5"><p>The Lustre file system<br>
<a href="https://www.lustre.org/" class="uri">https://www.lustre.org/</a>↩︎</p></li>
<li id="fn6"><p>Slurm overview <a href="https://slurm.schedmd.com/overview.html" class="uri">https://slurm.schedmd.com/overview.html</a>↩︎</p></li>
<li id="fn7"><p>JAliEn job execution workflow <a href="https://indico.cern.ch/event/877541/contributions/3697557/attachments/1967641/4324980/T1T2_2022.pdf" class="uri">https://indico.cern.ch/event/877541/contributions/3697557/attachments/1967641/4324980/T1T2_2022.pdf</a>↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Container</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2023-11-15-AF-at-GSI/</guid>
  <pubDate>Tue, 14 Nov 2023 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Plasma PIC with Apptainer Containers</title>
  <dc:creator>Denis Bertini</dc:creator>
  <dc:creator>Victor Penso</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2023-11-14-pp-containers/</link>
  <description><![CDATA[ 






<section id="software-stack" class="level2">
<h2 class="anchored" data-anchor-id="software-stack">Software Stack</h2>
<p>Container images are all built with RockyLinux 8.8 <sup>1</sup> in alignment with the host platform of the compute cluster. Each container image provides a self-consistent environment to perform PIC simulation using either EPOCH <sup>2</sup> or WarpX <sup>3</sup>. The environments have been tested and validated for full speed InfiniBand interconnect communication and Lustre file-system optimised MPI I/O. Containers provide the latest versions the PIC codes and dependencies, which includes:</p>
<ul>
<li>Linux RockyLinux 8.8 with Lustre Client v2.15.3 <sup>4</sup></li>
<li>OpenMPI v5.0.0 <sup>5</sup>, PMix v4.2.7 <sup>6</sup>, UCX v1.15.0 <sup>7</sup></li>
<li>I/O Libraries HDF5 v1.14 <sup>8</sup> and ADIOS2 v2.9.1 <sup>9</sup></li>
<li>EPOCH v4.19.0 <sup>10</sup> and WarpX v23.10 <sup>11</sup></li>
<li>Python v3.6.8 with scientific packages (Numpy , Matplotlib, etc.) and SDFUtils bindings for EPOCH</li>
</ul>
<p>All Apptainer container definition files <sup>12</sup> are available to users in a GitLab repository in sub-directory <code>defs/</code>. Use the definition files to build the containers and provide feedback using GitLab issues:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Repository</th>
<th>URL</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>pp-containers</td>
<td><a href="https://git.gsi.de/d.bertini/pp-containers" class="uri">https://git.gsi.de/d.bertini/pp-containers</a></td>
</tr>
</tbody>
</table>
</section>
<section id="container-images" class="level2">
<h2 class="anchored" data-anchor-id="container-images">Container Images</h2>
<p>Ready to use container images are provided to the cluster on <a href="../../../user-guide/storage/cvmfs.html">CVMFS</a> in the directory <code>/cvmfs/phelix.gsi.de/sifs/</code>. The latest images are stored in the development <code>dev/</code> sub-directory for validation from the user community. After validation, images are moved to the production <code>prod/</code> sub-directory, replacing the previous versions preserved for reference in the <code>old/</code> sub-directory. The directory structure looks similar to the following example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> tree <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/cvmfs/phelix.gsi.de/sifs</span></span>
<span id="cb1-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb1-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> cpu</span>
<span id="cb1-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> ├── dev</span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> │&nbsp;&nbsp; ├── rlx8_ompi5_ucx_cma.sif</span>
<span id="cb1-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> │&nbsp;&nbsp; ├── rlx8_ompi5_ucx_dask.sif</span>
<span id="cb1-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> │&nbsp;&nbsp; ├── rlx8_ompi5_ucx_gcc13_cma.sif</span>
<span id="cb1-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> │&nbsp;&nbsp; ├── rlx8_ompi5_ucx_gcc13.sif</span>
<span id="cb1-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> │&nbsp;&nbsp; └── rlx8_ompi5_ucx.sif</span>
<span id="cb1-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> ├── old</span>
<span id="cb1-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> └── prod</span>
<span id="cb1-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span>     ├── rlx8_ompi_ucx_gcc12.sif</span>
<span id="cb1-13"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span>     └── rlx8_ompi_ucx.sif</span>
<span id="cb1-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> gpu</span>
<span id="cb1-15">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> dev</span>
<span id="cb1-16">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│&nbsp;&nbsp;</span> └── rlx8_rocm-5.7.1_warpx.sif</span>
<span id="cb1-17">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> old</span>
<span id="cb1-18">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> prod</span>
<span id="cb1-19">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> rlx8_rocm-5.4.6.def</span>
<span id="cb1-20">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> rlx8_rocm-5.4.6.sif</span>
<span id="cb1-21">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> rlx8_rocm-5.4.6_warpx.def</span>
<span id="cb1-22">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> rlx8_rocm-5.4.6_warpx.sif</span>
<span id="cb1-23">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> ubuntu-20.04_rocm-5.4.2_picongpu.def</span>
<span id="cb1-24">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> ubuntu-20.04_rocm-5.4.2_picongpu.sif</span>
<span id="cb1-25">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> ubuntu-20.04_rocm-5.4.2_warpx.def</span>
<span id="cb1-26">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> ubuntu-20.04_rocm-5.4.2_warpx.sif</span></code></pre></div></div>
<p>The file names for container image reflect the base Linux distribution, and compiler and library versions. For example RockyLinus 8 with the default compiler GCC 8.5:</p>
<ul>
<li><code>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx.sif</code></li>
<li><code>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_cma.sif</code></li>
<li><code>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_dask.sif</code></li>
</ul>
<p>Similar but with a recent GCC 13.2:</p>
<ul>
<li><code>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_gcc13.sif</code></li>
<li><code>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_gcc13_cma.sif</code></li>
</ul>
</section>
<section id="getting-started" class="level2">
<h2 class="anchored" data-anchor-id="getting-started">Getting Started</h2>
<p>In order to use a container image of your choice, login to the (non-VAE) cluster <a href="../../../user-guide/containers/run-time.html#submit-node">submit nodes</a>. These nodes grant access to the <a href="../../../user-guide/containers/environment.html">bare-metal environment</a> enabling users to launch custom container instance:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...login to a (bare-metal) submit node</span></span>
<span id="cb2-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ssh</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span>@virgo.hpc.gsi.de</span>
<span id="cb2-3"></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...selecting a RockyLinux 8 container with GCC 8.5.0</span></span>
<span id="cb2-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx.sif</span>
<span id="cb2-6"></span>
<span id="cb2-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...bind storage directories to the container</span></span>
<span id="cb2-8"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_BINDPATH</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>/,/cvmfs</span>
<span id="cb2-9"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">OMPI_MCA_io</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>romio341</span>
<span id="cb2-10"></span>
<span id="cb2-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...run an application within a container instance</span></span>
<span id="cb2-12"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">srun</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--export</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ALL <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span> epoch3d</span></code></pre></div></div>
<section id="mpi-communication" class="level3">
<h3 class="anchored" data-anchor-id="mpi-communication">MPI Communication</h3>
<p>The cluster utilizes Apptainer as container engine in <code>non-setuid</code> mode <sup>13</sup> by default. Using <code>non-setuid</code> mode offers several advantages. It enables unprivileged users to build their own containers without requiring any configurations from system administrators. In <code>non-setuid</code> mode, each processes spawned by MPI runs in a dedicated user-namespace which prevent any intra-node optimizations (for example POSIX shared memory or cross memory attach).</p>
<p>A possible workaround is to use a container as service approach <sup>14</sup> to run a single container instance per node. All MPI processes “join” this instances sharing one user-namespace. Following example illustrates how to adapt a typical EPOCH submit script in order to use a single Apptainer instances per node. Launch of the application is build with two scripts. The batch script <code>run-file-cma.sh</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/bin/bash</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">srun</span>  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--export</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ALL  ./epoch3d.sh</span></code></pre></div></div>
<p>A second script <code>epoch3d.sh</code> first checks if a container instance already exist on the node, otherwise it starts an instance. All consecutive MPI processes created on the node will then “join” the same container instance before execution:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/bin/bash</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_cma.sif</span>
<span id="cb4-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONFIGDIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$USER</span>/apptainer </span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">OMP_NUM_THREADS</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>1</span>
<span id="cb4-7"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">OMPI_MCA_io</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>romio341</span>
<span id="cb4-8"></span>
<span id="cb4-9"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">EPOCH_EXE</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>epoch3d</span>
<span id="cb4-10"></span>
<span id="cb4-11"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">nb_instances</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">flock</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> /tmp apptainer instance list <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wc</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span></span>
<span id="cb4-12"></span>
<span id="cb4-13"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">[</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$nb_instances</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">-eq</span> 1 <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb4-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb4-15">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Instance already created:  join ..."</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$nb_instances</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURMD_NODENAME</span>  </span>
<span id="cb4-16">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> exec instance://<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$EPOCH_EXE</span> </span>
<span id="cb4-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb4-18">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> instance list <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">wc</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span></span>
<span id="cb4-19">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Instance not created:  create it ..."</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$nb_instances</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURMD_NODENAME</span></span>
<span id="cb4-20">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">flock</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-o</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> /tmp <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb4-21">              apptainer instance start  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /lustre <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /cvmfs <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span></span>
<span id="cb4-22">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> exec instance://<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SLURM_JOB_ID</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$EPOCH_EXE</span></span>
<span id="cb4-23"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fi</span></span></code></pre></div></div>
<p>The scripts above are available in the <a href="https://git.gsi.de/d.bertini/pp-containers/-/tree/main/scripts/cma"><code>scripts/cma/</code></a> sub-directory of the pp-container repository. Note that race conditions when querying for a container instance are prevented by requiring an advisory lock via the Linux <code>flock</code> command.</p>
</section>
<section id="interactive-usage" class="level3">
<h3 class="anchored" data-anchor-id="interactive-usage">Interactive Usage</h3>
<p>Once you data is produced you can do analysis using the same containerized environment since it also provide the necessary python libraries:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> apptainer <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> /cvmfs/phelix.gsi.de/sifs/cpu/rlx8_ompi_ucx.sif bash <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span>  </span>
<span id="cb5-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Centos</span> system profile loaded ...</span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Apptainer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> python3 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--version</span></span>
<span id="cb5-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Python</span> 3.6.8</span>
<span id="cb5-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Apptainer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> python3</span>
<span id="cb5-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Python</span> 3.6.8 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default,</span> Feb 21 2023, 16:57:46<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> </span>
<span id="cb5-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[GCC</span> 8.5.0 20210514 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Red</span> Hat 8.5.0-16<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">]</span> on linux</span>
<span id="cb5-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Type</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"help"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"copyright"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"credits"</span> or <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"license"</span> for more information.</span>
<span id="cb5-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> import <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">numpy</span></span>
<span id="cb5-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> import <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">matplotlib</span></span>
<span id="cb5-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> import <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">sdf</span></span>
<span id="cb5-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">...</span></span></code></pre></div></div>
</section>
</section>
<section id="gpu-containers" class="level2">
<h2 class="anchored" data-anchor-id="gpu-containers">GPU Containers</h2>
<p>A dedicated container images provides the latest WarpX 23.11 used with the cluster <code>gpu</code> <a href="../../../user-guide/cluster/partitions.html">partition</a>. The image is built on top of the standard RockyLinux container adding latest Radeon Open Compute (ROCm) <sup>15</sup> from AMD. The image has been tested on the AMD MI 100 GPUs available on the <code>gpu</code> partition. The <a href="https://git.gsi.de/d.bertini/pp-containers/-/tree/main/gpu_scripts"><code>gpu_scripts/</code></a> sub-directory in the pp-container repository provides example batch scripts to launch a batch job on GPUS:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/bin/bash</span></span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Define container image and working directory</span></span>
<span id="cb6-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">CONT</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/cvmfs/phelix.gsi.de/sifs/gpu/dev/rlx8_rocm-5.7.1_warpx.sif</span>
<span id="cb6-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">WDIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>/gpu/warpx</span>
<span id="cb6-6"></span>
<span id="cb6-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Define I/O module for openMPI </span></span>
<span id="cb6-8"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">OMPI_MCA_io</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>romio341</span>
<span id="cb6-9"></span>
<span id="cb6-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Definie apptainer external filesystems bindings </span></span>
<span id="cb6-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_BINDPATH</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>/,/cvmfs</span>
<span id="cb6-12"></span>
<span id="cb6-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Executable with dimentionality and corresponding input deck file.</span></span>
<span id="cb6-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">srun</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--export</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ALL <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$CONT</span> warpx_2d  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$WDIR</span>/scripts/inputs/warpx_opmd_deck</span></code></pre></div></div>
</section>
<section id="install-software" class="level2">
<h2 class="anchored" data-anchor-id="install-software">Install Software</h2>
<p>Install additional packages and software using the provided container images as foundation. Build software within a container environment by stating a container instance for an infective session. The <code>apptainer&gt;</code> prompt indicates the containerized environment. Load your Bash profile by running the <code>bash</code> command (note that your home-directory is automatically mounted to the container):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...set an environment variable with the path for the container image to use</span></span>
<span id="cb7-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_cma.sif</span>
<span id="cb7-3"></span>
<span id="cb7-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...start the container mounting shared storage (if required)</span></span>
<span id="cb7-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> exec <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /lustre <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /cvmfs bash <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span></span>
<span id="cb7-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Apptainer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> </span>
<span id="cb7-7"></span>
<span id="cb7-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...load your Bash profile</span></span>
<span id="cb7-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Apptainer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> bash</span>
<span id="cb7-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>@lxbk1130 /lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>]$</span></code></pre></div></div>
<p>You can check for example which version are available within the environment:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> g++ <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">--version</span></span>
<span id="cb8-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">g++</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">GCC</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">8.5.0</span> 20210514 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Red</span> Hat 8.5.0-18<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb8-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Copyright</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">C</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2018</span> Free Software Foundation, Inc.</span>
<span id="cb8-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">This</span> is free software<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">see</span> the source for copying conditions.  There is NO</span>
<span id="cb8-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">warranty</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">not</span> even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span>
<span id="cb8-6"></span>
<span id="cb8-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> ompi_info <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> ucx</span>
<span id="cb8-8">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Configure</span> command line: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--prefix=/usr/local'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-pmix=/usr/local'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-libevent=/usr'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-ompi-pmix-rte'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-orte=no'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--disable-oshmem'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--enable-mpirun-prefix-by-default'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--enable-shared'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--without-verbs'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-hwloc'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-ucx=/usr/local/ucx'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-lustre'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-slurm'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--enable-mca-no-build=btl-uct'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--with-cma=no'</span></span>
<span id="cb8-9">                 <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">MCA</span> osc: ucx <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">MCA</span> v2.1.0, API v3.0.0, Component v5.0.0<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb8-10">                 <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">MCA</span> pml: ucx <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">MCA</span> v2.1.0, API v2.1.0, Component v5.0.0<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>Installation additional software to Lustre <a href="../../../user-guide/storage.html#shared-storage">shared storage</a> and use it with a batch script similar to:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_CONTAINER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/cvmfs/phelix.gsi.de/sifs/cpu/dev/rlx8_ompi5_ucx_cma.sif</span>
<span id="cb9-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APPTAINER_BINDPATH</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>/,/cvmfs</span>
<span id="cb9-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">SLURM_WORKING_DIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>/lustre/rz/<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>/warpx</span>
<span id="cb9-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">OMPI_MCA_io</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>romio321</span>
<span id="cb9-5"></span>
<span id="cb9-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">srun</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--export</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ALL <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb9-7">      <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--</span> apptainer exec <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /lustre <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-B</span> /cvmfs <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$APPTAINER_CONTAINER</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb9-8">      <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$my_executable</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$options</span></span></code></pre></div></div>


<!-- -->

</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>RockyLinux 8.8 Release<br>
<a href="https://rockylinux.org/news/rocky-linux-8-8-ga-release" class="uri">https://rockylinux.org/news/rocky-linux-8-8-ga-release</a>↩︎</p></li>
<li id="fn2"><p>EPOCH, GitHub<br>
<a href="https://github.com/Warwick-Plasma/epoch" class="uri">https://github.com/Warwick-Plasma/epoch</a>↩︎</p></li>
<li id="fn3"><p>WarpX, GitHub<br>
<a href="https://github.com/ECP-WarpX/WarpX" class="uri">https://github.com/ECP-WarpX/WarpX</a>↩︎</p></li>
<li id="fn4"><p>Lustre Client for Enterprise Linux 8.8, Whamcloud<br>
<a href="http://downloads.whamcloud.com/public/lustre/lustre-2.15.3/el8.8/client" class="uri">http://downloads.whamcloud.com/public/lustre/lustre-2.15.3/el8.8/client</a>↩︎</p></li>
<li id="fn5"><p>OpenMPI v5, OpenMPI Project<br>
<a href="https://www.open-mpi.org/software/ompi/v5.0" class="uri">https://www.open-mpi.org/software/ompi/v5.0</a>↩︎</p></li>
<li id="fn6"><p>OpenPMIx, GitHub<br>
<a href="https://github.com/openpmix/openpmix" class="uri">https://github.com/openpmix/openpmix</a>↩︎</p></li>
<li id="fn7"><p>UCX, GitHub<br>
<a href="https://github.com/openucx/ucx" class="uri">https://github.com/openucx/ucx</a>↩︎</p></li>
<li id="fn8"><p>HDF5 Library, The HDF Group<br>
<a href="https://www.hdfgroup.org/solutions/hdf5/" class="uri">https://www.hdfgroup.org/solutions/hdf5/</a>↩︎</p></li>
<li id="fn9"><p>ADIOS2, GitHub<br>
<a href="https://github.com/ornladios/ADIOS2" class="uri">https://github.com/ornladios/ADIOS2</a>↩︎</p></li>
<li id="fn10"><p>EPOCH v4.19.0, GitHub<br>
<a href="https://github.com/Warwick-Plasma/epoch/releases/tag/v4.19.0" class="uri">https://github.com/Warwick-Plasma/epoch/releases/tag/v4.19.0</a>↩︎</p></li>
<li id="fn11"><p>WarpX Development Branch, GitHub<br>
<a href="https://github.com/ECP-WarpX/WarpX/tree/development" class="uri">https://github.com/ECP-WarpX/WarpX/tree/development</a>↩︎</p></li>
<li id="fn12"><p>Definition Files, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/definition_files.html" class="uri">https://apptainer.org/docs/user/main/definition_files.html</a>↩︎</p></li>
<li id="fn13"><p>Security in Apptainer, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/main/security.html" class="uri">https://apptainer.org/docs/user/main/security.html</a>↩︎</p></li>
<li id="fn14"><p>Running Services, Apptainer User Guide<br>
<a href="https://apptainer.org/docs/user/1.0/running_services.html" class="uri">https://apptainer.org/docs/user/1.0/running_services.html</a>↩︎</p></li>
<li id="fn15"><p>AMD ROCm™ platform, GitHub<br>
<a href="https://github.com/RadeonOpenCompute/ROCm" class="uri">https://github.com/RadeonOpenCompute/ROCm</a>↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Container</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2023-11-14-pp-containers/</guid>
  <pubDate>Mon, 13 Nov 2023 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Using Python on the Compute Cluster</title>
  <dc:creator>Matteo Dessalvi</dc:creator>
  <dc:creator>Victor Penso</dc:creator>
  <link>https://hpc.gsi.de/virgo/blog/posts/2023-11-06-how-to-python/</link>
  <description><![CDATA[ 






<p>This article describes three options for users to configure a custom Python environment to be used with the compute cluster. These options are:</p>
<ol type="1">
<li>Use of an Apptainer <sup>1</sup> Container</li>
<li>Use of Conda-Forge <sup>2</sup></li>
<li>Use of a Python Virtual Environment</li>
</ol>
<p>Using a containerized Python is recommended if no dependencies other then the Python interpreter and its related ecosystem are required. Note that <a href="../../../user-guide/containers/run-time.html">custom containers</a> do not provide any software available from the <a href="../../../user-guide/overview/software.html#vae">virtual application environments</a>. In case users are interested in more details then described in this article, we recommend corresponding material from HPC Carpentry for Python <sup>3</sup> and the Python HPC Community <sup>4</sup>.</p>
<section id="apptainer-container" class="level2">
<h2 class="anchored" data-anchor-id="apptainer-container">Apptainer Container</h2>
<p>Depending on the target hardware different container images are recommended:</p>
<ul>
<li>For <strong>CPU workloads</strong> JupyterLab <sup>5</sup> containers are the best choice in terms of options available, e.g.&nbsp;frameworks like TensorFlow, Scipy, Spark or languages like Julia or R. Please refer to the official documentation <sup>6</sup> in order to see which container may be better suited for your application.</li>
<li>For <strong>GPU workloads</strong> it is preferable to use container images provided by either the AMD Infinity Hub <sup>7</sup> or the NVIDIA Registry <sup>8</sup> for the respective hardware.</li>
</ul>
<p>A simple array example which uses NumPy:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/usr/bin/env python</span></span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-4"></span>
<span id="cb1-5">array <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.array([</span>
<span id="cb1-6">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>],</span>
<span id="cb1-7">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>],</span>
<span id="cb1-8">    [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]</span>
<span id="cb1-9">])</span>
<span id="cb1-10"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(array)</span>
<span id="cb1-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>()</span>
<span id="cb1-12"></span>
<span id="cb1-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sort the whole array</span></span>
<span id="cb1-14"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(np.sort(array, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>))</span>
<span id="cb1-15"></span>
<span id="cb1-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sort along each row</span></span>
<span id="cb1-17"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(np.sort(array, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb1-18"></span>
<span id="cb1-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sort along each column</span></span>
<span id="cb1-20"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(np.sort(array, axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>))</span></code></pre></div></div>
<p>Pull the JupyterLab <code>data-science</code> container from Docker Hub:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> pull docker://jupyter/datascience-notebook:latest</span></code></pre></div></div>
<p>Test the container <strong>interactively</strong> with the previous script:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">apptainer</span> exec datascience-notebook.sif numpy_array.py</span></code></pre></div></div>
<p>Refer to the <a href="../../../user-guide/containers/execution.html">container section</a> in the Virgo User Guide for instructions on how to submit an container as batch job on the compute cluster.</p>
</section>
<section id="conda-forge" class="level2">
<h2 class="anchored" data-anchor-id="conda-forge">Conda-Forge</h2>
<p>Alternative to a container it is possible to install a standalone Python installation using Conda-Forge, a community-driven installer for Python. Note that Anaconda and Miniconda should not be used on the cluster infrastructure due its licence!</p>
<div class="callout callout-style-default callout-important callout-titled" title="Anaconda Inc. Licence Terms of Service">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Important</span>Anaconda Inc.&nbsp;Licence Terms of Service
</div>
</div>
<div class="callout-body-container callout-body">
<p>In the end of 2020 Anaconda Inc.&nbsp;updated its licence terms of service <sup>9</sup>. The change is targeted primarily thwarts commercial companies. Despite being a scientific institute GSI is not qualified for a non-commercial license unfortunately. As a consequence to that:</p>
<p><strong>Use of the default Anaconda package channels is not allowed!</strong></p>
<p>The terms of service change does not apply to Conda-Forge, nor to other channels hosted on <code>anaconda.org</code> <sup>10</sup>. It applies only to the default channel and other software hosted on <code>repo.anaconda.com</code> <sup>11</sup>. We kindly ask and strongly recommend to use Conda-Forge for your Python based projects.</p>
</div>
</div>
<section id="installation" class="level3">
<h3 class="anchored" data-anchor-id="installation">Installation</h3>
<p>Download the latest version of Miniforge <sup>12</sup> and perform the installation, as exemplified below. If a prefix is not specified with the <code>APP_DIR</code> environment variable, then Miniforge will be installed in your home-directory by default:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Download the installer...</span></span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-OL</span> https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh</span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...set a prefix environment variable</span></span>
<span id="cb4-5"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">APP_DIR</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"~/opt/conda"</span></span>
<span id="cb4-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...run the install passing the prefix as option</span></span>
<span id="cb4-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/bin/sh</span> Miniforge3-Linux-x86_64.sh <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-b</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${APP_DIR}</span></span>
<span id="cb4-8"></span>
<span id="cb4-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...load the installation into your shell environment</span></span>
<span id="cb4-10"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">source</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${APP_DIR}</span>/etc/profile.d/conda.sh</span></code></pre></div></div>
<p>The <code>source</code> command will add the <code>conda</code> executable to the <code>$PATH</code> environment variable. Use <code>conda</code> command to manage the environment…</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...modifies your shell prompt and show (base) as prefix</span></span>
<span id="cb5-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> activate</span>
<span id="cb5-3"></span>
<span id="cb5-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...print information about Conda</span></span>
<span id="cb5-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> info</span>
<span id="cb5-6"></span>
<span id="cb5-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...remove Conda from your shell environment</span></span>
<span id="cb5-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> deactivate</span></code></pre></div></div>
</section>
<section id="usage" class="level3">
<h3 class="anchored" data-anchor-id="usage">Usage</h3>
<p>Search and install Python packages…</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...search for packages</span></span>
<span id="cb6-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> search <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$package_name</span></span>
<span id="cb6-3"></span>
<span id="cb6-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...install a package with a specified version...</span></span>
<span id="cb6-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> install pytorch=2.0.0=cpu_py39he4d1dc0_0</span></code></pre></div></div>
<p>Work with environments…</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># create a new environment with basic options</span></span>
<span id="cb7-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> create <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$env_name</span></span>
<span id="cb7-3"></span>
<span id="cb7-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># switch to the newly created environment</span></span>
<span id="cb7-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> activate <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$env_name</span></span>
<span id="cb7-6"></span>
<span id="cb7-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># install packages within the environment</span></span>
<span id="cb7-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> install <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$package_name</span></span>
<span id="cb7-9"></span>
<span id="cb7-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># list installed packages</span></span>
<span id="cb7-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> list</span>
<span id="cb7-12"></span>
<span id="cb7-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># remove an environment</span></span>
<span id="cb7-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">conda</span> env remove <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$env_name</span></span></code></pre></div></div>
</section>
</section>
<section id="virtual-environments" class="level2">
<h2 class="anchored" data-anchor-id="virtual-environments">Virtual Environments</h2>
<p>Python virtual environments are useful if you do not want to maintain a complete Python installation yourself, but rather a small subset of Python packages. The <a href="../../../user-guide/overview/software.html#vae">virtual application environments</a> provide Python as loadable <a href="../../../user-guide/overview/software.html#spack">Spack package</a>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Load the Python interpreter...</span></span>
<span id="cb8-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">spack</span> load python target=<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">spack</span> arch <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-t</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-3"></span>
<span id="cb8-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ...and create a virtual environment</span></span>
<span id="cb8-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">python</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-m</span> venv myEnv</span></code></pre></div></div>
<ul>
<li>Initialize the environment: <code>source venv/bin/activate</code> (the environment can be deactivated simply with: <code>deactivate</code>)</li>
<li>Installation of additional modules can be done simply with <code>pip install</code>.</li>
</ul>
<p>Note that the installation directory (if not specified otherwise) will always be <code>$HOME/myEnv</code>, so your Linux home directory (<code>/u/$USER</code>) will be used as default installation path which poses a problem when a job is launched via Slurm since the home directory is <strong>not available</strong> on the batch farm.</p>
<p>If you decide to use a directory on Lustre to deploy Python virtual environments, we will kindly ask you to avoid having dozens of “big” frameworks installed (e.g.&nbsp;TensorFlow, PyTorch, etc.) at the same time. This would affects the performance of the shared storage for all users. Please read the Lustre <a href="../../../user-guide/storage/lustre.html#best-practices">best practices</a> section in the User Guide for more details. Consider to use containers as described above instead.</p>


<!-- -->

</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Apptainer Website<br>
<a href="https://apptainer.org/" class="uri">https://apptainer.org/</a>↩︎</p></li>
<li id="fn2"><p>Conda Forge Website<br>
<a href="https://conda-forge.org" class="uri">https://conda-forge.org</a>↩︎</p></li>
<li id="fn3"><p>HPC Carpentry for Python<br>
<a href="https://www.hpc-carpentry.org/hpc-python" class="uri">https://www.hpc-carpentry.org/hpc-python</a>↩︎</p></li>
<li id="fn4"><p>Python for HPC: Community Materials<br>
<a href="https://betterscientificsoftware.github.io/python-for-hpc/python-for-hpc" class="uri">https://betterscientificsoftware.github.io/python-for-hpc/python-for-hpc</a>↩︎</p></li>
<li id="fn5"><p>JupyterLab Docker Stack, Github<br>
<a href="https://github.com/jupyter/docker-stacks" class="uri">https://github.com/jupyter/docker-stacks</a>↩︎</p></li>
<li id="fn6"><p>Selecting an Image, JupyterLab Docker Stack Documentation<br>
<a href="https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html" class="uri">https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html</a>↩︎</p></li>
<li id="fn7"><p>AMD Infinity Hub<br>
<a href="https://www.amd.com/en/technologies/infinity-hub" class="uri">https://www.amd.com/en/technologies/infinity-hub</a>↩︎</p></li>
<li id="fn8"><p>NVIDIA Container Registry<br>
<a href="https://catalog.ngc.nvidia.com/collections" class="uri">https://catalog.ngc.nvidia.com/collections</a>↩︎</p></li>
<li id="fn9"><p>Package Distribution and the anaconda.com Terms of Service, Conda-Forge Blog<br>
<a href="https://conda-forge.org/blog/posts/2020-11-20-anaconda-tos" class="uri">https://conda-forge.org/blog/posts/2020-11-20-anaconda-tos</a>↩︎</p></li>
<li id="fn10"><p>Anaconda Inc.&nbsp;Website<br>
<a href="https://anaconda.org" class="uri">https://anaconda.org</a>↩︎</p></li>
<li id="fn11"><p>Anaconda Packages, Anaconda Inc.<br>
<a href="https://repo.anaconda.com" class="uri">https://repo.anaconda.com</a>↩︎</p></li>
<li id="fn12"><p>Miniforge, GitHub<br>
<a href="https://github.com/conda-forge/miniforge" class="uri">https://github.com/conda-forge/miniforge</a>↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Container</category>
  <guid>https://hpc.gsi.de/virgo/blog/posts/2023-11-06-how-to-python/</guid>
  <pubDate>Thu, 12 Oct 2023 22:00:00 GMT</pubDate>
</item>
</channel>
</rss>
