Install
Describes Hibernator chart 0.12.44
This page installs Hibernator with Helm, checks that it works, and lists what the chart
creates in your cluster. The commands use the release name hibernator in the namespace
hibernator.
- Prerequisites
- Install Hibernator
- Secrets from your own pipeline
- Verify the install
- Validating a values file before you install
- What the chart creates
Prerequisites
Section titled “Prerequisites”- Kubernetes 1.21 or later. The chart refuses an older cluster.
- Helm 3.8 or later.
- RBAC on the cluster.
- Credentials for the registry that holds the chart and the images.
- A mail server. Users sign in with a one-time code that Hibernator sends by email, so without a mail server nobody can sign in. There is no local account and no bypass. Passkeys are optional. They replace the code for a user who enrols one, but never the email: see passkeys.md.
- A license that names the place where you install, such as your AWS account. Without a license, Hibernator scales nothing. On AWS, the controller also needs an AWS role and access to AWS STS: see license.md.
- An HTTPS address for the UI.
config.externalUrlmust start withhttps://.
Install Hibernator
Section titled “Install Hibernator”1. Log in to the registry
Section titled “1. Log in to the registry”The chart is an OCI artifact at
oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator. The images are next to
it, under registry.gitlab.com/cirriton/hibernator.
helm registry login registry.gitlab.comIf you copy the chart and the images into your own registry, use your chart reference in
the commands below. Then set image.registry, image.repositoryPrefix and
imagePullSecrets.registry to your registry.
2. Generate the two secrets
Section titled “2. Generate the two secrets”openssl rand -base64 32 # secrets.jwtSecretopenssl rand -base64 32 # secrets.internalApiSecretThe chart generates neither secret. Keep both values. If jwtSecret changes on a later
upgrade, every user must sign in again.
If your secrets come from your own pipeline, the chart can read them from your own Secret: see Secrets from your own pipeline.
3. Write a values file
Section titled “3. Write a values file”Copy this file to my-values.yaml. Replace each value in angle brackets and each
example.com address.
imagePullSecrets: create: true username: "<registry-username>" password: "<registry-password-or-token>" # Or use a pull secret that you manage. Then remove the three lines above. # existingSecret: "<your-pull-secret>"
# Or put the secrets in a Secret that you manage, and name it in existingSecret.secrets: jwtSecret: "<first openssl output>" internalApiSecret: "<second openssl output>" smtp: user: "hibernator@example.com" password: "<smtp-password>"
# The license file you received, whole and unchanged. Or leave this out and add# --set-file license=HL-XXXXXXXX.license to the install command. license.md has# the other ways to install a license.license: | -----BEGIN HIBERNATOR LICENSE----- <the lines of your license file> -----END HIBERNATOR LICENSE-----
config: # A name for this cluster. Required. The UI and the notifications show it. clusterName: "my-cluster"
# The address where users open Hibernator. Required. It starts with https:// # and ends with /. Sign-in emails and satellite redirects use it. externalUrl: "https://hibernator.example.com/"
auth: adminUsers: - "you@example.com" # The domains whose addresses can sign in. allowedEmailDomains: - "example.com"
smtp: enabled: true host: "smtp.example.com" port: 587 from: "hibernator@example.com"
workingHours: timezone: "Europe/Berlin" schedule: monday: "08:00-20:00" tuesday: "08:00-20:00" wednesday: "08:00-20:00" thursday: "08:00-20:00" friday: "08:00-20:00" saturday: "off" sunday: "off"
targeting: namespaces: exclude: - pattern: "kube-*" - exact: "hibernator"
operations: # Hibernator writes to its log what it would do, and changes nothing. # Set this to false when the exclude list above is correct. dryRun: trueThe working hours are the chart defaults. schedule.md has the format.
To keep one workload running at all times, put the annotation
hibernator.io/exclude: "true" on it. annotations.md has the details.
4. Install the chart
Section titled “4. Install the chart”Name the release hibernator. The controller and the API find their ConfigMap and their
Service by that name. To use a different release name, set fullnameOverride: hibernator
in my-values.yaml. The chart refuses every other full name, and the install fails.
helm install hibernator oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator \ -n hibernator --create-namespace \ -f my-values.yamlIf you did not put the license in my-values.yaml, give the license file with
--set-file:
helm install hibernator oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator \ -n hibernator --create-namespace \ -f my-values.yaml \ --set-file license=HL-XXXXXXXX.licenseWhen a required value is missing, the install fails, and the message names the value. To check the values file before you install, see Validating a values file before you install.
Secrets from your own pipeline
Section titled “Secrets from your own pipeline”If External Secrets Operator, Sealed Secrets, Vault or a similar tool supplies your secrets, the chart can read them from a Secret that you manage. Then the chart creates no Secret of its own, and your values file holds no secret.
-
Create a Secret in the release namespace before you install the chart. Until the Secret exists, the pods do not start.
-
Put these keys in the Secret:
Key Value jwt-secretThe first openssl rand -base64 32output. Requiredinternal-api-secretThe second openssl rand -base64 32output. Requiredsmtp-userThe user name for the mail server. Only if the mail server needs a sign-in smtp-passwordThe password for the mail server. Only if the mail server needs a sign-in -
Set
secrets.existingSecretto the name of the Secret. -
Remove the other
secretsvalues from your values file.
secrets: existingSecret: "hibernator-app-secrets"The Secret looks like this:
apiVersion: v1kind: Secretmetadata: name: hibernator-app-secrets namespace: hibernatortype: OpaquestringData: jwt-secret: "<first openssl output>" internal-api-secret: "<second openssl output>" smtp-user: "hibernator@example.com" smtp-password: "<smtp-password>"The mail server’s host, port and sender address stay in config.smtp. They are not
secrets, so the Secret does not hold them.
The pods read the Secret when they start. After you change a value in the Secret, restart the pods:
kubectl rollout restart deployment -n hibernator hibernator-app hibernator-controllerVerify the install
Section titled “Verify the install”1. Check the pods
Section titled “1. Check the pods”kubectl get pods -n hibernatorThe controller pod and the app pod must both be Running.
2. Check the API
Section titled “2. Check the API”The service is ClusterIP, and the chart creates no Ingress. To check the API before you
expose the UI, forward a port to the service:
kubectl port-forward -n hibernator svc/hibernator-app 8080:80curl -s http://127.0.0.1:8080/api/v1/public/hibernation-statusAn answer shows that the API and the ConfigMap store work. Do not open the UI on this
address: the UI sends 127.0.0.1:8080 to config.externalUrl.
troubleshooting.md
tells why.
3. Expose the UI
Section titled “3. Expose the UI”Set service.type to LoadBalancer, or put your own Ingress or Gateway in front of the
service hibernator-app. Make sure that config.externalUrl is the address that
results. If it is not, change the value and upgrade the release.
Users must be able to open that address. The UI and the satellites send users to it.
4. Sign in
Section titled “4. Sign in”- Open
config.externalUrl. - Enter an address from
config.auth.adminUsers. - Enter the one-time code from the email.
The login page shows that the API, the UI and the ConfigMap store work. The email shows that the mail server works.
5. Check the schedule
Section titled “5. Check the schedule”Open the Schedule page. It shows the next scheduled transition and the working hours of each day. Make sure that they agree with your values file.
To test a hibernation now:
- In Manual Control, click Trigger Manual Hibernation.
- Enter a reason of 10 to 50 characters.
- Click Hibernate Resources.
While config.operations.dryRun is true, Hibernator changes nothing. It writes each
change that it would make to the controller log:
kubectl logs -n hibernator deployment/hibernator-controller | grep "(dry-run)"The manual hibernation continues until the working hours start. To stop it before then, click Resume Schedule in Manual Control.
6. Turn off dry run
Section titled “6. Turn off dry run”When the log shows only the workloads that you expect, set
config.operations.dryRun: false in my-values.yaml. Then upgrade the release as
upgrade.md shows.
When dry run ends, Hibernator acts at once. Outside the working hours, or while a manual hibernation continues, it scales the workloads to zero. To bring them back before the working hours start:
- In Manual Control, click Wake Up Resources.
- Select how long the workloads stay awake.
- Click Wake Up Resources in the dialog.
When the wake expires, the schedule decides again.
Validating a values file before you install
Section titled “Validating a values file before you install”Render your values file with the chart before you install it:
helm template hibernator oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator -f my-values.yaml >/dev/nullThis command reports the errors of the chart’s schema and of the chart’s own checks.
It is the only check that finds both. helm lint alone is not sufficient: it shows a
template failure as an INFO line and exits 0.
A misspelled key is usually silent
Section titled “A misspelled key is usually silent”Helm does not report an unknown key. It ignores a misspelled key and uses the default in its place. The install can then succeed and do something different from what you wrote.
The chart’s values.schema.json closes the objects that it models fully. A typo in a
closed object is an error that names the path:
$ helm template ... --set config.smtp.hosst=mail.example.comError: values don't meet the specifications of the schema(s) in the following chart(s):hibernator:- at '/config/smtp': additional properties 'hosst' not allowedThese objects are closed:
namespace,replicaCount, andimagewith each per-component blockimagePullSecrets,secretsandsecrets.smtpmetrics.serviceMonitorconfig.workingHoursand itsscheduleconfig.targetingwith.namespacesand itsexcludematchersconfig.resourceRulesand eachneverScaleentryconfig.serviceRedirectionand each serviceconfig.smtp,config.dashboardApiandconfig.auth.webauthnconfig.notifications.channels.emailconfig.externalDependencies, withsecretRefand each resource groupconfig.externalWakeand itsquotas- each entry of
config.externalWake.clusters, withsecretRefand each resource group
config.databases, config.wakeOrdering and config.hibernateOrdering also refuse
unknown keys, but the schema does not check them. The controller reads them with a
strict decoder when it loads the ConfigMap. A typo there installs without an error. Then
the controller stops at startup and names the path in its log. Check the controller log
after you change one of the three.
The schema does not model every key of the objects below, so they stay open. Helm ignores a typo in an open object without an error. Check these objects yourself:
| Object | Keys the schema does not model |
|---|---|
config |
most of its sections |
config.auth |
privacy (webauthn is closed) |
config.operations |
enableApiAccessLogs |
service |
api, frontend, controller |
metrics |
grafanaDashboard, prometheusRule |
global |
all keys: it stays open on purpose, because Helm shares it with subcharts |
resources.*.requests / .limits |
any resource name other than cpu and memory |
To check an open object, compare the rendered ConfigMap with what you expect:
helm template hibernator oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator -f my-values.yaml \ --show-only templates/configmap.yamlWhat the chart creates
Section titled “What the chart creates”The names below are the same for each release, because the chart accepts only the full
name hibernator. Hibernator itself creates more
ConfigMaps at runtime; how-it-works.md
lists them. The controller also creates two PodDisruptionBudgets at runtime;
how-it-works.md has them.
Workloads, services, configuration
Section titled “Workloads, services, configuration”| Kind | Name | When |
|---|---|---|
| Deployment | hibernator-controller |
Always |
| Deployment | hibernator-app |
Always |
| Service | hibernator-app |
Always |
| Service | hibernator-controller |
Always. Health and metrics ports only |
| ConfigMap | hibernator-config |
Always |
| Secret | hibernator-secrets |
secrets.existingSecret is empty, the default. The two secrets, and the mail server sign-in while config.smtp.enabled is true |
| ServiceAccount | hibernator-api, hibernator-controller |
serviceAccount.api.create and serviceAccount.controller.create, both true by default |
| ConfigMap | hibernator-license |
license is set |
| ConfigMap | hibernator-brand |
A branding value is set |
| Secret | hibernator-registry, or imagePullSecrets.secretName |
imagePullSecrets.create is true |
| Secret | One per entry of externalWakeSecrets.secrets |
externalWakeSecrets.create is true |
| Namespace | namespace.name, or the release namespace |
namespace.create is true |
| ServiceMonitor | hibernator-api, hibernator-controller |
metrics.serviceMonitor.enabled is true |
| PrometheusRule | hibernator |
metrics.prometheusRule.enabled is true |
| ConfigMap | hibernator-dashboard |
metrics.grafanaDashboard.enabled is true |
The chart creates these objects while rbac.create is true, the default. With
rbac.create: false it creates none of them, and you must grant the same rules
yourself.
ClusterRole hibernator-controller, bound to the ServiceAccount
hibernator-controller by the ClusterRoleBinding hibernator-controller:
| API group | Resource | Verbs | Used for |
|---|---|---|---|
| core | namespaces |
get, list, watch | Finding the namespaces in scope |
apps |
deployments |
get, list, watch, create, update, delete | Scaling. The satellites are Deployments too |
apps |
statefulsets |
get, list, watch, update | Scaling |
apps |
replicasets |
get, list, watch | Finding the owner of a pod, for pod protection |
batch |
cronjobs |
get, list, watch, update | Suspending and resuming |
batch |
jobs |
get, list, watch | Finding the owner of a pod, for pod protection |
| core | pods |
get, list, watch, update, patch | The pod protection annotations |
| core | nodes |
get, list | Sustainability (instance type, allocatable resources) and the license check (providerID) |
metrics.k8s.io |
nodes |
list | CPU use for Sustainability, from metrics-server |
| core | configmaps |
get, list, watch, create, update | State and configuration |
| core | services |
get, list, update | Service redirection |
policy |
poddisruptionbudgets |
get, create, update, delete | Protection while it scales |
| core | secrets |
get, create, delete | The image pull secrets of the satellites |
| core | events |
create | Kubernetes events |
Role hibernator-api in the release namespace, bound to the ServiceAccount
hibernator-api by the RoleBinding hibernator-api:
| API group | Resource | Verbs | Used for |
|---|---|---|---|
| core | configmaps |
get, list, watch, create, update | Hibernation and wake state, external wake sessions and configuration |
| core | secrets |
get | The external wake HMAC secret |
ClusterRole hibernator-api-services, bound to the ServiceAccount hibernator-api by
the ClusterRoleBinding hibernator-api-services:
| API group | Resource | Verbs | Used for |
|---|---|---|---|
| core | services |
get, list, watch | Reading the services in all namespaces |
To see the rules as the chart renders them for your values file:
helm template hibernator oci://registry.gitlab.com/cirriton/hibernator/charts/hibernator -f my-values.yaml \ --show-only templates/rbac.yaml