mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
docs: Update sync-waves.md to include more details about phases and waves (#22768)
Signed-off-by: Revital Barletz <revitalbarletz@gmail.com> Co-authored-by: Dan Garfield <dan@codefresh.io>
This commit is contained in:
BIN
docs/user-guide/how_phases_work.png
Normal file
BIN
docs/user-guide/how_phases_work.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/user-guide/how_waves_work.png
Normal file
BIN
docs/user-guide/how_waves_work.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
@@ -1,143 +1 @@
|
||||
# Resource Hooks
|
||||
## Overview
|
||||
|
||||
Synchronization can be configured using resource hooks. Hooks are ways to run scripts before, during,
|
||||
and after a Sync operation. Hooks can also be run if a Sync operation fails at any point. Some use cases for hooks are:
|
||||
|
||||
* Using a `PreSync` hook to perform a database schema migration before deploying a new version of the app.
|
||||
* Using a `Sync` hook to orchestrate a complex deployment requiring more sophistication than the
|
||||
Kubernetes rolling update strategy.
|
||||
* Using a `PostSync` hook to run integration and health checks after a deployment.
|
||||
* Using a `SyncFail` hook to run clean-up or finalizer logic if a Sync operation fails.
|
||||
* Using a `PostDelete` hook to run clean-up or finalizer logic after all Application resources are deleted. Please note that
|
||||
`PostDelete` hooks are only deleted if the delete policy matches the aggregated deletion hooks status and not garbage collected after the application is deleted.
|
||||
|
||||
## Usage
|
||||
|
||||
Hooks are simply Kubernetes manifests tracked in the source repository of your Argo CD Application annotated with `argocd.argoproj.io/hook`, e.g.:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
generateName: schema-migrate-
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
```
|
||||
|
||||
During a Sync operation, Argo CD will apply the resource during the appropriate phase of the
|
||||
deployment. Hooks can be any type of Kubernetes resource kind, but tend to be Pod,
|
||||
[Job](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/)
|
||||
or [Argo Workflows](https://github.com/argoproj/argo). Multiple hooks can be specified as a comma
|
||||
separated list.
|
||||
|
||||
The following hooks are defined:
|
||||
|
||||
| Hook | Description |
|
||||
|------|-------------|
|
||||
| `PreSync` | Executes prior to the application of the manifests. |
|
||||
| `Sync` | Executes after all `PreSync` hooks completed and were successful, at the same time as the application of the manifests. |
|
||||
| `Skip` | Indicates to Argo CD to skip the application of the manifest. |
|
||||
| `PostSync` | Executes after all `Sync` hooks completed and were successful, a successful application, and all resources in a `Healthy` state. |
|
||||
| `SyncFail` | Executes when the sync operation fails. |
|
||||
| `PostDelete` | Executes after all Application resources are deleted. _Available starting in v2.10._ |
|
||||
|
||||
### Generate Name
|
||||
|
||||
Named hooks (i.e. ones with `/metadata/name`) will only be created once. If you want a hook to be re-created each time either use `BeforeHookCreation` policy (see below) or `/metadata/generateName`.
|
||||
|
||||
## Selective Sync
|
||||
|
||||
Hooks are not run during [selective sync](selective_sync.md).
|
||||
|
||||
## Hook Deletion Policies
|
||||
|
||||
Hooks can be deleted in an automatic fashion using the annotation: `argocd.argoproj.io/hook-delete-policy`.
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
generateName: integration-test-
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PostSync
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
```
|
||||
Multiple hook delete policies can be specified as a comma separated list.
|
||||
|
||||
The following policies define when the hook will be deleted.
|
||||
|
||||
| Policy | Description |
|
||||
|--------|-------------|
|
||||
| `HookSucceeded` | The hook resource is deleted after the hook succeeded (e.g. Job/Workflow completed successfully). |
|
||||
| `HookFailed` | The hook resource is deleted after the hook failed. |
|
||||
| `BeforeHookCreation` | Any existing hook resource is deleted before the new one is created (since v1.3). It is meant to be used with `/metadata/name`. |
|
||||
|
||||
Note that if no deletion policy is specified, Argo CD will automatically assume `BeforeHookCreation` rules.
|
||||
|
||||
### Sync Status with Jobs/Workflows with Time to Live (ttl)
|
||||
|
||||
Jobs support the [`ttlSecondsAfterFinished`](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/)
|
||||
field in the spec, which let their respective controllers delete the Job after it completes. Argo Workflows support a
|
||||
[`ttlStrategy`](https://argoproj.github.io/argo-workflows/fields/#ttlstrategy) property that also allow a Workflow to be
|
||||
cleaned up depending on the ttl strategy chosen.
|
||||
|
||||
Using either of the properties above can lead to Applications being OutOfSync. This is because Argo CD will detect a difference
|
||||
between the Job or Workflow defined in the git repository and what's on the cluster since the ttl properties cause deletion of the resource after completion.
|
||||
|
||||
However, using deletion hooks instead of the ttl approaches mentioned above will prevent Applications from having a status of
|
||||
OutOfSync even though the Job or Workflow was deleted after completion.
|
||||
|
||||
## Using A Hook To Send A Slack Message
|
||||
|
||||
The following example uses the Slack API to send a Slack message when sync completes or fails:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
generateName: app-slack-notification-
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PostSync
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: slack-notification
|
||||
image: curlimages/curl
|
||||
command:
|
||||
- "curl"
|
||||
- "-X"
|
||||
- "POST"
|
||||
- "--data-urlencode"
|
||||
- "payload={\"channel\": \"#somechannel\", \"username\": \"hello\", \"text\": \"App Sync succeeded\", \"icon_emoji\": \":ghost:\"}"
|
||||
- "https://hooks.slack.com/services/..."
|
||||
restartPolicy: Never
|
||||
backoffLimit: 2
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
generateName: app-slack-notification-fail-
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: SyncFail
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: slack-notification
|
||||
image: curlimages/curl
|
||||
command:
|
||||
- "curl"
|
||||
- "-X"
|
||||
- "POST"
|
||||
- "--data-urlencode"
|
||||
- "payload={\"channel\": \"#somechannel\", \"username\": \"hello\", \"text\": \"App Sync failed\", \"icon_emoji\": \":ghost:\"}"
|
||||
- "https://hooks.slack.com/services/..."
|
||||
restartPolicy: Never
|
||||
backoffLimit: 2
|
||||
```
|
||||
> ⚠️ This page has moved. See [New Page](sync-waves.md)
|
||||
|
||||
@@ -1,12 +1,84 @@
|
||||
# Sync Phases and Waves
|
||||
|
||||
>v1.1
|
||||
Sync phases and hooks define when resources are applied such as before or after the main sync operation. This makes it possible to define jobs, or any other resource to run or be applied in any specific order.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/zIHe3EVp528" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
Argo CD has the following hook types:
|
||||
|
||||
Argo CD executes a sync operation in a number of steps. At a high-level, there are three phases *pre-sync*, *sync* and *post-sync*.
|
||||
| Hook | Description |
|
||||
|------|-------------|
|
||||
| `PreSync` | Executes prior to the application of the manifests. |
|
||||
| `Sync` | Executes after all `PreSync` hooks completed and were successful, at the same time as the application of the manifests. |
|
||||
| `Skip` | Indicates to Argo CD to skip the application of the manifest. |
|
||||
| `PostSync` | Executes after all `Sync` hooks completed and were successful, a successful application, and all resources in a `Healthy` state. |
|
||||
| `SyncFail` | Executes when the sync operation fails. |
|
||||
| `PostDelete` | Executes after all Application resources are deleted. _Available starting in v2.10._ |
|
||||
|
||||
Within each phase you can have one or more waves, that allows you to ensure certain resources are healthy before subsequent resources are synced.
|
||||
Adding the argocd.argoproj.io/hook annotation to a resource will assign it to a specific phase. During a Sync operation, Argo CD will apply the resource during the appropriate phase of the deployment. Hooks can be any type of Kubernetes resource kind, but tend to be Pod, Job or Argo Workflows. Multiple hooks can be specified as a comma separated list.
|
||||
|
||||
## How phases work?
|
||||
|
||||
Argo CD will respect resources assigned to different phases, during a sync operation Argo CD will do the following.
|
||||
|
||||
Apply all the resources marked as PreSync hooks. If any of them fails the whole sync process will stop and will be marked as failed
|
||||
Apply all the resources marked as Sync hooks. If any of them fails the whole sync process will be marked as failed. Hooks marked with SyncFail will also run
|
||||
Apply all the resources marked as PostSync hooks. If any of them fails the whole sync process will be marked as failed.
|
||||
Hooks marked with Skip will not be applied.
|
||||
|
||||
Here is a graphical overview of the sync process:
|
||||
|
||||

|
||||
|
||||
You can use this simple lifecycle method in various scenarios. For example you can run an essential check as a PreSync hook. If it fails then the whole sync operation will stop preventing the deployment from taking place. In a similar manner you can run smoke tests as PostSync hooks. If they succeed you know that your application has passed the validation. If they fail then the whole deployment will be marked as failed and Argo CD can then notify you in order to take further actions.
|
||||
|
||||
Hooks at the SyncFail phase can be used for cleanup actions and other housekeeping tasks. Note that if they themselves fail, Argo CD will not do anything special (other than marking the whole operation as failed).
|
||||
|
||||
Note that hooks do not run during a selective sync operation.
|
||||
|
||||
## Hook lifecycle and cleanup
|
||||
|
||||
Argo CD offers several methods to clean up hooks and decide how much history will be kept for previous runs.
|
||||
In the most basic case you can use the argocd.argoproj.io/hook-delete-policy to decide when a hook will be deleted.
|
||||
This can take the following values:
|
||||
|
||||
| Policy | Description |
|
||||
|--------|-------------|
|
||||
| `HookSucceeded` | The hook resource is deleted after the hook succeeded (e.g. Job/Workflow completed successfully). |
|
||||
| `HookFailed` | The hook resource is deleted after the hook failed. |
|
||||
| `BeforeHookCreation` | Any existing hook resource is deleted before the new one is created (since v1.3). It is meant to be used with `/metadata/name`. |
|
||||
|
||||
|
||||
## How sync waves work?
|
||||
|
||||
Argo CD also offers an alternative method of changing the sync order of resources. These are sync waves. They are defined by the argocd.argoproj.io/sync-wave annotation. The value is an integer that defines the ordering (ArgoCD will start deploying from the lowest number and finish with the highest number).
|
||||
|
||||
Hooks and resources are assigned to wave 0 by default. The wave can be negative, so you can create a wave that runs before all other resources.
|
||||
|
||||
When a sync operation takes place, Argo CD will:
|
||||
Order all resources according to their wave (lowest to highest)
|
||||
Apply the resources according to the resulting sequence
|
||||
|
||||
There is currently a delay between each sync wave in order to give other controllers a chance to react to the spec change that was just applied. This also prevents Argo CD from assessing resource health too quickly (against the stale object), causing hooks to fire prematurely. The current delay between each sync wave is 2 seconds and can be configured via the environment variable ARGOCD_SYNC_WAVE_DELAY.
|
||||
|
||||
## Combining Sync waves and hooks
|
||||
|
||||
While you can use sync waves on their own, for maximum flexibility you can combine them with hooks. This way you can use sync phases for coarse grained ordering and sync waves for defining the exact order of a resource within an individual phase.
|
||||
|
||||

|
||||
|
||||
When Argo CD starts a sync, it orders the resources in the following precedence:
|
||||
|
||||
The phase
|
||||
The wave they are in (lower values first)
|
||||
By kind (e.g. namespaces first and then other Kubernetes resources, followed by custom resources)
|
||||
By name
|
||||
|
||||
Once the order is defined:
|
||||
|
||||
First Argo CD determines the number of the first wave to apply. This is the first number where any resource is out-of-sync or unhealthy.
|
||||
It applies resources in that wave.
|
||||
It repeats this process until all phases and waves are in-sync and healthy.
|
||||
|
||||
Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy.
|
||||
|
||||
## How Do I Configure Phases?
|
||||
|
||||
@@ -32,30 +104,65 @@ metadata:
|
||||
|
||||
Hooks and resources are assigned to wave zero by default. The wave can be negative, so you can create a wave that runs before all other resources.
|
||||
|
||||
### Can Multiple Resources Share the Same Wave?
|
||||
## Examples
|
||||
|
||||
Yes, multiple resources can share the same sync-wave value. Resources with the same sync-wave are processed together.
|
||||
The following example uses the Slack API to send a a Slack message when sync completes:
|
||||
|
||||
Within a wave, resources are ordered by their kind (e.g. namespaces first) and then by their name.
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
generateName: app-slack-notification-
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PostSync
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: slack-notification
|
||||
image: curlimages/curl
|
||||
command:
|
||||
- curl
|
||||
- '-X'
|
||||
- POST
|
||||
- '--data-urlencode'
|
||||
- >-
|
||||
payload={"channel": "#somechannel", "username": "hello", "text":
|
||||
"App Sync succeeded", "icon_emoji": ":ghost:"}
|
||||
- 'https://hooks.slack.com/services/...'
|
||||
restartPolicy: Never
|
||||
backoffLimit: 2
|
||||
```
|
||||
|
||||
## How Does It Work?
|
||||
|
||||
When Argo CD starts a sync, it orders the resources in the following precedence:
|
||||
|
||||
* The phase
|
||||
* The wave they are in (lower values first for creation & updation and higher values first for deletion)
|
||||
* By kind (e.g. [namespaces first and then other Kubernetes resources, followed by custom resources](https://github.com/argoproj/gitops-engine/blob/bc9ce5764fa306f58cf59199a94f6c968c775a2d/pkg/sync/sync_tasks.go#L27-L66))
|
||||
* By name
|
||||
|
||||
It then determines the number of the next wave to apply. This is the first number where any resource is out-of-sync or unhealthy.
|
||||
|
||||
It applies resources in that wave.
|
||||
|
||||
It repeats this process until all phases and waves are in-sync and healthy.
|
||||
|
||||
Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy.
|
||||
|
||||
During pruning of resources, resources from higher waves are processed first before moving to lower waves. If, for any reason, a resource isn't removed/pruned in a wave, the resources in next waves won't be processed. This is to ensure proper resource cleanup between waves.
|
||||
|
||||
Note: there is a delay between each sync wave to give other controllers a chance to react to the applied spec change. This prevents Argo CD from assessing resource health too quickly (against a stale object), and firing
|
||||
hooks prematurely. The default delay between each sync wave is 2 seconds. This can be adjusted by setting the `ARGOCD_SYNC_WAVE_DELAY` environment variable in the argocd-application-controller deployment.
|
||||
The following example runs a db migration command before the main sync operation (also in wave -1):
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: db-migrate
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||
argocd.argoproj.io/sync-wave: '-1'
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 360
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: postgresql-client
|
||||
image: 'my-postgres-data:11.5'
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: PGPASSWORD
|
||||
value: admin
|
||||
- name: POSTGRES_HOST
|
||||
value: my_postgresql_db
|
||||
command:
|
||||
- psql
|
||||
- '-h=my_postgresql_db'
|
||||
- '-U postgres'
|
||||
- '-f preload.sql'
|
||||
restartPolicy: Never
|
||||
backoffLimit: 1
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user