<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Documentation – Notebooks</title><link>/providers/notebooks/</link><description>Recent content in Notebooks on Documentation</description><generator>Hugo -- gohugo.io</generator><atom:link href="/providers/notebooks/index.xml" rel="self" type="application/rss+xml"/><item><title>Providers: Architecture</title><link>/providers/notebooks/architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/providers/notebooks/architecture/</guid><description>
&lt;p>The EGI Notebooks service relies on the following technologies to provide its
functionality:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/jupyterhub/jupyterhub">JupyterHub&lt;/a> with custom
&lt;a href="https://github.com/enolfc/oauthenticator">EGI Check-in oauthentication&lt;/a>
configured to spawn pods on Kubernetes.&lt;/li>
&lt;li>&lt;a href="https://kubernetes.io/">Kubernetes&lt;/a> as container orchestration platform
running on top of EGI Cloud resources. Within the service it is in charge of
managing the allocated resources and providing the right abstraction to deploy
the containers that build the service. Resources are provided by EGI Federated
Cloud providers, including persistent storage for users notebooks.&lt;/li>
&lt;li>CA authority to allocate recognised certificates for the HTTPS server&lt;/li>
&lt;li>&lt;a href="https://prometheus.io/">Prometheus&lt;/a> for monitoring resource consumption.&lt;/li>
&lt;li>Specific EGI hooks for
&lt;a href="https://github.com/EGI-Federation/egi-notebooks-monitoring">monitoring&lt;/a>,
&lt;a href="https://github.com/EGI-Federation/egi-notebooks-accounting">accounting&lt;/a> and
&lt;a href="https://github.com/EGI-Federation/egi-notebooks-backup">backup&lt;/a>.&lt;/li>
&lt;li>VO-Specific storage/Big data facilities or any pluggable tools into the
notebooks environment can be added to community specific instances.&lt;/li>
&lt;/ul>
&lt;h2 id="kubernetes">Kubernetes&lt;/h2>
&lt;p>A Kubernetes (k8s) cluster deployed into a resource provider is in charge of
managing the containers that will provide the service. On this cluster there
are:&lt;/p>
&lt;ul>
&lt;li>1 master node that manages the whole cluster&lt;/li>
&lt;li>Support for load balancer or alternatively 1 or more edge nodes with a public
IP and corresponding public DNS name (e.g. notebooks.egi.eu) where a k8s
ingress HTTP reverse proxy redirects requests from user to other components of
the service. The HTTP server has a valid certificate from one CA recognised at
most browsers (e.g. Let's Encrypt).&lt;/li>
&lt;li>1 or more nodes that host the JupyterHub server, the notebooks servers where
the users will run their notebooks. Hub is deployed using the
&lt;a href="https://jupyterhub.github.io/helm-chart/">JupyterHub helm charts&lt;/a>. These
nodes should have enough capacity to run as many concurrent user notebooks as
needed. Main constraint is usually memory.&lt;/li>
&lt;li>Support for
&lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/">Kubernetes PersistentVolumeClaims&lt;/a>
for storing the persistent folders. Default EGI-Notebooks installation uses
NFS, but any other volume type with ReadWriteOnce capabilities can be used.&lt;/li>
&lt;li>Prometheus installation to monitor the usage of resources so accounting
records are generated.&lt;/li>
&lt;/ul>
&lt;p>All communication with the user goes via HTTPS and the service only needs a
publicly accessible entry point (public IP with resolvable name)&lt;/p>
&lt;p>Monitoring and accounting are provided by hooking into the respective monitoring
and accounting EGI services.&lt;/p>
&lt;p>There are no specific hardware requirements and the whole environment can run on
commodity virtual machines.&lt;/p>
&lt;h2 id="egi-customisations">EGI Customisations&lt;/h2>
&lt;p>EGI Notebooks is deployed as a set of customisations of the
&lt;a href="https://jupyterhub.github.io/helm-chart/">JupyterHub helm charts&lt;/a>.&lt;/p>
&lt;p>&lt;img src="egi_notebooks_architecture.png" alt="image">&lt;/p>
&lt;h3 id="authentication">Authentication&lt;/h3>
&lt;p>EGI Check-in can be easily configured as a OAuth2.0 provider for
&lt;a href="https://github.com/jupyterhub/oauthenticator">JupyterHub's oauthenticator&lt;/a>.
See below a sample configuration for the helm chart using Check-in production
environment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">hub&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">extraEnv&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OAUTH2_AUTHORIZE_URL&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">https://aai.egi.eu/auth/realms/egi/protocol/openid-connect/auth&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OAUTH2_TOKEN_URL&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">https://aai.egi.eu/auth/realms/egi/protocol/openid-connect/token&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">OAUTH_CALLBACK_URL&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">https://&amp;lt;your host&amp;gt;/hub/oauth_callback&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">auth&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">custom&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">custom&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">className&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">oauthenticator.generic.GenericOAuthenticator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">config&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">login_service&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;EGI Check-in&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_id&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your client id&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_secret&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your client secret&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">oauth_callback_url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;https://&amp;lt;your host&amp;gt;/hub/oauth_callback&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">username_key&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;sub&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">token_url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;https://aai.egi.eu/auth/realms/egi/protocol/openid-connect/token&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">userdata_url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;https://aai.egi.eu/auth/realms/egi/protocol/openid-connect/userinfo&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;openid&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;profile&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;email&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;eduperson_scoped_affiliation&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;eduperson_entitlement&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To simplify the configuration and to add refresh capabilities to the
credentials, we have created a new
&lt;a href="https://github.com/enolfc/oauthenticator">EGI Check-in authenticator&lt;/a> that can
be configured as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">auth&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">state&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enabled&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">cryptoKey&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;some unique crypto key&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">custom&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">custom&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">className&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">oauthenticator.egicheckin.EGICheckinAuthenticator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">config&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_id&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your client id&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_secret&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your client secret&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">oauth_callback_url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;https://&amp;lt;your host&amp;gt;/hub/oauth_callback&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">openid&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">profile&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">email&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">offline_access&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">eduperson_scoped_affiliation&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">eduperson_entitlement&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>auth.state&lt;/code> configuration allows to store refresh tokens for the users that
will allow to get up-to-date valid credentials as needed.&lt;/p>
&lt;h3 id="accounting">Accounting&lt;/h3>
&lt;div class="alert alert-warning" role="alert">
&lt;h4 class="alert-heading">Warning&lt;/h4>
This is Work in progress, expect changes!
&lt;/div>
&lt;p>&lt;a href="https://github.com/EGI-Federation/egi-notebooks-accounting">Accounting module&lt;/a>
generates VM-like accounting records for each of the notebooks started at the
service. It's available as a
&lt;a href="https://EGI-Federation.github.io/egi-notebooks-chart/">helm chart&lt;/a> that can be
deployed in the same namespace as the JupyterHub chart. The only needed
configuration for the chart is an IGTF-recognised certificate for the host
registered in GOCDB as accounting.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">ssm&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">hostcert&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">|-&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> &lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;hostcert&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">hostkey&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">|-&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> &lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;hostkey&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="monitoring">Monitoring&lt;/h3>
&lt;p>&lt;a href="https://github.com/EGI-Federation/egi-notebooks-monitoring">Monitoring&lt;/a> is
performed by trying to execute a user notebook every hour. This is accomplished
by registering a new service in the hub that has admin permissions. Monitoring
is then deployed as a
&lt;a href="https://EGI-Federation.github.io/egi-notebooks-chart/">helm chart&lt;/a> that must be
deployed in the same namespace as the JupyterHub chart. Configuration of
JupyterHub must include this section:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">hub&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">services&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">status&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;http://status-web/&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">admin&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">apiToken&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;a unique API token&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Likewise the monitoring chart is configured as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">service&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">api_token&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;same API token as above&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docker-images">Docker images&lt;/h3>
&lt;p>Our service relies on custom images for the hub and the single-user notebooks.
Dockerfiles are available at
&lt;a href="https://github.com/EGI-Federation/egi-notebooks-images">EGI Notebooks images&lt;/a>
git repository and automatically build for every commit pushed to the repository to
&lt;a href="https://hub.docker.com/u/eginotebooks">eginotebooks @ dockerhub&lt;/a>.&lt;/p>
&lt;h4 id="hub-image">Hub image&lt;/h4>
&lt;p>Builds from the
&lt;a href="https://hub.docker.com/r/jupyterhub/k8s-hub">JupyterHub k8s-hub image&lt;/a> and
adds:&lt;/p>
&lt;ul>
&lt;li>EGI and D4Science authenticators&lt;/li>
&lt;li>EGISpawner&lt;/li>
&lt;li>EGI look and feel for the login page&lt;/li>
&lt;/ul>
&lt;h4 id="single-user-image">Single-user image&lt;/h4>
&lt;p>Builds from
&lt;a href="https://hub.docker.com/r/jupyter/datascience-notebook">Jupyter datasicence-notebook&lt;/a>
and adds a wide range of libraries as requested by users of the services. We are
currently looking into alternatives for better managing this image with CVMFS as
a possible solution.&lt;/p>
&lt;h3 id="sample-helm-configuration">Sample helm configuration&lt;/h3>
&lt;p>If you want to build your own EGI Notebooks instance, you can start from the
following sample configuration and adapt to your needs by setting:&lt;/p>
&lt;ul>
&lt;li>secret tokens (for &lt;code>proxy.secretToken&lt;/code>, &lt;code>hub.services.status.api_token&lt;/code>,
&lt;code>auth.state.cryptoKey&lt;/code>). They can be generated with &lt;code>openssl rand -hex 32&lt;/code>.&lt;/li>
&lt;li>A valid hostname (&lt;code>&amp;lt;your notebooks host&amp;gt;&lt;/code> below) that resolves to your
Kubernetes Ingress&lt;/li>
&lt;li>Valid EGI Check-in client credentials, these can be obtained by creating a new
Service for the demo instance of Check-in through the
&lt;a href="https://aai.egi.eu/federation">EGI Federation Registry&lt;/a>. When moving to EGI
Check-in production environment, make sure to remove the
&lt;code>hub.extraEnv.EGICHECKIN_HOST&lt;/code> variable.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">---&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">proxy&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">secretToken&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;some secret&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">service&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">NodePort&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ingress&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enabled&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">annotations&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kubernetes.io/tls-acme&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;true&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">hosts&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">&amp;lt;your notebooks host&amp;gt;]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">tls&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">hosts&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">&amp;lt;your notebooks host&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">secretName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">acme-tls-notebooks&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enabled&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">hosts&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">&amp;lt;your notebooks host&amp;gt;]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">singleuser&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">storage&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">capacity&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">1Gi&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">dynamic&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">pvcNameTemplate&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">claim-{userid}{servername}&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">volumeNameTemplate&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">vol-{userid}{servername}&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">storageAccessModes&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;ReadWriteMany&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">memory&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">limit&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">1G&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">guarantee&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">512M&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">cpu&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">limit&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">2&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">guarantee&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">.02&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">defaultUrl&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;/lab&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">image&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">eginotebooks/single-user&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">tag&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">c1b2a2a&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">hub&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">image&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">eginotebooks/hub&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">tag&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">c1b2a2a&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">extraConfig&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enable-lab&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">|-&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> &lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">c.KubeSpawner.cmd = [&amp;#39;jupyter-labhub&amp;#39;]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">volume-handling&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">|-&lt;/span>&lt;span style="color:#8f5902;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> from egispawner.spawner import EGISpawner
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"> c.JupyterHub.spawner_class = EGISpawner&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">extraEnv&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">JUPYTER_ENABLE_LAB&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">EGICHECKIN_HOST&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">aai-demo.egi.eu&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">services&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">status&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;http://status-web/&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">admin&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">api_token&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;monitor token&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">auth&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">custom&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">state&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enabled&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">cryptoKey&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;a unique crypto key&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">admin&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">access&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">users&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000;font-weight:bold">[&lt;/span>&lt;span style="color:#000">&amp;lt;list of EGI Check-in users with admin powers&amp;gt;]&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">custom&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">className&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">oauthenticator.egicheckin.EGICheckinAuthenticator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">config&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_id&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your egi checkin_client_id&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">client_secret&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;lt;your egi checkin_client_secret&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">oauth_callback_url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;https://&amp;lt;your notebooks host&amp;gt;/hub/oauth_callback&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">enable_auth_state&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">openid&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">profile&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">email&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">offline_access&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">eduperson_scoped_affiliation&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">eduperson_entitlement&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Providers: Service Operations</title><link>/providers/notebooks/operations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/providers/notebooks/operations/</guid><description>
&lt;p>In this section you can find the common operational activities related to keep
the service available to our users.&lt;/p>
&lt;h2 id="initial-set-up">Initial set-up&lt;/h2>
&lt;h3 id="notebooks-vo">Notebooks VO&lt;/h3>
&lt;p>The resources used for the Notebooks deployments are managed with the
&lt;a href="https://operations-portal.egi.eu/vo/view/voname/vo.notebooks.egi.eu">&lt;code>vo.notebooks.egi.eu&lt;/code> VO&lt;/a>.
Operators of the service should join the VO with the &lt;code>admin&lt;/code> role.&lt;/p>
&lt;h3 id="clients-installation">Clients installation&lt;/h3>
&lt;p>In order to manage the resources you will need these tools installed on your
client machine:&lt;/p>
&lt;ul>
&lt;li>&lt;code>fedcloudclient&lt;/code> for discovering sites and managing tokens,&lt;/li>
&lt;li>&lt;code>terraform&lt;/code> to create the VMs at the providers,&lt;/li>
&lt;li>&lt;code>ansible&lt;/code> to configure the VMs and install kubernetes at the providers,&lt;/li>
&lt;li>&lt;code>terraform-inventory&lt;/code> to get the list of hosts to use from terraform.&lt;/li>
&lt;/ul>
&lt;h3 id="get-the-configuration-repository">Get the configuration repository&lt;/h3>
&lt;p>All the configuration of the notebooks is stored at a git repository available
in GitHub.
Start by cloning the repo:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>git clone https://github.com/EGI-Federation/notebooks-operations
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="kubernetes">Kubernetes&lt;/h2>
&lt;p>We use &lt;code>terraform&lt;/code> and &lt;code>ansible&lt;/code> to build the cluster at one of the EGI Cloud
providers. If you are building the cluster for the first time, create a new
directory on your local git repository from the template, add it to the repo,
and get &lt;code>terraform&lt;/code> ready:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cp -a template &amp;lt;new provider&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git add &amp;lt;new provider&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87">cd&lt;/span> &amp;lt;new provider&amp;gt;/terraform
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>terraform init
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Using the &lt;code>fedcloud&lt;/code> you can get set the right environment for interacting with
the OpenStack APIs of a given site:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87">eval&lt;/span> &lt;span style="color:#4e9a06">&amp;#34;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">$(&lt;/span>fedcloud site show-project-id --site CESGA --vo vo.notebooks.egi.eu&lt;span style="color:#204a87;font-weight:bold">)&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Whenever you need to get a valid token for the site and VO, you can obtain it with:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">OS_TOKEN&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#204a87;font-weight:bold">$(&lt;/span>fedcloud openstack --site CESGA --vo vo.notebooks.egi.eu &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> token issue -c id -f value&lt;span style="color:#204a87;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>First get the network IDs and pool to use for the site:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ fedcloud openstack --site CESGA --vo vo.notebooks.egi.eu network list
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+-------------------------+--------------------------------------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> ID &lt;span style="color:#000;font-weight:bold">|&lt;/span> Name &lt;span style="color:#000;font-weight:bold">|&lt;/span> Subnets &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+-------------------------+--------------------------------------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 1aaf20b6-47a1-47ef-972e-7b36872f678f &lt;span style="color:#000;font-weight:bold">|&lt;/span> net-vo.notebooks.egi.eu &lt;span style="color:#000;font-weight:bold">|&lt;/span> 6465a327-c261-4391-a0f5-d503cc2d43d3 &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 6174db12-932f-4ee3-bb3e-7a0ca070d8f2 &lt;span style="color:#000;font-weight:bold">|&lt;/span> public00 &lt;span style="color:#000;font-weight:bold">|&lt;/span> 6af8c4f3-8e2e-405d-adea-c0b374c5bd99 &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+-------------------------+--------------------------------------+
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this case we will use &lt;code>public00&lt;/code> as the pool for public IPs and
&lt;code>1aaf20b6-47a1-47ef-972e-7b36872f678f&lt;/code> as the network ID. Check with the
provider which is the right network to use. Use these values in the
&lt;code>terraform.tfvars&lt;/code> file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-terraform" data-lang="terraform">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#c4a000">ip_pool&lt;/span> = &lt;span style="color:#4e9a06">&amp;#34;public00&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#c4a000">net_id&lt;/span> = &lt;span style="color:#4e9a06">&amp;#34;1aaf20b6-47a1-47ef-972e-7b36872f678f&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You may want to check the right flavors for your VMs and adapt other variables
in &lt;code>terraform.tfvars&lt;/code>. To get a list of flavors you can use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ fedcloud openstack --site CESGA --vo vo.notebooks.egi.eu flavor list
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+----------------+-------+------+-----------+-------+-----------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> ID &lt;span style="color:#000;font-weight:bold">|&lt;/span> Name &lt;span style="color:#000;font-weight:bold">|&lt;/span> RAM &lt;span style="color:#000;font-weight:bold">|&lt;/span> Disk &lt;span style="color:#000;font-weight:bold">|&lt;/span> Ephemeral &lt;span style="color:#000;font-weight:bold">|&lt;/span> VCPUs &lt;span style="color:#000;font-weight:bold">|&lt;/span> Is Public &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+----------------+-------+------+-----------+-------+-----------+
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 26d14547-96f2-4751-a686-f89a9f7cd9cc &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor4mem8hd40 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">8192&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">40&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">4&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 42eb9c81-e556-4b63-bc19-4c9fb735e344 &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor2mem2hd20 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2048&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">20&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 4787d9fc-3923-4fc9-b770-30966fc3baee &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor4mem4hd40 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">4096&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">40&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">4&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 58586b06-7b9d-47af-b9d0-e16d49497d09 &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor24mem62hd60 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">63488&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">60&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">24&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 635c739a-692f-4890-b8fd-d50963bff00e &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor1mem1hd10 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1024&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">10&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 6ba0080d-d71c-4aff-b6f9-b5a9484097f8 &lt;span style="color:#000;font-weight:bold">|&lt;/span> small &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">512&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 6e514065-9013-4ce1-908a-0dcc173125e4 &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor2mem4hd20 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">4096&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">20&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> 85f66ce6-0b66-4889-a0bf-df8dc23ee540 &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor1mem2hd10 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2048&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">10&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> c4aa496b-4684-4a86-bd7f-3a67c04b1fa6 &lt;span style="color:#000;font-weight:bold">|&lt;/span> cor24mem50hd50 &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">51200&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">50&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">24&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">|&lt;/span> edac68c3-50ea-42c2-ae1d-76b8beb306b5 &lt;span style="color:#000;font-weight:bold">|&lt;/span> test-bigHD &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">4096&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">237&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#000;font-weight:bold">|&lt;/span> True &lt;span style="color:#000;font-weight:bold">|&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>+--------------------------------------+----------------+-------+------+-----------+-------+-----------+
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Finally, ensure your public ssh key is also listed in the &lt;code>cloud-init.yaml&lt;/code> file
and then you are ready to deploy the cluster with:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>terraform apply
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Your VMs are up and running, it's time to get kubernetes configured and running
with Ansible.&lt;/p>
&lt;p>The following Ansible role needs to be installed first:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>ansible-galaxy install grycap.kubernetes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and then:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87">cd&lt;/span> .. &lt;span style="color:#8f5902;font-style:italic"># you should be now in &amp;lt;new provider&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>silently &lt;span style="color:#000">TF_STATE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>./terraform &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> ansible-playbook --inventory-file&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#204a87;font-weight:bold">$(&lt;/span>which terraform-inventory&lt;span style="color:#204a87;font-weight:bold">)&lt;/span> &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> playbooks/k8s.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="interacting-with-the-cluster">Interacting with the cluster&lt;/h3>
&lt;p>As the master will be on a private IP, you won't be able to directly interact
with it, but you can still ssh into the VM using the ingress node as a gateway
host (you can get the different hosts with
&lt;code>TF_STATE=./terraform terraform-inventory --inventory&lt;/code>)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ ssh -o &lt;span style="color:#000">ProxyCommand&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -W %h:%p -q egi@&amp;lt;ingress ip&amp;gt;&amp;#34;&lt;/span> &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> -o &lt;span style="color:#000">StrictHostKeyChecking&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>no -o &lt;span style="color:#000">UserKnownHostsFile&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>/dev/null egi@&amp;lt;master ip&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>egi@k8s-master:~$ kubectl get nodes
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME STATUS ROLES AGE VERSION
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>k8s-master Ready master 33m v1.15.7
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>k8s-nfs Ready &amp;lt;none&amp;gt; 16m v1.15.7
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>k8s-w-ingress Ready &amp;lt;none&amp;gt; 16m v1.15.7
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>egi@k8s-master:~$ helm list
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>certs-man &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> Wed Jan &lt;span style="color:#0000cf;font-weight:bold">8&lt;/span> 15:56:58 &lt;span style="color:#0000cf;font-weight:bold">2020&lt;/span> DEPLOYED cert-manager-v0.11.0 v0.11.0 cert-manager
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cluster-ingress &lt;span style="color:#0000cf;font-weight:bold">3&lt;/span> Wed Jan &lt;span style="color:#0000cf;font-weight:bold">8&lt;/span> 15:56:53 &lt;span style="color:#0000cf;font-weight:bold">2020&lt;/span> DEPLOYED nginx-ingress-1.7.0 0.24.1 kube-system
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nfs-provisioner &lt;span style="color:#0000cf;font-weight:bold">3&lt;/span> Wed Jan &lt;span style="color:#0000cf;font-weight:bold">8&lt;/span> 15:56:43 &lt;span style="color:#0000cf;font-weight:bold">2020&lt;/span> DEPLOYED nfs-client-provisioner-1.2.8 3.1.0 kube-system
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="modifyingdestroying-the-cluster">Modifying/Destroying the cluster&lt;/h3>
&lt;p>You should be able to change the number of workers in the cluster and re-apply
terraform to start them and then execute the playbook to get them added to the
cluster.&lt;/p>
&lt;p>Any changes in the master, NFS or ingress VMs should be done carefully as those
will probably break the configuration of the Kubernetes cluster and of any
application running on top.&lt;/p>
&lt;p>Destroying the cluster can be done with a single command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>terraform destroy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="notebooks-deployments">Notebooks deployments&lt;/h2>
&lt;p>Once the k8s cluster is up and running, you can deploy a notebooks instance. For
each deployment you should create a file in the &lt;code>deployments&lt;/code> directory
following the template provided:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cp deployments/hub.yaml.template deployments/hub.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Each deployment will need a domain name pointing to your ingress host, you can
create one at the &lt;a href="https://nsupdate.fedcloud.eu/">FedCloud dynamic DNS service&lt;/a>.&lt;/p>
&lt;p>Then you will need to create an OpenID Connect client for EGI Check-in to
authorise users into the new deployment. You can create a client by going to the
&lt;a href="https://aai.egi.eu/federation">EGI Federation Registry&lt;/a>.
You can find more information about registering an OIDC Client in
&lt;a href="../../check-in/sp/#service-provider-integration-workflow">EGI Check-in guide for SPs&lt;/a>
Use the following as redirect URL:
&lt;code>https://&amp;lt;your host domain name&amp;gt;/hub/oauth_callback&lt;/code>.&lt;/p>
&lt;p>Then add &lt;code>offline_access&lt;/code> to the list of scopes and submit the request. After
the approval of the Service request, save the client and take note of the
client ID and client secret for later.&lt;/p>
&lt;p>Finally, you will also need 3 different random strings generated with
&lt;code>openssl rand -hex 32&lt;/code> that will be used as secrets in the file describing the
deployment.&lt;/p>
&lt;p>Go and edit the deployment description file to add this information (search for
&lt;code># FIXME NEEDS INPUT&lt;/code> in the file to quickly get there)&lt;/p>
&lt;p>For deploying the notebooks instance we will also use &lt;code>ansible&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>silently &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> &lt;span style="color:#000">TF_STATE&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>./terraform ansible-playbook &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --inventory-file&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#204a87;font-weight:bold">$(&lt;/span>which terraform-inventory&lt;span style="color:#204a87;font-weight:bold">)&lt;/span> playbooks/notebooks.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The first deployment trial may fail due to a timeout caused by the downloading
of the container images needed. You can retry after a while to re-deploy.&lt;/p>
&lt;p>In the master you can check the status of your deployment (the name of the
deployment will be the same as the name of your local deployment file):&lt;/p>
&lt;!-- markdownlint-disable line-length -->
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ helm status hub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>LAST DEPLOYED: Thu Jan &lt;span style="color:#0000cf;font-weight:bold">9&lt;/span> 08:14:49 &lt;span style="color:#0000cf;font-weight:bold">2020&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAMESPACE: hub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>STATUS: DEPLOYED
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RESOURCES:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/ServiceAccount
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME SECRETS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> 6m46s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000">3m34s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/Service
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME TYPE CLUSTER-IP EXTERNAL-IP PORT&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>S&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span> AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub ClusterIP 10.100.77.129 &amp;lt;none&amp;gt; 8081/TCP 6m46s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>proxy-public NodePort 10.107.127.44 &amp;lt;none&amp;gt; 443:32083/TCP,80:30581/TCP 6m45s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>proxy-api ClusterIP 10.103.195.6 &amp;lt;none&amp;gt; 8001/TCP &lt;span style="color:#000">6m45s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/ConfigMap
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DATA AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-config &lt;span style="color:#0000cf;font-weight:bold">4&lt;/span> 6m47s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000">3m35s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/PersistentVolumeClaim
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-db-dir Pending managed-nfs-storage &lt;span style="color:#000">6m46s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/ClusterRole
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-user-scheduler-complementary &lt;span style="color:#000">3m34s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/ClusterRoleBinding
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-user-scheduler-base 3m34s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-user-scheduler-complementary &lt;span style="color:#000">3m34s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/RoleBinding
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub &lt;span style="color:#000">6m46s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/Pod&lt;span style="color:#ce5c00;font-weight:bold">(&lt;/span>related&lt;span style="color:#ce5c00;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY STATUS RESTARTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>continuous-image-puller-flf5t 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 3m34s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>continuous-image-puller-scr49 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 3m34s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-569596fc54-vjbms 0/1 Pending &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 3m30s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>proxy-79fb6d57c5-nj8n2 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 2m22s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler-9685d654b-9zt5d 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 3m30s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler-9685d654b-k8v9p 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000">3m30s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/Secret
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME TYPE DATA AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub-secret Opaque &lt;span style="color:#0000cf;font-weight:bold">3&lt;/span> &lt;span style="color:#000">6m47s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/DaemonSet
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>continuous-image-puller &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &amp;lt;none&amp;gt; &lt;span style="color:#000">3m34s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/Deployment
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 6m45s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>proxy &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> 6m45s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">2&lt;/span> &lt;span style="color:#000">3m32s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/StatefulSet
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DESIRED CURRENT AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-placeholder &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> &lt;span style="color:#000">6m44s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1beta1/Ingress
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME HOSTS ADDRESS PORTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>jupyterhub notebooktest.fedcloud-tf.fedcloud.eu 80, &lt;span style="color:#0000cf;font-weight:bold">443&lt;/span> &lt;span style="color:#000">6m44s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1beta1/PodDisruptionBudget
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> N/A &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 6m48s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>proxy &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> N/A &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 6m48s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-placeholder &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> N/A &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 6m48s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>user-scheduler &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> N/A &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#000">6m47s&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ce5c00;font-weight:bold">==&lt;/span>&amp;gt; v1/Role
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>hub 6m46s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NOTES:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Thank you &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> installing JupyterHub!
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Your release is named hub and installed into the namespace hub.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>You can find &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> the hub and proxy is ready by doing:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>kubectl --namespace&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>hub get pod
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>and watching &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> both those pods to be in status &lt;span style="color:#4e9a06">&amp;#39;Running&amp;#39;&lt;/span>.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>You can find the public IP of the JupyterHub by doing:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>kubectl --namespace&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>hub get svc proxy-public
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>It might take a few minutes &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> it to appear!
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Note that this is still an alpha release! If you have questions, feel free to
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>1. Read the guide at https://z2jh.jupyter.org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2. Chat with us at https://gitter.im/jupyterhub/jupyterhub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>3. File issues at https://github.com/jupyterhub/zero-to-jupyterhub-k8s/issues
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-enable line-length -->
&lt;h3 id="updating-a-deployment">Updating a deployment&lt;/h3>
&lt;p>Just edit the deployment description file and run ansible again. The helm will
be upgraded at the cluster.&lt;/p></description></item></channel></rss>