What Are Deployment Strategies?

A deployment strategy is a way to change or upgrade an application. The aim
is to make the change without downtime in a way that the user barely notices the
improvements.

The most common strategy is to use a
blue-green
deployment. The new version (the blue version) is brought up for testing and
evaluation, while the users still use the stable version (the green version).
When ready, the users are switched to the blue version. If a problem arises, you
can switch back to the green version.

A common alternative strategy is to use A/B versions that are both active at the
same time and some users use one version, and some users use the other version.
This can be used for experimenting with user interface changes and other
features to get user feedback. It can also be used to verify proper operation in
a production context where problems impact a limited number of users.

A canary deployment tests the new version but when a problem is detected it
quickly falls back to the previous version. This can be done with both of the
above strategies.

The route based deployment strategies do not scale the number of pods in the
services. To maintain desired performance characteristics the deployment
configurations may need to be scaled.

There are things to consider when choosing a deployment strategy.

Long running connections need to be handled gracefully.

Database conversions can get tricky and will need to be done and rolled
back along with the application.

If the application is a hybrid of microservices and traditional components
downtime may be needed to complete the transition.

You need the infrastructure to do this.

If you have a non-isolated test environment, you can break both new and old versions.

Since the end user usually accesses the application through a route handled by a
router, the deployment strategy can focus on deployment configuration features
or routing features.

Strategies that focus on the deployment configuration impact all routes that use
the application. Strategies that use router features target individual routes.

Many deployment strategies are supported through the deployment configuration
and some additional strategies are supported through router features. The
deployment configuration-based strategies are discussed in this section.

The Rolling strategy is the default strategy used if
no strategy is specified on a deployment configuration.

A deployment strategy uses
readiness
checks to determine if a new pod is ready for use. If a readiness check fails,
the deployment configuration will retry to run the pod until it times out. The
default timeout is 10m, a value set in TimeoutSeconds in
dc.spec.strategy.*params.

Rolling Strategy

A rolling deployment slowly replaces instances of the previous version of an
application with instances of the new version of the application. A rolling
deployment typically waits for new pods to become ready via a readiness
check before scaling down the old components. If a significant issue occurs,
the rolling deployment can be aborted.

Canary Deployments

All rolling deployments in OpenShift Container Platform are canary deployments; a new
version (the canary) is tested before all of the old instances are replaced. If
the readiness check never succeeds, the canary instance is removed and the
deployment configuration will be automatically rolled back. The readiness check
is part of the application code, and may be as sophisticated as necessary to
ensure the new instance is ready to be used. If you need to implement more
complex checks of the application (such as sending real user workloads to the
new instance), consider implementing a custom deployment or using a
blue-green deployment strategy.

When to Use a Rolling Deployment

When you want to take no downtime during an application update.

When your application supports having old code and new code running at the same time.

A rolling deployment means you to have both old and new versions of your code
running at the same time. This typically requires that your application handle
N-1 compatibility.

Scale down the old replication controller based on the max unavailable count.

Repeat this scaling until the new replication controller has reached the desired
replica count and the old replication controller has been scaled to zero.

Execute any post lifecycle hook.

When scaling down, the Rolling strategy waits for pods to become ready so it can
decide whether further scaling would affect availability. If scaled up pods
never become ready, the deployment process will eventually time out and result in a
deployment failure.

The maxUnavailable parameter is the maximum number of pods that can be
unavailable during the update. The maxSurge parameter is the maximum number
of pods that can be scheduled above the original number of pods. Both parameters
can be set to either a percentage (e.g., 10%) or an absolute value (e.g.,
2). The default value for both is 25%.

These parameters allow the deployment to be tuned for availability and speed. For
example:

maxUnavailable=0 and maxSurge=20% ensures full capacity is maintained
during the update and rapid scale up.

maxUnavailable=10% and maxSurge=0 performs an update using no extra
capacity (an in-place update).

maxUnavailable=10% and maxSurge=10% scales up and down quickly with
some potential for capacity loss.

Generally, if you want fast rollouts, use maxSurge. If you need to take into
account resource quota and can accept partial unavailability, use
maxUnavailable.

Rolling Example

Rolling deployments are the default in OpenShift Container Platform. To see a rolling update,
follow these steps:

Create an application based on the example deployment images found in
DockerHub:

$ oc new-app openshift/deployment-example

If you have the router installed, make the application available via a route (or
use the service IP directly)

$ oc expose svc/deployment-example

Browse to the application at deployment-example.<project>.<router_domain> to
verify you see the v1 image.

Scale the deployment configuration up to three replicas:

$ oc scale dc/deployment-example --replicas=3

Trigger a new deployment automatically by tagging a new version of the example
as the latest tag:

$ oc tag deployment-example:v2 deployment-example:latest

In your browser, refresh the page until you see the v2 image.

If you are using the CLI, the following command will show you how many pods are on version 1 and how many
are on version 2. In the web console, you should see the pods slowly being added to v2 and removed from v1.

$ oc describe dc deployment-example

During the deployment process, the new replication controller is incrementally
scaled up. Once the new pods are marked as ready (by passing their readiness
check), the deployment process will continue. If the pods do not become ready,
the process will abort, and the deployment configuration will be rolled back to
its previous version.

Recreate Strategy

The Recreate strategy has basic rollout behavior and supports
lifecycle hooks for injecting code into the deployment
process.

During scale up, if the replica count of the deployment is greater than one, the
first replica of the deployment will be validated for readiness before fully
scaling up the deployment. If the validation of the first replica fails, the
deployment will be considered a failure.

When to Use a Recreate Deployment

When you must run migrations or other data transformations before your new code starts.

When you do not support having new and old versions of your application code running at the same time.

When you want to use a RWO volume, which is not supported being shared between multiple replicas.

A recreate deployment incurs downtime because, for a brief period, no instances
of your application are running. However, your old code and new code do not run
at the same time.

Custom Strategy

The Custom strategy allows you to provide your own deployment behavior.

In the above example, the organization/strategy container image provides the
deployment behavior. The optional command array overrides any CMD directive
specified in the image’s Dockerfile. The optional environment variables
provided are added to the execution environment of the strategy process.

Additionally, OpenShift Container Platform provides the following environment variables to the
deployment process:

Environment Variable

Description

OPENSHIFT_DEPLOYMENT_NAME

The name of the new deployment (a replication controller).

OPENSHIFT_DEPLOYMENT_NAMESPACE

The name space of the new deployment.

The replica count of the new deployment will initially be zero. The
responsibility of the strategy is to make the new deployment active using the
logic that best serves the needs of the user.

Alternatively, use customParams to inject the custom deployment logic into the
existing deployment strategies. Provide a custom shell script logic and call the
openshift-deploy binary. Users do not have to supply their custom deployer
container image, but the default OpenShift Container Platform deployer image will be used
instead:

If the custom deployment strategy process requires access to the OpenShift Container Platform API or the
Kubernetes API the container that executes the strategy can use the service account token
available inside the container for authentication.

Lifecycle Hooks

The Recreate and Rolling
strategies support lifecycle hooks, which allow behavior to be injected into
the deployment process at predefined points within the strategy: