Reduce the risk of introducing a new software version in production by slowly rolling out the change to a small subset of users. This plugin also enables roll back to your original upstream service, or shift all traffic to the new version.
Configuration Reference
Example plugin configuration
Enable on a service
Enable on a route
Enable on a consumer
Enable globally
The following examples provide some typical configurations for enabling
the canary
plugin on a
service.
Admin API
Kubernetes
Declarative (YAML)
Konnect Cloud
Kong Manager
Make the following request:
curl -X POST http://{HOST}:8001/services/{SERVICE}/plugins \
--data "name=canary"
SERVICE
is the id
or name
of the service that this plugin
configuration will target.
First, create a KongPlugin
resource:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: <canary-example>
config:
<optional_parameter>: <value>
plugin: canary
Next, apply the KongPlugin resource to a
Service by annotating the
Service as follows:
apiVersion: v1
kind: Service
metadata:
name: {SERVICE}
labels:
app: {SERVICE}
annotations:
konghq.com/plugins: <canary-example>
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: {SERVICE}
selector:
app: {SERVICE}
{SERVICE}
is the id
or name
of the service that this plugin
configuration will target.
Note: The KongPlugin resource only needs to be defined once
and can be applied to any service, consumer, or route in the namespace. If you
want the plugin to be available cluster-wide, create the resource as a
KongClusterPlugin
instead of KongPlugin
.
Add this section to your declarative configuration file:
plugins:
- name: canary
service: {SERVICE}
config:
<optional_parameter>: <value>
SERVICE
is the id
or name
of the service that this plugin
configuration will target.
- In Konnect Cloud, select the service on the ServiceHub page.
- Scroll down to Versions and select the version.
- Scroll down to Plugins and click New Plugin.
- Find and select the Canary Release plugin.
- Click Create.
- In Kong Manager, select the workspace.
- From the Dashboard, scroll down to Services and click View for the
service row.
- Scroll down to plugins and click Add Plugin.
-
Find and select the Canary Release plugin.
Note: If the plugin is greyed out, then it is not available
for your product tier. See
Kong Gateway tiers.
- If the option is available, select Scoped.
- Add the service name and ID to the Service field if it
is not already prefilled.
- Click Create.
The following examples provide some typical configurations for enabling
the canary
plugin on a
route.
Admin API
Kubernetes
Declarative (YAML)
Konnect Cloud
Kong Manager
Make the following request:
$ curl -X POST http://{HOST}:8001/routes/{ROUTE}/plugins \
--data "name=canary"
ROUTE
is the id
or name
of the route that this plugin configuration
will target.
First, create a KongPlugin
resource:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: <canary-example>
config:
<optional_parameter>: <value>
plugin: canary
Then, apply it to an ingress (Route or Routes)
by annotating the ingress as follows:
apiVersion: networking/v1beta1
kind: Ingress
metadata:
name: {ROUTE}
annotations:
kubernetes.io/ingress.class: kong
konghq.com/plugins: <canary-example>
spec:
rules:
- host: examplehostname.com
http:
paths:
- path: /bar
backend:
serviceName: echo
servicePort: 80
ROUTE
is the id
or name
of the route that this plugin configuration
will target.
Note: The KongPlugin resource only needs to be defined once
and can be applied to any service, consumer, or route in the namespace. If you
want the plugin to be available cluster-wide, create the resource as a
KongClusterPlugin
instead of KongPlugin
.
Add this section to your declarative configuration file:
plugins:
- name: canary
route: <route>
config:
<optional_parameter>: <value>
ROUTE
is the id
or name
of the route that this plugin configuration
will target.
- In Konnect Cloud, select the service from the ServiceHub page.
- Scroll down to Versions and select the version.
- Select the route.
- Scroll down to Plugins and click Add Plugin.
- Find and select the Canary Release plugin.
- Click Create.
- In Kong Manager, select the workspace.
- From the Dashboard, select Routes in the left navigation.
- Click View for the route row.
- Scroll down to plugins and click Add Plugin.
-
Find and select the Canary Release plugin.
Note: If the plugin is greyed out, then it is not available
for your product tier. See
Kong Gateway tiers.
- If the option is available, select Scoped.
- Add the Route ID if it is not already prefilled.
- Click Create.
The following examples provide some typical configurations for enabling
the canary
plugin on a
consumer.
Admin API
Kubernetes
Declarative (YAML)
Kong Manager
Make the following request:
$ curl -X POST http://{HOST}:8001/consumers/{CONSUMER}/plugins \
--data "name=canary"
CONSUMER
is the id
or username
of the consumer that this plugin
configuration will target.
You can combine consumer.id
, service.id
, or route.id
in the same request, to further narrow the scope of the plugin.
First, create a KongPlugin
resource:
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: <canary-example>
config:
<optional_parameter>: <value>
plugin: canary
Then, apply it to a consumer by
annotating the KongConsumer resource as follows:
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: {CONSUMER}
annotations:
konghq.com/plugins: <canary-example>
kubernetes.io/ingress.class: kong
CONSUMER
is the id
or username
of the consumer that this plugin
configuration will target.
Note: The KongPlugin resource only needs to be defined once
and can be applied to any Service, Consumer, or Route in the namespace. If you
want the plugin to be available cluster-wide, create the resource as a
KongClusterPlugin
instead of KongPlugin
.
Add this section to your declarative configuration file:
plugins:
- name: canary
consumer: {CONSUMER}
config:
<optional_parameter>: <value>
CONSUMER
is the id
or username
of the consumer that this plugin
configuration will target.
- In Kong Manager, select the workspace.
- From the Dashboard, scroll down to Consumers and click View for the consumer row.
- Select the Plugins tab.
- Click Add Plugin.
-
Find and select the Canary Release plugin.
Note: If the plugin is greyed out, then it is not available
for your product tier. See
Kong Gateway tiers.
- If the option is available, select Global.
- Click Create.
A plugin which is not associated to any service, route, or consumer is
considered global, and will be run on every request. Read the
Plugin Reference and the Plugin Precedence
sections for more information.
The following examples provide some typical configurations for enabling
the canary
plugin globally.
Admin API
Kubernetes
Declarative (YAML)
Kong Manager
Make the following request:
$ curl -X POST http://{HOST}:8001/plugins/ \
--data "name=canary"
Create a KongClusterPlugin
resource and label it as global:
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: <global-canary>
annotations:
kubernetes.io/ingress.class: kong
labels:
global: \"true\"
config:
<optional_parameter>: <value>
plugin: canary
Add a plugins
entry in the declarative
configuration file:
plugins:
- name: canary
config:
<optional_parameter>: <value>
- In Kong Manager, select the workspace.
- From the Dashboard, select Plugins in the left navigation.
- Click New Plugin.
-
Find and select the Canary Release plugin.
Note: If the plugin is greyed out, then it is not available
for your product tier. See
Kong Gateway tiers.
- If the option is available, set the plugin scope to Global.
- Click Create.
Parameters
Here's a list of all the parameters which can be used in this plugin's configuration:
Form Parameter |
Description |
name
required
Type: string |
The name of the plugin, in this case canary . |
service.id
Type: string |
The ID of the Service the plugin targets. |
route.id
Type: string |
The ID of the Route the plugin targets. |
consumer.id
Type: string |
The ID of the Consumer the plugin targets. |
enabled
required
Type: boolean
Default value: true |
Whether this plugin will be applied. |
api_id
Type: string |
The ID of the API the plugin targets.
Note: The API Entity is deprecated in favor of Services since CE 0.13.0 and EE 0.32. |
config.start
|
Future time in seconds since epoch, when the release will start (ignored when percentage is set)
|
config.duration
Default value: 3600
|
How long, in seconds, should the transition take (ignored when percentage is set)
|
config.percentage
|
Fixed % of traffic to be routed to new target, if given overrides start and duration
|
config.steps
Default value: 1000
|
Number of steps the release should be broken into
|
config.upstream_host
|
Target hostname where traffic will be routed, required if upstream_uri is not set
|
config.upstream_uri
|
Upstream URI where traffic will be routed, required if upstream_host is not set
|
config.hash
Default value: consumer
|
Entity to be used for hashing. Options: consumer, ip, or none. Please make sure when not using none, to properly set the settings for trusted_ips (see settings trusted_ips and real_ip_header in the Kong config file)
|
Usage
The plugin will route traffic to 2 different upstream services, referred to as A and B. The location of service A will be defined by the upstream_url
property of the api the plugin is configured on. The location of service B is defined by the config.upstream_host
or config.upstream_uri
as configured on the plugin.
There are 2 modes of operation:
- Set a fixed percentage to be routed to destination B. See parameter
config.percentage
.
- Set a period over which (in linear time) the traffic will be moved over from destination A to B. See parameters
config.start
and config.duration
.
Determining where to route a request
The plugin defines a number of “buckets” (config.steps
). Each of those can be routed to either A or B. For example: 100 steps, and percentage
at 10%. Then 100 buckets will be created, of which 10 will be routed to upstream B, and 90 will remain at A.
Which requests end up in a specific bucket is determined by the config.hash
parameter. When set to consumer then it is made sure that each consumer will consistently end up in the same bucket. The effect being that once a bucket a consumer belongs to is switched to B, it will then always go to B, and a consumer
will not “flip-flop” between A and B. Alternatively if it is set to ip
then the same concept applies, but based on the originating ip address.
The downside of consumer
and ip
is that if any specific consumer or ip is responsible for a more than average part of the load, the migration is not nicely distributed. Eg. with percentage set to 50%, then 50% of either the consumers or ips are rerouted, but not necessarily 50% of the requests.
When set to none
then the requests will be nicely distributed, each bucket will get the same number of requests, but in this case a consumer or ip might be flip-flopping between destination A and B on consecutive requests.
In any case there is an automatic fallback in case a consumer or ip could not be identified for some reason. The fall-back order will be consumer
->ip
->none
.
Finalizing the canary
Once the canary is complete, either going to 100% for a percent-based canary, or after the timed canary reached 100%, the configuration needs to be updated.
This takes 2 steps:
- Update location A to point to location B. This can be done by a PATCH request on the API where the
upstream_url
property is updated to the url as specified by config.upstream_host
or config.upstream_uri
(or location B).
- Since now the location A and B are the same, the canary plugin can now be removed from the system with a
DELETE
request.
If the canary was not complete yet, then executing those steps prematurely, will instantly switch 100% of traffic to the new location (B).