mirror of https://github.com/portainer/portainer
343 lines
18 KiB
HTML
343 lines
18 KiB
HTML
<page-header
|
|
ng-if="ctrl.state.viewReady"
|
|
title="'Kubernetes features configuration'"
|
|
breadcrumbs="[
|
|
{ label:'Environments', link:'portainer.endpoints' },
|
|
{
|
|
label:ctrl.endpoint.Name,
|
|
link: 'portainer.endpoints.endpoint',
|
|
linkParams:{id: ctrl.endpoint.Id}
|
|
},
|
|
'Kubernetes configuration'
|
|
]"
|
|
reload="true"
|
|
>
|
|
</page-header>
|
|
|
|
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
|
|
|
<div ng-if="ctrl.state.viewReady">
|
|
<div class="row">
|
|
<div class="col-sm-12">
|
|
<rd-widget>
|
|
<rd-widget-body>
|
|
<form class="form-horizontal" name="kubernetesClusterSetupForm">
|
|
<div class="col-sm-12 form-section-title"> Networking </div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-12 text-muted small">
|
|
<p> Enabling the load balancer feature will allow users to expose application they deploy over an external IP address assigned by cloud provider. </p>
|
|
<p class="mt-1 vertical-center">
|
|
<pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
|
|
Ensure that your cloud provider allows you to create load balancers if you want to use this feature. Might incur costs.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-sm-12">
|
|
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Allow users to use external load balancer </label>
|
|
<label class="switch col-sm-8 mb-0">
|
|
<input type="checkbox" ng-model="ctrl.formValues.UseLoadBalancer" /><span class="slider round" data-cy="kubeSetup-loadBalancerToggle"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<ingress-class-datatable
|
|
on-change-controllers="(ctrl.onChangeControllers)"
|
|
allow-none-ingress-class="ctrl.formValues.AllowNoneIngressClass"
|
|
ingress-controllers="ctrl.originalIngressControllers"
|
|
is-loading="ctrl.isIngressControllersLoading"
|
|
description="'Enabling ingress controllers in your cluster allows them to be available in the Portainer UI for users to publish applications over HTTP/HTTPS. A controller must have a class name for it to be included here.'"
|
|
no-ingress-controller-label="'No supported ingress controllers found.'"
|
|
view="'cluster'"
|
|
></ingress-class-datatable>
|
|
|
|
<label htmlFor="foldingButtonIngControllerSettings" class="col-sm-12 form-section-title cursor-pointer flex items-center">
|
|
<button
|
|
id="foldingButtonIngControllerSettings"
|
|
type="button"
|
|
class="border-0 mx-2 bg-transparent inline-flex justify-center items-center w-2 !ml-0"
|
|
ng-click="ctrl.toggleAdvancedIngSettings()"
|
|
>
|
|
<pr-icon ng-if="!ctrl.state.isIngToggleSectionExpanded" icon="'chevron-right'"></pr-icon>
|
|
<pr-icon ng-if="ctrl.state.isIngToggleSectionExpanded" icon="'chevron-down'"></pr-icon>
|
|
</button>
|
|
More settings
|
|
</label>
|
|
<div ng-if="ctrl.state.isIngToggleSectionExpanded" class="ml-4">
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<por-switch-field
|
|
checked="ctrl.formValues.AllowNoneIngressClass"
|
|
name="'allowNoIngressClass'"
|
|
label="'Allow ingress class to be set to "none"'"
|
|
tooltip="'This allows users setting up ingresses to select "none" as the ingress class.'"
|
|
on-change="(ctrl.onToggleAllowNoneIngressClass)"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8'"
|
|
>
|
|
</por-switch-field>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<por-switch-field
|
|
checked="ctrl.formValues.IngressAvailabilityPerNamespace"
|
|
name="'ingressAvailabilityPerNamespace'"
|
|
label="'Configure ingress controller availability per namespace'"
|
|
tooltip="'This allows an administrator to configure, in each namespace, which ingress controllers will be available for users to select when setting up ingresses for applications.'"
|
|
on-change="(ctrl.onToggleIngressAvailabilityPerNamespace)"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8'"
|
|
>
|
|
</por-switch-field>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- auto update window -->
|
|
<div class="col-sm-12 form-section-title"> Change Window Settings </div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<por-switch-field
|
|
checked="ctrl.state.autoUpdateSettings.Enabled"
|
|
name="'disableSysctlSettingForRegularUsers'"
|
|
label="'Enable Change Window'"
|
|
feature-id="ctrl.limitedFeatureAutoWindow"
|
|
tooltip="'Automatic updates to stacks or applications outside the defined change window will not occur.'"
|
|
on-change="(ctrl.onToggleAutoUpdate)"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8 text-muted'"
|
|
>
|
|
</por-switch-field>
|
|
</div>
|
|
</div>
|
|
|
|
<time-window-picker ng-show="ctrl.state.autoUpdateSettings.Enabled" time-window="ctrl.state.autoUpdateSettings" time-zone="ctrl.state.timeZone"></time-window-picker>
|
|
|
|
<!-- #region SECURITY -->
|
|
<div class="col-sm-12 form-section-title"> Security </div>
|
|
|
|
<div
|
|
ng-if="!ctrl.isRBACEnabled"
|
|
class="mt-1 mb-6 p-4 w-full border border-solid bg-warning-2 border-warning-5 text-warning-8 th-dark:bg-yellow-11 th-dark:text-white th-highcontrast:bg-yellow-11 th-highcontrast:text-white small flex gap-1 rounded-lg"
|
|
>
|
|
<div class="mt-0.5">
|
|
<pr-icon icon="'alert-triangle'" feather="true" class-name="'text-warning-7 th-dark:text-white th-highcontrast:text-white'"></pr-icon>
|
|
</div>
|
|
<div>
|
|
<p> Your cluster does not have Kubernetes role-based access control (RBAC) enabled. </p>
|
|
<p> This means you can't use Portainer RBAC functionality to regulate access to environment resources based on user roles. </p>
|
|
<p class="mb-0">
|
|
To enable RBAC, start the <a
|
|
class="th-dark:text-blue-7 th-highcontrast:text-blue-4"
|
|
href="https://kubernetes.io/docs/concepts/overview/components/#kube-apiserver"
|
|
target="_blank"
|
|
>API server</a
|
|
> with the <code class="box-decoration-clone bg-gray-4 th-dark:bg-black th-highcontrast:bg-black">--authorization-mode</code> flag set to a
|
|
comma-separated list that includes <code class="bg-gray-4 th-dark:bg-black th-highcontrast:bg-black">RBAC</code>, for example:
|
|
<code class="box-decoration-clone bg-gray-4 th-dark:bg-black th-highcontrast:bg-black">kube-apiserver --authorization-mode=Example1,RBAC,Example2</code>.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<span class="col-sm-12 text-muted small">
|
|
By default, all the users have access to the default namespace. Enable this option to set accesses on the default namespace.
|
|
</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<por-switch-field
|
|
checked="ctrl.formValues.RestrictDefaultNamespace"
|
|
name="'restrictDefaultNs'"
|
|
label="'Restrict access to the default namespace'"
|
|
on-change="(ctrl.onToggleRestrictNs)"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8 text-muted'"
|
|
data-cy="kubeSetup-restrictDefaultNsToggle"
|
|
disabled="!ctrl.isRBACEnabled"
|
|
>
|
|
</por-switch-field>
|
|
</div>
|
|
|
|
<div class="col-sm-12 mt-5">
|
|
<por-switch-field
|
|
name="'restrictStandardUserIngressW'"
|
|
label="'Only allow admins to deploy ingresses'"
|
|
tooltip="'Enforces only allowing admins to deploy ingresses (and disallows standard users from doing so).'"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8 text-muted'"
|
|
data-cy="kubeSetup-restrictStandardUserIngressWToggle"
|
|
feature-id="ctrl.limitedFeatureIngressDeploy"
|
|
disabled="!ctrl.isRBACEnabled"
|
|
></por-switch-field>
|
|
</div>
|
|
</div>
|
|
<!-- #endregion -->
|
|
|
|
<div class="col-sm-12 form-section-title"> Resources and Metrics </div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-12 text-muted small">
|
|
<p>
|
|
By ENABLING resource over-commit, you are able to assign more resources to namespaces than is physically available in the cluster. This may lead to unexpected
|
|
deployment failures if there is insufficient resource to service demand.
|
|
</p>
|
|
<p class="mt-1 vertical-center">
|
|
<pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
|
|
By DISABLING resource over-commit (highly recommended), you are only able to assign resources to namespaces that are less (in aggregate) than the cluster total
|
|
minus any system resource reservation.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-sm-12">
|
|
<por-switch-field
|
|
data-cy="'kubeSetup-resourceOverCommitToggle'"
|
|
label="'Allow resource over-commit'"
|
|
name="'resource-over-commit-switch'"
|
|
feature-id="ctrl.limitedFeature"
|
|
checked="ctrl.formValues.EnableResourceOverCommit"
|
|
on-change="(ctrl.onChangeEnableResourceOverCommit)"
|
|
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
|
switch-class="'col-sm-8'"
|
|
></por-switch-field>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="col-sm-12 text-muted small">
|
|
<p> Enabling this feature will allow users to use specific features like autoscaling and to see container and node resource usage. </p>
|
|
<p class="vertical-center mt-1">
|
|
<pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
|
|
Ensure that <a href="https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#metrics-server" target="_blank">metrics server</a> or
|
|
<a href="https://github.com/kubernetes-sigs/prometheus-adapter" target="_blank">prometheus</a> is running inside your cluster.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Enable features using the metrics API </label>
|
|
<label class="switch col-sm-8">
|
|
<input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
|
|
<span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
|
|
</label>
|
|
</div>
|
|
<div ng-if="ctrl.state.metrics.pending && ctrl.state.metrics.userClick" class="col-sm-12 small text-muted" style="margin-top: 5px">
|
|
Checking metrics API... <pr-icon icon="'loader'" class-name="'ml-0.5'"></pr-icon>
|
|
</div>
|
|
<div
|
|
ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
|
class="col-sm-12 small text-muted vertical-center"
|
|
style="margin-top: 5px"
|
|
>
|
|
<pr-icon icon="'check'" mode="'success'"></pr-icon> Successfully reached metrics API
|
|
</div>
|
|
<div
|
|
ng-if="!ctrl.state.metrics.pending && !ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
|
class="col-sm-12 small text-muted vertical-center mt-2"
|
|
>
|
|
<pr-icon icon="'x'" mode="'danger'"></pr-icon> Unable to reach metrics API, make sure metrics server is properly deployed inside that cluster.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-12 form-section-title"> Available storage options </div>
|
|
|
|
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
|
<div class="col-sm-12 small text-muted vertical-center">
|
|
<pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
|
|
Unable to detect any storage class available to persist data. Users won't be able to persist application data inside this cluster.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
|
<span class="col-sm-12 text-muted small">
|
|
<p>
|
|
Select which storage options will be available for use when deploying applications. Have a look at your storage driver documentation to figure out which access
|
|
policy to configure and if the volume expansion capability is supported.
|
|
</p>
|
|
<p>
|
|
You can find more information about access modes
|
|
<a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes" target="_blank">in the official Kubernetes documentation</a>.
|
|
</p>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
|
<div style="margin-top: 10px" class="col-sm-12">
|
|
<table class="table" style="table-layout: fixed">
|
|
<tbody>
|
|
<tr class="text-muted">
|
|
<td>Storage</td>
|
|
<td>Shared access policy</td>
|
|
<td>Volume expansion</td>
|
|
</tr>
|
|
<tr ng-repeat="class in ctrl.StorageClasses">
|
|
<td>
|
|
<div class="flex flex-row items-center h-full">
|
|
<label class="switch mr-2 mb-0">
|
|
<input type="checkbox" ng-model="class.selected" /><span class="slider round" data-cy="kubeSetup-storageToggle{{ class.Name }}"></span>
|
|
</label>
|
|
<span>{{ class.Name }}</span>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<storage-access-mode-selector
|
|
options="ctrl.availableAccessModes"
|
|
value="class.AccessModes"
|
|
on-change="(ctrl.onChangeStorageClassAccessMode)"
|
|
storage-class-name="class.Name"
|
|
></storage-access-mode-selector>
|
|
</td>
|
|
<td>
|
|
<div class="flex flex-row items-center h-full">
|
|
<label class="switch mr-2 mb-0"
|
|
><input type="checkbox" ng-model="class.AllowVolumeExpansion" /><span
|
|
class="slider round"
|
|
data-cy="kubeSetup-storageExpansionToggle{{ class.Name }}"
|
|
></span>
|
|
</label>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="col-sm-12">
|
|
<span ng-if="!ctrl.hasValidStorageConfiguration()" class="text-muted small vertical-center mt-2">
|
|
<pr-icon icon="'alert-circle'" mode="'warning'"></pr-icon>
|
|
Shared access policy configuration required
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-sm-12 form-section-title"> Actions </div>
|
|
<!-- actions -->
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<button
|
|
type="submit"
|
|
class="btn btn-primary btn-sm !ml-0"
|
|
ng-click="ctrl.configure()"
|
|
ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
|
|
button-spinner="ctrl.state.actionInProgress"
|
|
analytics-on
|
|
analytics-if="ctrl.restrictDefaultToggledOn()"
|
|
analytics-category="kubernetes"
|
|
analytics-event="kubernetes-configure"
|
|
analytics-properties="{ metadata: { restrictAccessToDefaultNamespace: ctrl.formValues.RestrictDefaultNamespace } }"
|
|
data-cy="kubeSetup-saveConfigurationButton"
|
|
>
|
|
<span ng-hide="ctrl.state.actionInProgress">Save configuration</span>
|
|
<span ng-show="ctrl.state.actionInProgress">Saving configuration...</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</rd-widget-body>
|
|
</rd-widget>
|
|
</div>
|
|
</div>
|
|
</div>
|