3
votes

I am trying to deploy a new revision to Cloud Run via a CI/CD job and immediately start serving 100% of the traffic to the new revision.

This service is not customer facing and we do not need canary deployments or traffic splitting.

Currently the image is build in gitlab ci pipeline and published gcr. The next step is a gcloud run deploy command. The command is working just fine, I get a new revision. However 0% of the traffic is served to this revision, and I can't for the life of me figure out how to manage that programatically.

The only relevant piece of information I can find is this from the FAQ:

However, Cloud Run (currently) only supports serving traffic from the last healthy revision of your service. Therefore, it currently does not support revision based traffic splitting and canary deployments.

But it seems outdated, since I can currently split traffic between revisions manually via the UI. Any clarification would be greatly appreciated. Thank you!

1

1 Answers

7
votes

(The FAQ repo you linked is out of date, since I'm maintaining that I'll update it thanks for reminding.)

Cloud Run now offers traffic splitting. Here's how it works in a nutshell:

  • if there's no traffic split in place (latest=100%), gcloud run deploy will make the new revision 100%
  • if there's a split in place, gcloud run deploy will make the new revision 0%.

To prevent the new revision getting traffic, you can explicitly use --no-traffic.

If you want to split traffic programmatically, I recommend doing this:

  1. Before new deployment promote latest version (given it's stable/good) to 100%:

    gcloud run services update-traffic --to-revisions=LATEST=100 [...]
    

    (However, if your latest revision was not good, and you're not willing to send it 100% traffic, then you actually need to find the revision name and use it instead of LATEST)

  2. Deploy new revision:

    gcloud run deploy [...] --no-traffic
    
  3. Send a small amount of traffic to new revision:

    gcloud run services  update-traffic --to-revisions=LATEST=5 [...]
    

    When you run this, the new Revision will get 5% and the rest, and the previous revision will get 95%.

Caveat with the approach above: (This is mentioned by @Steren in the comment below.) If you possibly have multiple deployments happening at close time proximity (imagine two git pushes triggering a deployment), the LATEST can unintentionally point to the wrong revision. Steren’s recommendation is:

instead, to use gcloud run deploy [...] --revision-suffix=1234 --no-traffic and then gcloud run services update-traffic --to-revisions service-1234=10.

You can also give friendly names ("tags") to Revisions, however it's currently not possible to split traffic between them. (#ahmetb-todo) With that feature, you will be able to deploy a Revision and give it a name like "candidate" and then refer to it while splitting traffic instead of the complex auto-generated Revision name.

Alternatively, you can manage traffic between Revisions by deploying YAML manifests using gcloud run services replace command. This involves understanding how Knative API works. Here are some docs that might be relevant: