Zero Downtime Deployments
Zero Downtime Deployments are a significant feature that the Cloud Platform provides.
Rolling updates enable you to update an application without any downtime.
A rolling update works by ensuring there is always one extra Pod than the maximum number stated in the deployment, for the duration of the update. i.e. when updating the application, new pods are created before the old pods are destroyed.
The new deployment is applied incrementally, usually one to two Pods at a time until all Pods are running the latest version. How the deployment is rolled out, can be configured by the user. More information about configuring a rolling update can be found here.
If an application is exposed publicly, traffic will only be routed to available Pods. This requires that your pods have correctly-configured
readinessProbes. More information can be found here.
More information about rolling updates is available here.
Readiness/Liveness probes and SSL in Rails applications
For zero downtime deployments, you will need a readiness probe in your application, so that the cluster knows when your container is ready to receive traffic. You will also need a liveness probe, so that the cluster knows if it needs to restart your container after a crash.
SSL will be terminated outside of your pod, so your probes will need to respond to HTTP requests. However, Ruby on Rails applications are sometimes configured to only respond to HTTPS traffic (by adding
config.force_ssl = true in the
In this case, the application will respond to any HTTP request with a redirect status code, asking the requester to resend the request to the equivalent HTTPS URL. This will cause your probes to fail, because the redirect will not be followed.
To fix this, the probe needs to tell the application that it is an HTTPS request, even though it isn’t, so that the application will process the request rather than sending a redirect response. You can do this by adding some HTTP headers to your probe definitions like this:
readinessProbe: httpGet: path: /ping.json port: 3000 httpHeaders: - name: X-Forwarded-Proto value: https - name: X-Forwarded-Ssl value: "on"
This will send an HTTP request to
/ping.json, but the rails application will respond as if it is HTTPS, and your probe should work as expected. This works for both readiness and liveness probes.