blob: ba5e42b5de8183932ca32fdf04968f6417553e51 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="keywords" content="installationkubernetes, openshift, configuration, admin guide">
<title>Che on OpenShift: Admin Guide | Eclipse Che Documentation</title>
<link rel="stylesheet" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous">
<!--<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">-->
<link rel="stylesheet" href="css/modern-business.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="css/customstyles.css">
<link rel="stylesheet" href="css/boxshadowproperties.css">
<!-- most color styles are extracted out to here -->
<link rel="stylesheet" href="css/theme-che.css">
<link rel="stylesheet" href="/css/coderay.css" media="screen" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js" crossorigin="anonymous"></script>
<script src="js/jquery.navgoco.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- Anchor.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script>
<script src="js/toc.js"></script>
<script src="js/customscripts.js"></script>
<link rel="shortcut icon" href="che/docs/images/favicon.ico">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<link rel="alternate" type="application/rss+xml" title="che" href="http://0.0.0.0:4000/feed.xml">
<script>
$(document).ready(function() {
// Initialize navgoco with default options
$("#mysidebar").navgoco({
caretHtml: '',
accordion: true,
openClass: 'active', // open
save: false, // leave false or nav highlighting doesn't work right
cookie: {
name: 'navgoco',
expires: false,
path: '/'
},
slide: {
duration: 400,
easing: 'swing'
}
});
$("#collapseAll").click(function(e) {
e.preventDefault();
$("#mysidebar").navgoco('toggle', false);
});
$("#expandAll").click(function(e) {
e.preventDefault();
$("#mysidebar").navgoco('toggle', true);
});
});
</script>
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
</script>
<script>
$(document).ready(function() {
$("#tg-sb-link").click(function() {
$("#tg-sb-sidebar").toggle();
$("#tg-sb-content").toggleClass('col-md-9');
$("#tg-sb-content").toggleClass('col-md-12');
$("#tg-sb-icon").toggleClass('fa-toggle-on');
$("#tg-sb-icon").toggleClass('fa-toggle-off');
});
});
</script>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container topnavlinks">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="fa fa-home fa-lg navbar-brand" href="index.html">&nbsp;<span class="projectTitle"> Eclipse Che Documentation</span></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<!-- toggle sidebar button -->
<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>
<!-- entries without drop-downs appear here -->
<li><a href="https://medium.com/eclipse-che-blog/" target="_blank">Blog</a></li>
<li><a href="https://github.com/eclipse/che" target="_blank">Source Code</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Support<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://github.com/eclipse/che/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Akind%2Fbug" target="_blank">Known Bugs</a></li>
<li><a href="https://github.com/eclipse/che/issues/new" target="_blank">File an Issue</a></li>
<li><a href="https://stackoverflow.com/questions/tagged/eclipse-che" target="_blank">Che on StackOverflow</a></li>
</ul>
</li>
<!--
<li>
<a class="email" title="Submit feedback" href="#" onclick="javascript:window.location='mailto:?subject= feedback&body=I have some feedback about the Che on OpenShift: Admin Guide page: ' + window.location.href;"><i class="fa fa-envelope-o"></i> Feedback</a>
</li>
-->
<!--comment out this block if you want to hide search-->
<li>
<!--start search-->
<div id="search-demo-container">
<input type="text" id="search-input" placeholder="search...">
<ul id="results-container"></ul>
</div>
<script src="js/jekyll-search.js" type="text/javascript"></script>
<script type="text/javascript">
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
dataSource: 'search.json',
searchResultTemplate: '<li><a href="{url}" title="Che on OpenShift: Admin Guide">{title}</a></li>',
noResultsText: 'No results found.',
limit: 10,
fuzzy: true,
})
</script>
<!--end search-->
</li>
</ul>
</div>
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<div class="container">
<div id="main">
<!-- Content Row -->
<div class="row">
<!-- Sidebar Column -->
<div class="col-md-3" id="tg-sb-sidebar">
<ul id="mysidebar" class="nav">
<li class="sidebarTitle"> </li>
<li>
<a href="#">Overview</a>
<ul>
<li><a href="index.html">Introduction</a></li>
<li><a href="quick-start.html">Getting Started</a></li>
<li><a href="single-multi-user.html">Single and Multi-User Flavors</a></li>
<li><a href="infra-support.html">Supported Infrastructures</a></li>
</ul>
</li>
<li>
<a href="#">Che on Docker</a>
<ul>
<li><a href="docker-single-user.html">Docker - Single User</a></li>
<li><a href="docker-multi-user.html">Docker - Multi User</a></li>
<li><a href="docker-config.html">Docker - Configuration</a></li>
<li><a href="docker-cli.html">Docker - CLI Reference</a></li>
</ul>
</li>
<li>
<a href="#">Che on Kubernetes</a>
<ul>
<li><a href="kubernetes-single-user.html">Kubernetes - Single User</a></li>
<li><a href="kubernetes-multi-user.html">Kubernetes - Multi User</a></li>
<li><a href="kubernetes-config.html">Kubernetes - Configuration</a></li>
<li><a href="kubernetes-admin-guide.html">Kubernetes - Admin Guide</a></li>
</ul>
</li>
<li>
<a href="#">Che on OpenShift</a>
<ul>
<li><a href="openshift-single-user.html">OpenShift - Single User</a></li>
<li><a href="openshift-multi-user.html">OpenShift - Multi User</a></li>
<li><a href="openshift-config.html">OpenShift - Configuration</a></li>
<li class="active"><a href="openshift-admin-guide.html">OpenShift - Admin Guide</a></li>
</ul>
</li>
<li>
<a href="#">User Management</a>
<ul>
<li><a href="user-management.html">Authentication and Authorization</a></li>
<li><a href="authentication.html">Security Model</a></li>
<li><a href="permissions.html">Permissions</a></li>
<li><a href="organizations.html">Organizations in UD</a></li>
<li><a href="resource-management.html">Resource Management</a></li>
</ul>
</li>
<li>
<a href="#">User Guides</a>
<ul>
<li><a href="creating-starting-workspaces.html">Creating and starting Workspaces</a></li>
<li><a href="ide-projects.html">Projects</a></li>
<li><a href="editor-code-assistance.html">Editor and Code-Assistance</a></li>
<li><a href="dependency-management.html">Dependency Management</a></li>
<li><a href="commands-ide-macro.html">Commands and IDE Macros</a></li>
<li><a href="version-control.html">Version Control</a></li>
<li><a href="debug.html">Debug</a></li>
</ul>
</li>
<li>
<a href="#">Workspace Administration</a>
<ul>
<li><a href="what-are-workspaces.html">Workspace Overview</a></li>
<li><a href="stacks.html">Workspace - Stacks</a></li>
<li><a href="recipes.html">Workspace - Recipes</a></li>
<li><a href="servers.html">Workspace - Servers</a></li>
<li><a href="installers.html">Workspace - Installers</a></li>
<li><a href="volumes.html">Workspace - Volumes Mount</a></li>
<li><a href="env-variables.html">Workspace - Environment Variables</a></li>
<li><a href="projects.html">Workspace - Projects</a></li>
<li><a href="workspaces-troubleshooting.html">Workspace - Troubleshooting</a></li>
<li><a href="workspace-data-model.html">Workspace Data Model</a></li>
</ul>
</li>
<li>
<a href="#">Portable Workspaces</a>
<ul>
<li><a href="chedir-getting-started.html">Chedir - Getting Started</a></li>
<li><a href="why-chedir.html">Chedir - Why Chedir?</a></li>
<li><a href="chedir-installation.html">Chedir - Installation</a></li>
<li><a href="chedir-project-setup.html">Chedir - Project Setup</a></li>
<li><a href="chedir-up-and-down.html">Chedir - Up and Down</a></li>
<li><a href="chefile.html">Chedir - Chefile</a></li>
<li><a href="chedir-ssh.html">Chedir - SSH</a></li>
<li><a href="factories-getting-started.html">Factory - Getting Started</a></li>
<li><a href="creating-factories.html">Factory - Creating</a></li>
<li><a href="factories_json_reference.html">Factory - JSON Reference</a></li>
</ul>
</li>
<li>
<a href="#">Developer Guides</a>
<ul>
<li><a href="framework-overview.html">Overview</a></li>
<li><a href="rest-api.html">SDK - REST API</a></li>
<li><a href="che-in-che-quickstart.html">SDK - Your First Plugin</a></li>
<li><a href="build-reqs.html">SDK - Building Che</a></li>
<li><a href="assemblies.html">SDK - Assemblies</a></li>
<li><a href="logging.html">SDK - Logging</a></li>
<li><a href="ide-extensions-gwt.html">SDK - GWT IDE Extensions</a></li>
<li><a href="server-side-extensions.html">SDK - Server Side Extensions</a></li>
<li><a href="custom-installers.html">SDK - Installers</a></li>
<li><a href="project-types.html">SDK - Project Types</a></li>
<li><a href="language-servers.html">SDK - Language Support</a></li>
<li><a href="parts.html">IDE UI&#58 Parts</a></li>
<li><a href="actions.html">IDE UI&#58 Actions</a></li>
</ul>
</li>
<li>
<a href="#">Dev Essentials</a>
<ul>
<li><a href="guice.html">Dependency Injection</a></li>
<li><a href="dto.html">Transport&#58 DTO</a></li>
<li><a href="json-rpc.html">Communication&#58 JSON-RPC</a></li>
<li><a href="handling-projects-in-plugins.html">Handling Projects in Plugins</a></li>
<li><a href="dao.html">Persistence, DAO</a></li>
<li><a href="properties.html">Properties</a></li>
</ul>
</li>
<li>
<a href="#">Infrastructure and SPI</a>
<ul>
<li><a href="spi_overview.html">Overview</a></li>
<li><a href="spi-implementation.html">Implementation Notes</a></li>
</ul>
</li>
<!-- if you aren't using the accordion, uncomment this block:
<p class="external">
<a href="#" id="collapseAll">Collapse All</a> | <a href="#" id="expandAll">Expand All</a>
</p>
-->
</ul>
<!-- this highlights the active parent class in the navgoco sidebar. this is critical so that the parent expands when you're viewing a page. This must appear below the sidebar code above. Otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.-->
<script>$("li.active").parents('li').toggleClass("active");</script>
</div>
<!-- Content Column -->
<div class="col-md-9" id="tg-sb-content">
<div class="post-header">
<h1 class="post-title-main">Che on OpenShift: Admin Guide</h1>
</div>
<div class="post-content">
<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
<script>
$( document ).ready(function() {
// Handler for .ready() called.
$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2' });
/* this offset helps account for the space taken up by the floating toolbar. */
$('#toc').on('click', 'a', function() {
var target = $(this.getAttribute('href'))
, scroll_target = target.offset().top
$(window).scrollTop(scroll_target - 10);
return false
})
});
</script>
<div id="toc"></div>
<!--
-->
<div class="sect1">
<h2 id="examples">Examples</h2>
<div class="sectionbody">
<div class="paragraph">
<p>All examples use <code>kubectl</code> command. OpenShift admins should use <code>oc</code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="ram">RAM</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>Single User</strong></p>
</div>
<div class="paragraph">
<p>Che server pod consumes up to 1GB RAM. The initial request is 256MB, and server pod rarely consumes more than 800MB. A typical workspace will require 2GB. So, <strong>3GB</strong> is a minimum to try single user Che on OpenShift/Kubernetes.</p>
</div>
<div class="paragraph">
<p><strong>Multi-User</strong></p>
</div>
<div class="paragraph">
<p>Depending on whether or not you deploy Che bundled with Keycloak auth server and Postgres database, RAM requirements for a multi-user Che installation can vary.</p>
</div>
<div class="paragraph">
<p>When deployed with Keycloak and Postgres, your Kubernetes cluster should have <strong>at least 5GB RAM</strong> available - 3GB go to Che deployments:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>~750MB for Che server</p>
</li>
<li>
<p>~1GB for Keycloak</p>
</li>
<li>
<p>~515MB for Postgres)</p>
</li>
<li>
<p>min 2GB should be reserved to run at least one workspace. The total RAM required for running workspaces will grow depending on the size of your workspace runtime(s) and the number of concurrent workspace pods you run.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="resource-allocation-and-quotas">Resource Allocation and Quotas</h2>
<div class="sectionbody">
<div class="paragraph">
<p>All workspace pods are created either in the same namespace with Che itself, a dedicated namespace, or a new namespace is created for every workspace.</p>
</div>
<div class="paragraph">
<p>Therefore, an account where Che pods are created (including workspace pods) should have reasonable quotas for RAM, CPU and storage, otherwise, workspace pods won’t be created.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="who-creates-workspace-objects">Who Creates Workspace Objects?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Eclipse Che currently supports two different configurations: in the single OpenShift project case, workspace objects are created using a service account that can be configured for Che server, whereas in the multi OpenShift project case, workspace objects are created on behalf of each OpenShift user as they use Eclipse Che. As Eclipse Che communicates with the Kubernetes/OpenShift API through the fabric8 client, an authorization token is required.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>In the single project case, the environment variable <code>CHE_OPENSHIFT_SERVICEACCOUNTNAME</code> governs which service account is used to create workspace objects. This service account must be visible to the Che server (i.e. in the same namespace) and have appropriate permissions to create and edit OpenShift resources. This means that if objects are to be created outside of the service accounts bound namespace the service account will require cluster-admin rights, which can be enabled by an admin via the <code>oc</code> CLI:</p>
<div class="listingblock">
<div class="content">
<pre>oc adm policy add-cluster-role-to-user self-provisioner system:serviceaccount:eclipse-che:che
# eclipse-che is Che namespace</pre>
</div>
</div>
</li>
<li>
<p>In the multi project case, Eclipse Che will use individual user’s OpenShift tokens to create resources <strong>on behalf of the currently logged-in user</strong>. Refer to the <a href="openshift-admin-guide.html#create-workspace-objects-in-personal-namespaces">OpenShift Admin Guide</a> for more details about how it works.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The environment variable <code>CHE_INFRA_OPENSHIFT_PROJECT</code> controls the namespace in which workspace objects are created. In the multi-project case, it should be set to <code>NULL</code> to create workspace objects in different namespaces for each user. In the single project case, if the che service accout does not have cluster-admin rights, it should be set to the same project that hosts the Che server. Refer to the <a href="openshift-config.html">OpenShift Configuration Guide</a> for more details on how to configure Che.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="storage-overview">Storage Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Che server, Keycloak and Postgres pods, as well as workspace pods use PVCs that are then bound to PVs with <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes">ReadWriteOnce access mode</a>. Che PVCs are defined in deployment yamls, while <a href="#che-workspaces-storage">workspace PVC</a> access mode and claim size is configurable through Che deployment environment variables.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="che-infrastructure-storage">Che Infrastructure: Storage</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>Che server claims 1GB to store logs and initial workspace stacks. PVC mode is RWO</p>
</li>
<li>
<p>Keycloak needs 2 PVCs, 1Gb each to store logs and Keycloak data</p>
</li>
<li>
<p>Postgres needs one 1GB PVC to store db</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="che-workspaces-storage">Che Workspaces: Storage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As said above, che workspace PVC access type and claim size is configurable, and so is a workspace PVC strategy:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">strategy</th>
<th class="tableblock halign-left valign-top">details</th>
<th class="tableblock halign-left valign-top">pros</th>
<th class="tableblock halign-left valign-top">cons</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>common</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">One PVC for all workspaces, sub-paths pre-created</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">easy to manage and control storage. no need to recycle PVs when pod with pvc is deleted</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ws pods should all be in one namespace</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>unique</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">PVC per workspace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Storage isolation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">An undefined number of PVs is required</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="common-pvc-strategy">Common PVC Strategy</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>How it Works</strong></p>
</div>
<div class="paragraph">
<p>When a common PVC strategy is used, <strong>all workspaces use the same PVC</strong> to store data declared in their volumes (projects and workspace-logs by default and whatever additional <a href="volumes.html">volumes</a> that a user can define.)</p>
</div>
<div class="paragraph">
<p>In case of a common strategy, an PV that is bound to PVC <code>che-claim-workspace</code> will have the following structure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>pv0001
workspaceid1
workspaceid2
workspaceidn
che-logs projects &lt;volume1&gt; &lt;volume2&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>Directory names are self explaining. Other volumes can be anything that a user defines as volumes for workspace machines (volume name == directory name in <code>${PV}/${ws-id}</code>)</p>
</div>
<div class="paragraph">
<p>When a workspace is deleted, a corresponding subdirectory (<code>${ws-id}</code>) is deleted in the PV directory.</p>
</div>
<div class="paragraph">
<p><strong>How to enable common strategy</strong></p>
</div>
<div class="paragraph">
<p>Set <code>CHE_INFRA_KUBERNETES_PVC_STRATEGY</code> to <code>common</code> in dc/che if you have already deployed Che with unique strategy, or pass <code>-p CHE_INFRA_KUBERNETES_PVC_STRATEGY=common</code> to oc new-app command when applying <code>che-server-template.yaml</code>. See: <a href="openshift-multi-user.html">Deploy to OpenShift</a>.</p>
</div>
<div class="paragraph">
<p><strong>What’s CHE_INFRA_KUBERNETES_PVC_PRECREATE__SUBPATHS?</strong></p>
</div>
<div class="paragraph">
<p>Pre 1.6 Kubernetes created subpaths within a PV with invalid permissions, sot hat a user in a running container was unable to write to mounted directories. When <code>CHE_INFRA_KUBERNETES_PVC_PRECREATE__SUBPATHS</code> is <code>true</code>, and a common strategy is used, a special pod is started before workspace pod is schedules, to pre-create subpaths in PV with the right permissions. You don’t need to set it to true if you have Kubernetes 1.6+.</p>
</div>
<div class="paragraph">
<p><strong>Restrictions</strong></p>
</div>
<div class="paragraph">
<p>When a common strategy is used, and a workspace PVC access mode is RWO, only one Kubernetes node can simultaneously use PVC. You’re fine if your Kubernetes/OpenShift cluster has just one node. If there are several nodes, a common strategy can still be used, but in this case, workspace PVC access mode should be RWM, ie multiple nodes should be able to use this PVC simultaneously (in fact, you may sometimes have some luck and all workspaces will be scheduled on the same node). You can change access mode for workspace PVCs by passing environment variable <code>CHE_INFRA_KUBERNETES_PVC_ACCESS_MODE=ReadWriteMany</code> to che deployment either when initially deploying Che or through che deployment update.</p>
</div>
<div class="paragraph">
<p>Another restriction is that only pods in the same namespace can use the same PVC, thus, <code>CHE_INFRA_KUBERNETES_PROJECT</code> env variable should not be empty - it should be either Che server namespace (in this case objects can be created with che SA) or a dedicated namespace (token or username/password need to be used).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="unique-pvc-strategy">Unique PVC Strategy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It is a default PVC strategy, i.e. <code>CHE_INFRA_KUBERNETES_PVC_STRATEGY</code> is set to <code>unique</code>. Every workspace gets its own PVC, which means a workspace PVC is created when a workspace starts for the first time. Workspace PVC is deleted when a corresponding workspace is deleted.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="update">Update</h2>
<div class="sectionbody">
<div class="paragraph">
<p>An update implies updating Che deployment with new image tags. There are multiple ways to update a deployment:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>kubeclt edit dc/che</code> - and just manually change image tag used in the deployment</p>
</li>
<li>
<p>manually in OpenShift web console &gt; deployments &gt; edit yaml &gt; image:tag</p>
</li>
<li>
<p><code>kubectl set image dc/che che=eclipse/che-server:${VERSION} --source=docker</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Config change will trigger a new deployment. In most cases, using older Keycloak and Postgres images is OK, since changes to those are very rare. However, you may update Keycloak and Postgres deployments:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>eclipse/che-keycloak</p>
</li>
<li>
<p>eclipse/che-postgres</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You can get the list of available versions at <a href="https://github.com/eclipse/che/tags">Che GitHub page</a>.</p>
</div>
<div class="paragraph">
<p>Since <code>nightly</code> is the default tag used in Che deployment, and image pull policy is set to Always, triggering a new deployment, will pull a newer image, if available.</p>
</div>
<div class="paragraph">
<p>You can use <strong>IfNotPresent</strong> pull policy (default is Always). Manually edit Che deployment after deployment or add <code>--set cheImagePullPolicy=IfNotPresent</code>.</p>
</div>
<div class="paragraph">
<p>OpenShift admins can pass <code>-p PULL_POLICY=IfNotPresent</code> to <a href="openshift-multi-user.html">Che deployment</a> or manually edit <code>dc/che</code> after deployment.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="scalability">Scalability</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To be able to run more workspaces, <a href="https://kubernetes.io/docs/concepts/architecture/nodes/#management">add more nodes to your Kubernetes cluster</a>. If the system is out of resources, workspace start will fail with an error message returned from Kubernetes (usually it’s <code>no available nodes</code> kind of error).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="gdpr">GDPR</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In case the user wants to delete their data or requested the admininistrator to do that, there is an API method for that purpose:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>curl -X DELETE http://che-server/api/user/{id}</pre>
</div>
</div>
<div class="paragraph">
<p>Use the above command with the user or administrator token.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="debug-mode">Debug Mode</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want Che server to run in a debug mode set the following env in Che deployment to true (false by default):</p>
</div>
<div class="paragraph">
<p><code>CHE_DEBUG_SERVER=true</code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="private-docker-registries">Private Docker Registries</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Refer to <a href="https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/">Kubernetes documentation</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="che-server-logs">Che Server Logs</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When Eclipse Che gets deployed to Kubernetes, a PVC <code>che-data-volume</code> is <a href="https://github.com/eclipse/che/blob/master/deploy/kubernetes/kubectl/che-kubernetes.yaml#L26">created</a> and bound to a PV. Logs are persisted in a PV and can be retrieved in the following ways:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>kubectl get log dc/che</code></p>
</li>
<li>
<p><code>kubectl describe pvc che-data-claim</code>, find PV it is bound to, then <code>oc describe pv $pvName</code>, you will get a local path with logs directory. Be careful with permissions for that directory, since once changed, Che server wont be able to write to a file</p>
</li>
<li>
<p>in Kubernetes web console, eclipse-che namespace, <strong>pods &gt; che-pod &gt; logs</strong>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It is also possible to configure Che master not to store logs, but produce JSON encoded logs to output instead. It may be used to collect logs by systems such as Logstash. To configure JSON logging instead of plain text environment variable <code>CHE_LOGS_APPENDERS_IMPL</code> should have value <code>json</code>. See more at <a href="logging.html">logging docs</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="workspace-logs">Workspace Logs</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Workspace logs are stored in an PV bound to <code>che-claim-workspace</code> PVC. Workspace logs include logs from workspace agent, <a href="what-are-workspaces.html#bootstrapper">bootstrapper</a> and other agents if applicable.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="che-master-states">Che Master States</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There is three possible states of the master - <code>RUNNING</code>, <code>PREPARING_TO_SHUTDOWN</code> and <code>READY_TO_SHUTDOWN</code>. <code>PREPARING_TO_SHUTDOWN</code> state may imply two different behaviors: - When no new workspace startups allowed, and all running workspaces are forcibly stopped; - When no new workspace startups allowed, any workspaces that are currently starting or stopping is allowed to finish that process, and running workspaces doesn’t stopped. This option is possible only for the infrastructures that support workspaces recovery. For those are didn’t, automatic fallback to the shutdown with full workspaces stopping will be performed. Therefore, <code>/api/system/stop</code> API contract changed slightly - now it tries to do the second behavior by default. Full shutdown with workspaces stop can be requested with <code>shutdown=true</code> parameter. When preparation process in finished, <code>READY_TO_SHUTDOWN</code> state will be set which allows to stop current Che master instance.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="che-workspace-termination-grace-period">Che Workspace Termination Grace Period</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Grace termination period of Kubernetes / OpenShift workspace’s pods defaults '0', which allows to terminate pods almost instantly and significantly decrease the time required for stopping a workspace. For increasing grace termination period the following environment variable should be used:</p>
</div>
<div class="paragraph">
<p><code>CHE_INFRA_KUBERNETES_POD_TERMINATION<em>GRACE</em>PERIOD__SEC</code></p>
</div>
<div class="paragraph">
<p><strong>IMPORTANT!</strong></p>
</div>
<div class="paragraph">
<p>If <code>terminationGracePeriodSeconds</code> have been explicitly set in Kubernetes / OpenShift recipe it will not be overridden by the environment variable.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="recreate-update">Recreate Update</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To perform Recreate type update without stopping active workspaces:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Make sure there is full compatibility between new master and old ws agent versions (API etc);</p>
</li>
<li>
<p>Make sure deployment update strategy set to Recreate;</p>
</li>
<li>
<p>Make POST request to the /api/system/stop api to start WS master suspend (means that all new attempts to start workspaces will be refused, and all current starts/stops will be finished). Note that this method requires system admin credentials.</p>
</li>
<li>
<p>Make periodical GET requests to /api/system/state api, until it returns READY_TO_SHUTDOWN state. Also, it may be visually controlled by line "System is ready to shutdown" in the server logs</p>
</li>
<li>
<p>Perform new deploy.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="rolling-update">Rolling Update</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To perform Rolling type update without stopping active workspaces, the following preconditions required:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Make sure deployment update strategy set to Rolling;</p>
</li>
<li>
<p>Make sure there is full API compatibility between new master and old ws agent versions, as well as database compatibility (since it is impossible to use DB migrations on this update mode);</p>
</li>
<li>
<p>Make sure <code>terminationGracePeriodSeconds</code> deployment parameter has enough value (see details below).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>After that preconditions is done, press Deploy button or execute <code>oc rollout latest che</code> from cli client will start the process.</p>
</div>
<div class="paragraph">
<p>Unlike the Recreate update, the Rolling update type does not imply any Che server downtime, since new deployment is starting in parallel and traffic is hot-switched. (Typically there is 5-6 sec period of Che server API unavailability due to routes switching).</p>
</div>
<div class="sect3">
<h4 id="known-issues">Known issues</h4>
<div class="ulist">
<ul>
<li>
<p>Workspaces that are started shortly (5-30sec) before the network traffic is switched to the new pod, may fallback to the stopped state. That happens because bootstrappers uses Che server route URL for notifying Che Server when bootstrapping is done. Since traffic is already switched to the new Che server, old one cannot get bootstrapper-s report, and fails the start after waiting timeout reached. If old Che server will be killed before this timeout, workspaces can stuck in the <code>STARTING</code> state. So the <code>terminationGracePeriodSeconds</code> parameter must define time enough to cover workspace start timeout timeout (which is 8 min by def.) plus some additional timings. Typically, setting <code>terminationGracePeriodSeconds</code> to 540 sec is enough to cover all timeouts.</p>
</li>
<li>
<p>Some users may experience problems with websocket reconnections or missed events published by WebSocket connection(when a workspace is STARTED but dashboard displays that it is STARTING); Need to reload page to restore connections and actual workspaces states.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="update-with-db-migrations-or-api-incompatibility">Update with DB migrations or API incompatibility</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If new version of Che server contains some DB migrations, but there is still API compatibility between old and new version, recreate update type may be used, without stopping running workspaces.</p>
</div>
<div class="paragraph">
<p>API incompatible versions should be updated with full workspaces stop. It means that <code>/api/system/stop?shutdown=true</code> must be called prior to update.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="delete-deployments">Delete deployments</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want to completely delete Che and its infrastructure components, deleting a project/namespace is the fastest way - all objects associated with this namespace will be deleted:</p>
</div>
<div class="paragraph">
<p><code>oc delete namespace che</code></p>
</div>
<div class="paragraph">
<p>If you need to delete particular deployments and associated objects, you can use selectors (use <code>oc</code> instead of <code>kubctl</code> for OpenShift):</p>
</div>
<div class="listingblock">
<div class="content">
<pre># remove all Che server related objects
kubectl delete all -l=app=che
# remove all Keycloak related objects
kubectl delete all -l=app=keycloak
# remove all Postgres related objects
kubectl delete all -l=app=postgres</pre>
</div>
</div>
<div class="paragraph">
<p>PVCs, service accounts and role bindings should be deleted separately as <code>oc delete all</code> does not delete them:</p>
</div>
<div class="listingblock">
<div class="content">
<pre># Delete Che server PVC, ServiceAccount and RoleBinding
kubectl delete sa -l=app=che
kubectl delete rolebinding -l=app=che
# Delete Keycloak and Postgres PVCs
kubectl delete pvc -l=app=keycloak
kubectl delete pvc -l=app=postgres</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="create-workspace-objects-in-personal-namespaces">Create workspace objects in personal namespaces</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When Che is installed on OpenShift in multi-user mode, it is possible to register the OpenShift server into the Keycloak server as an identity provider, in order to allow creating workspace objects in the personal OpenShift namespace of the user that is currenlty logged in Che through Keycloak.</p>
</div>
<div class="paragraph">
<p>This feature is available only when Che is configured to create a new OpenShift namespace for every Che workspace.</p>
</div>
<div class="paragraph">
<p>As detailed below, to enable this feature, the administrator should:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#openshift-identity-provider-registration">register</a>, inside Keycloak, an OpenShift identity provider that will point to the OpenShift console of the cluster in which the workspace resources should be created,</p>
</li>
<li>
<p><a href="#che-configuration">configure</a> Che to use this Keycloak identity provider in order to retrieve the OpenShift tokens of Che users.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Once this is done, every interactive action done by a Che user on workspaces, such as start or stop, will create OpenShift resources under his personal OpenShift account. And the first time the user will try to do it, he will be asked to link his Keycloak account with his personal OpenShift account: which he can do by simply following the provided link in the notification message.</p>
</div>
<div class="paragraph">
<p>But for non-interactive workspace actions, such as workspace stop on idling or Che server shutdown, the account used for operations on OpenShift resources will fall back to the dedicated OpenShift account configured for the Kubernetes infrastructure, as described in the <a href="admin-guide.html#who-creates-workspace-objects">AdminGuide</a>.</p>
</div>
<div class="paragraph">
<p>To easily install Che on OpenShift with this feature enabled, see <a href="openshift-multi-user.html#creating-workspace-resources-in-personal-openshift-accounts-on-minishift">this section for Minishift</a> and <a href="openshift-multi-user.html#creating-workspace-resources-in-personal-openshift-accounts">this one for OCP</a></p>
</div>
<div class="sect3">
<h4 id="openshift-identity-provider-registration">OpenShift identity provider registration</h4>
<div class="paragraph">
<p>The Keycloak OpenShift identity provider is described in <a href="https://www.keycloak.org/docs/3.3/server_admin/topics/identity-broker/social/openshift.html">this documentation</a>.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>In the <a href="user-management.html#auth-and-user-management">Keycloak administration console</a>, when adding the OpenShift identity provider, you should use the following settings:</p>
</li>
</ol>
</div>
<div class="imageblock">
<div class="content">
<img src="/che/docs/images/keycloak/openshift_identity_provider.png" alt="openshift identity provider">
</div>
</div>
<div class="paragraph">
<p><code>Base URL</code> is the URL of the OpenShift console</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Next thing is to add a default read-token role:</p>
</li>
</ol>
</div>
<div class="imageblock">
<div class="content">
<img src="/che/docs/images/git/kc_roles.png" alt="kc roles">
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Then this identity provider has to be declared as an OAuth client inside OpenShift. This can be done with the corresponding command:</p>
</li>
</ol>
</div>
<div class="listingblock">
<div class="content">
<pre>oc create -f &lt;(echo '
apiVersion: v1
kind: OAuthClient
metadata:
name: kc-client
secret: "&lt;value set for the 'Client Secret' field in step 1&gt;"
redirectURIs:
- "&lt;value provided in the 'Redirect URI' field in step 1&gt;"
grantMethod: prompt
')</pre>
</div>
</div>
<div class="paragraph">
<p><strong>Note</strong>: Adding a OAuth client requires cluster-wide admin rights.</p>
</div>
</div>
<div class="sect3">
<h4 id="che-configuration">Che configuration</h4>
<div class="paragraph">
<p>On the Che deployment configuration:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <code>CHE_INFRA_OPENSHIFT_PROJECT</code> environment variable should be set to <code>NULL</code> to ensure a new distinct OpenShift namespace is created for every started workspace.</p>
</li>
<li>
<p>the <code>CHE_INFRA_OPENSHIFT_OAUTH<em>IDENTITY</em>PROVIDER</code> environment variable should be set to the alias of the OpenShift identity provider specified in step 1 of its <a href="#openshift-identity-provider-registration">registration in Keycloak</a>. The default value is <code>openshift-v3</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="providing-the-openshift-certificate-to-keycloak">Providing the OpenShift certificate to Keycloak</h4>
<div class="paragraph">
<p>If the certificate used by the OpenShift console is self-signed or is not trusted, then by default the Keycloak will not be able to contact the OpenShift console to retrieve linked tokens.</p>
</div>
<div class="paragraph">
<p>In this case the OpenShift console certificate should be passed to the Keycloak deployment as an additional environment property. This will enable the Keycloak server to add it to its list of trusted certificates, and will fix the problem.</p>
</div>
<div class="paragraph">
<p>The environment variable is named <code>OPENSHIFT_IDENTITY_PROVIDER_CERTIFICATE</code>.</p>
</div>
<div class="paragraph">
<p>Since adding a multi-line certificate content in a deployment configuration environment variable is not that easy, the best way is to use a secret that contains the certificate, and refer to it in the environment variable.</p>
</div>
</div>
</div>
</div>
<div class="tags">
<b>Tags: </b>
<a href="tag_installation.html" class="btn btn-default navbar-btn cursorNorm" role="button">installation</a>
<a href="tag_kubernetes.html" class="btn btn-default navbar-btn cursorNorm" role="button">kubernetes</a>
</div>
<!--
-->
</div>
<hr class="shaded"/>
<footer>
<div class="row">
<div class="col-lg-12 footer">
Eclipse Che - Documentation <br/>
Site last generated: Sep 13, 2018 <br/>
<hr>
<a href="http://www.eclipse.org" target="_blank">Eclipse Foundation</a><br/>
<a href="http://www.eclipse.org/legal/privacy.php" target="_blank">Privacy Policy</a><br/>
<a href="http://www.eclipse.org/legal/termsofuse.php" target="_blank">Terms of Use</a><br/>
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">Eclipse Public License</a><br/>
<a href="http://www.eclipse.org/legal" target="_blank">Legal Resources</a><br/>
</div>
</div>
</footer>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- /#main -->
</div>
</body>
</html>