Introduction
When we were migrating from a bare-metal environment to a Kubernetes environment(replacing for example an rpm to helm charts), we needed a mechanism to even migrate the pre and post-install scripts into a helm pre-post steps.
For this, we found out an alternative in helm which is referred to as hooks.
Hooks is treated as a special annotation in helm. Helm handles hooks in its own specific way
Available Hooks
Annotation
Value
|
Description
|
pre-install
|
Executes
before any resource is loaded/created
|
post-install
|
Executes
after all resources are loaded into Kubernetes
|
pre-delete
|
Executes
on a deletion request before any resources are deleted from Kubernetes
|
post-delete
|
Executes
on a deletion request after all of the release's resources have been deleted
|
pre-upgrade
|
Executes on an upgrade request
after templates are rendered, but before any resources are updated
|
post-upgrade
|
Executes on an upgrade request
after all resources have been upgraded
|
pre-rollback
|
Executes on a rollback request
after templates are rendered, but before any resources are rolled back
|
post-rollback
|
Executes on a rollback request
after all resources have been modified
|
test
|
Executes when the Helm test
subcommand is invoked
|
Note: Resource here represents any kind for example a job, a pod and so on
Hooks example
Hooks are defined in a charts metadata section.
Consider following example for defining hooks:
apiVersion:
batch/v1
kind: Job
metadata: name: "{{ .Release.Name }}" labels: app.kubernetes.io/managed-by: {{
.Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} app.kubernetes.io/version: {{
.Chart.AppVersion }} helm.sh/chart: "{{ .Chart.Name
}}-{{ .Chart.Version }}" annotations: # This is what defines this resource
as a hook. Without this line, the # job is considered part of the
release. "helm.sh/hook":
post-install "helm.sh/hook-weight":
"-5" "helm.sh/hook-delete-policy":
hook-succeeded
|
The example provided above acts as a post-install hook which means when all the resources like job, deployment, service, and others are run/executed, this resource, for now a job, will then be run.
Similarly, there is no limit on the resources that can implement a hook.
Hooks Weight
There were scenarios wherein several pre-install hooks were to be executed in an order. For this, helm has provided a way to define weight for hooks. Following is how a weight is defined. Weight value can be negative or positive.
Example of hook weight:
annotations: "helm.sh/hook-weight":
"5"
|
Depending on the weight provided, each resource will then be executed
Consider the following example
post-install-job-1
apiVersion:
batch/v1
kind: Job
metadata: name: "{{ .Release.Name }}" labels: app.kubernetes.io/managed-by: {{
.Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} app.kubernetes.io/version: {{
.Chart.AppVersion }} helm.sh/chart: "{{ .Chart.Name
}}-{{ .Chart.Version }}" annotations: # This is what defines this
resource as a hook. Without this line, the # job is considered part of the
release. "helm.sh/hook":
post-install "helm.sh/hook-weight":
"-5" "helm.sh/hook-delete-policy":
hook-succeeded
spec: template: metadata: name: "{{ .Release.Name
}}" labels: app.kubernetes.io/managed-by:
{{ .Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} helm.sh/chart: "{{
.Chart.Name }}-{{ .Chart.Version }}" spec: restartPolicy: Never containers: - name: post-install-job-1 image: "alpine:3.3" command:
["/bin/sleep","{{ default "10" .Values.sleepyTime
}}"]
|
post-install-job-2
apiVersion:
batch/v1
kind: Job
metadata: name: "{{ .Release.Name }}" labels: app.kubernetes.io/managed-by: {{
.Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} app.kubernetes.io/version: {{
.Chart.AppVersion }} helm.sh/chart: "{{ .Chart.Name
}}-{{ .Chart.Version }}" annotations: # This is what defines this
resource as a hook. Without this line, the # job is considered part of the
release. "helm.sh/hook":
post-install "helm.sh/hook-weight":
"0" "helm.sh/hook-delete-policy":
hook-succeeded
spec: template: metadata: name: "{{ .Release.Name
}}" labels: app.kubernetes.io/managed-by:
{{ .Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} helm.sh/chart: "{{
.Chart.Name }}-{{ .Chart.Version }}" spec: restartPolicy: Never containers: - name: post-install-job-2 image: "alpine:3.3" command:
["/bin/sleep","{{ default "10" .Values.sleepyTime
}}"]
|
post-install-job-3
apiVersion:
batch/v1
kind: Job
metadata: name: "{{ .Release.Name }}" labels: app.kubernetes.io/managed-by: {{
.Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} app.kubernetes.io/version: {{
.Chart.AppVersion }} helm.sh/chart: "{{ .Chart.Name
}}-{{ .Chart.Version }}" annotations: # This is what defines this
resource as a hook. Without this line, the # job is considered part of the
release. "helm.sh/hook":
post-install "helm.sh/hook-weight":
"3" "helm.sh/hook-delete-policy":
hook-succeeded
spec: template: metadata: name: "{{ .Release.Name
}}" labels: app.kubernetes.io/managed-by:
{{ .Release.Service | quote }} app.kubernetes.io/instance: {{
.Release.Name | quote }} helm.sh/chart: "{{
.Chart.Name }}-{{ .Chart.Version }}" spec: restartPolicy: Never containers: - name: post-install-job-3 image: "alpine:3.3" command:
["/bin/sleep","{{ default "10" .Values.sleepyTime
}}"]
|
In the above given examples, the order of execution of the hooks will be as post-install-job-1, post-install-job-2, post-install-job-3.
Note: One resource can implement multiple hooks.
annotations: "helm.sh/hook":
post-install,post-upgrade
|
Hooks deletion
To manage system resources properly, helm even provides ways to delete each hook depending on certain criteria/policy.
Following is the way to define a hook deletion policy
annotations: "helm.sh/hook-delete-policy":
before-hook-creation,hook-succeeded
|
Hooks deletion policy
Following are the available hook deletion policy:
Annotation
Value
|
Description
|
before-hook-creation
|
Delete
the previous resource before a new hook is launched (default)
|
hook-succeeded
|
Delete
the resource after the hook is successfully executed
|
hook-failed
|
Delete
the resource if the hook failed during execution
|
Note: If no hook deletion policy annotation is specified, the before-hook-creation behavior applies by default.
0 Comments