github.com/koderover/helm@v2.17.0+incompatible/docs/charts_hooks.md (about)

     1  # Hooks
     2  
     3  Helm provides a _hook_ mechanism to allow chart developers to intervene
     4  at certain points in a release's life cycle. For example, you can use
     5  hooks to:
     6  
     7  - Load a ConfigMap or Secret during install before any other charts are
     8    loaded.
     9  - Execute a Job to back up a database before installing a new chart,
    10    and then execute a second job after the upgrade in order to restore
    11    data.
    12  - Run a Job before deleting a release to gracefully take a service out
    13    of rotation before removing it.
    14  
    15  Hooks work like regular templates, but they have special annotations
    16  that cause Helm to utilize them differently. In this section, we cover
    17  the basic usage pattern for hooks.
    18  
    19  Hooks are declared as an annotation in the metadata section of a manifest:
    20  
    21  ```yaml
    22  apiVersion: ...
    23  kind: ....
    24  metadata:
    25    annotations:
    26      "helm.sh/hook": "pre-install"
    27  # ...
    28  ```
    29  
    30  ## The Available Hooks
    31  
    32  The following hooks are defined:
    33  
    34  - pre-install: Executes after templates are rendered, but before any
    35    resources are created in Kubernetes.
    36  - post-install: Executes after all resources are loaded into Kubernetes
    37  - pre-delete: Executes on a deletion request before any resources are
    38    deleted from Kubernetes.
    39  - post-delete: Executes on a deletion request after all of the release's
    40    resources have been deleted.
    41  - pre-upgrade: Executes on an upgrade request after templates are
    42    rendered, but before any resources are loaded into Kubernetes (e.g.
    43    before a Kubernetes apply operation).
    44  - post-upgrade: Executes on an upgrade after all resources have been
    45    upgraded.
    46  - pre-rollback: Executes on a rollback request after templates are
    47    rendered, but before any resources have been rolled back.
    48  - post-rollback: Executes on a rollback request after all resources
    49    have been modified.
    50  - crd-install: Adds CRD resources before any other checks are run. This is used
    51    only on CRD definitions that are used by other manifests in the chart.
    52  - test-success: Executes when running `helm test` and expects the pod to
    53    return successfully (return code == 0).
    54  - test-failure: Executes when running `helm test` and expects the pod to
    55    fail (return code != 0).
    56  
    57  ## Hooks and the Release Lifecycle
    58  
    59  Hooks allow you, the chart developer, an opportunity to perform
    60  operations at strategic points in a release lifecycle. For example,
    61  consider the lifecycle for a `helm install`. By default, the lifecycle
    62  looks like this:
    63  
    64  1. User runs `helm install foo`
    65  2. Chart is loaded into Tiller
    66  3. After some verification, Tiller renders the `foo` templates
    67  4. Tiller loads the resulting resources into Kubernetes
    68  5. Tiller returns the release name (and other data) to the client
    69  6. The client exits
    70  
    71  Helm defines two hooks for the `install` lifecycle: `pre-install` and
    72  `post-install`. If the developer of the `foo` chart implements both
    73  hooks, the lifecycle is altered like this:
    74  
    75  1. User runs `helm install foo`
    76  2. Chart is loaded into Tiller
    77  3. After some verification, Tiller renders the `foo` templates
    78  4. Tiller prepares to execute the `pre-install` hooks (loading hook resources into
    79     Kubernetes)
    80  5. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order.
    81  6. Tiller then loads the hook with the lowest weight first (negative to positive)
    82  7. Tiller waits until the hook is "Ready" (except for CRDs)
    83  8. Tiller loads the resulting resources into Kubernetes. Note that if the `--wait`
    84  flag is set, Tiller will wait until all resources are in a ready state
    85  and will not run the `post-install` hook until they are ready.
    86  9. Tiller executes the `post-install` hook (loading hook resources)
    87  10. Tiller waits until the hook is "Ready"
    88  11. Tiller returns the release name (and other data) to the client
    89  12. The client exits
    90  
    91  What does it mean to wait until a hook is ready? This depends on the
    92  resource declared in the hook. If the resources is a `Job` kind, Tiller
    93  will wait until the job successfully runs to completion. And if the job
    94  fails, the release will fail. This is a _blocking operation_, so the
    95  Helm client will pause while the Job is run.
    96  
    97  For all other kinds, as soon as Kubernetes marks the resource as loaded
    98  (added or updated), the resource is considered "Ready". When many
    99  resources are declared in a hook, the resources are executed serially. If they
   100  have hook weights (see below), they are executed in weighted order. Otherwise,
   101  ordering is not guaranteed. (In Helm 2.3.0 and after, they are sorted
   102  alphabetically. That behavior, though, is not considered binding and could change
   103  in the future.) It is considered good practice to add a hook weight, and set it
   104  to `0` if weight is not important.
   105  
   106  
   107  ### Hook resources are not managed with corresponding releases
   108  
   109  The resources that a hook creates are not tracked or managed as part of the
   110  release. Once Tiller verifies that the hook has reached its ready state, it
   111  will leave the hook resource alone.
   112  
   113  Practically speaking, this means that if you create resources in a hook, you
   114  cannot rely upon `helm delete` to remove the resources. To destroy such
   115  resources, you need to either write code to perform this operation in a `pre-delete`
   116  or `post-delete` hook or add `"helm.sh/hook-delete-policy"` annotation to the hook template file.
   117  
   118  ## Writing a Hook
   119  
   120  Hooks are just Kubernetes manifest files with special annotations in the
   121  `metadata` section. Because they are template files, you can use all of
   122  the normal template features, including reading `.Values`, `.Release`,
   123  and `.Template`.
   124  
   125  For example, this template, stored in `templates/post-install-job.yaml`,
   126  declares a job to be run on `post-install`:
   127  
   128  ```yaml
   129  apiVersion: batch/v1
   130  kind: Job
   131  metadata:
   132    name: "{{.Release.Name}}"
   133    labels:
   134      app.kubernetes.io/managed-by: {{.Release.Service | quote }}
   135      app.kubernetes.io/instance: {{.Release.Name | quote }}
   136      app.kubernetes.io/version: {{ .Chart.AppVersion }}
   137      helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
   138    annotations:
   139      # This is what defines this resource as a hook. Without this line, the
   140      # job is considered part of the release.
   141      "helm.sh/hook": post-install
   142      "helm.sh/hook-weight": "-5"
   143      "helm.sh/hook-delete-policy": hook-succeeded
   144  spec:
   145    template:
   146      metadata:
   147        name: "{{.Release.Name}}"
   148        labels:
   149          app.kubernetes.io/managed-by: {{.Release.Service | quote }}
   150          app.kubernetes.io/instance: {{.Release.Name | quote }}
   151          helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}"
   152      spec:
   153        restartPolicy: Never
   154        containers:
   155        - name: post-install-job
   156          image: "alpine:3.3"
   157          command: ["/bin/sleep","{{default "10" .Values.sleepyTime}}"]
   158  
   159  ```
   160  
   161  What makes this template a hook is the annotation:
   162  
   163  ```
   164    annotations:
   165      "helm.sh/hook": post-install
   166  ```
   167  
   168  One resource can implement multiple hooks:
   169  
   170  ```
   171    annotations:
   172      "helm.sh/hook": post-install,post-upgrade
   173  ```
   174  
   175  Similarly, there is no limit to the number of different resources that
   176  may implement a given hook. For example, one could declare both a secret
   177  and a config map as a pre-install hook.
   178  
   179  When subcharts declare hooks, those are also evaluated. There is no way
   180  for a top-level chart to disable the hooks declared by subcharts.
   181  
   182  It is possible to define a weight for a hook which will help build a
   183  deterministic executing order. Weights are defined using the following annotation:
   184  
   185  ```
   186    annotations:
   187      "helm.sh/hook-weight": "5"
   188  ```
   189  
   190  Hook weights can be positive or negative numbers but must be represented as
   191  strings. When Tiller starts the execution cycle of hooks of a particular kind (ex. the `pre-install` hooks or `post-install` hooks, etc.) it will sort those hooks in ascending order.
   192  
   193  It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation:
   194  
   195  ```
   196    annotations:
   197      "helm.sh/hook-delete-policy": hook-succeeded
   198  ```
   199  
   200  You can choose one or more defined annotation values:
   201  
   202  * `"hook-succeeded"` specifies Tiller should delete the hook after the hook is successfully executed.
   203  * `"hook-failed"` specifies Tiller should delete the hook if the hook failed during execution.
   204  * `"before-hook-creation"` specifies Tiller should delete the previous hook before the new hook is launched.
   205  
   206  By default Tiller will wait for 60 seconds for a deleted hook to no longer exist in the API server before timing out. This
   207  behavior can be changed using the `helm.sh/hook-delete-timeout` annotation. The value is the number of seconds Tiller
   208  should wait for the hook to be fully deleted. A value of 0 means Tiller does not wait at all.
   209  
   210  ### Defining a CRD with the `crd-install` Hook
   211  
   212  Custom Resource Definitions (CRDs) are a special kind in Kubernetes. They provide
   213  a way to define other kinds.
   214  
   215  On occasion, a chart needs to both define a kind and then use it. This is done
   216  with the `crd-install` hook.
   217  
   218  The `crd-install` hook is executed very early during an installation, before
   219  the rest of the manifests are verified. CRDs can be annotated with this hook so
   220  that they are installed before any instances of that CRD are referenced. In this
   221  way, when verification happens later, the CRDs will be available.
   222  
   223  Here is an example of defining a CRD with a hook, and an instance of the CRD:
   224  
   225  ```yaml
   226  apiVersion: apiextensions.k8s.io/v1beta1
   227  kind: CustomResourceDefinition
   228  metadata:
   229    name: crontabs.stable.example.com
   230    annotations:
   231      "helm.sh/hook": crd-install
   232  spec:
   233    group: stable.example.com
   234    version: v1
   235    scope: Namespaced
   236    names:
   237      plural: crontabs
   238      singular: crontab
   239      kind: CronTab
   240      shortNames:
   241      - ct
   242  ```
   243  
   244  And:
   245  
   246  ```yaml
   247  apiVersion: stable.example.com/v1
   248  kind: CronTab
   249  metadata:
   250    name: {{ .Release.Name }}-inst
   251  ```
   252  
   253  Both of these can now be in the same chart, provided that the CRD is correctly
   254  annotated.
   255  
   256  ### Automatically delete hook from previous release
   257  
   258  When a helm release, that uses a hook, is being updated, it is possible that the hook resource might already exist in the cluster. In such circumstances, by default, helm will fail trying to install the hook resource with an `"... already exists"` error.
   259  
   260  A common reason why the hook resource might already exist is that it was not deleted following use on a previous install/upgrade. There are, in fact, good reasons why one might want to keep the hook: for example, to aid manual debugging in case something went wrong. In this case, the recommended way of ensuring subsequent attempts to create the hook do not fail is to define a `"hook-delete-policy"` that can handle this: `"helm.sh/hook-delete-policy": "before-hook-creation"`. This hook annotation causes any existing hook to be removed, before the new hook is installed.
   261  
   262  If it is preferred to actually delete the hook after each use (rather than have to handle it on a subsequent use, as shown above), then this can be achieved using a delete policy of `"helm.sh/hook-delete-policy": "hook-succeeded,hook-failed"`.
   263  
   264