Publish a service as a canary instance

This topic describes how to publish an initial or an updated service as a canary instance.


To publish a service as a canary instance:

  1. Create an overlay network to isolate and secure service traffic:

    docker network create -d overlay demo
    

    Example output:

    1se1glh749q1i4pw0kf26mfx5
    
  2. Create the initial service:

    docker service create \
    --name demo-v1 \
    --network demo \
    --detach=false \
    --replicas=4 \
    --label com.docker.lb.hosts=demo.local \
    --label com.docker.lb.port=8080 \
    --env METADATA="demo-version-1" \
    mirantiseng/docker-demo
    

    Interlock detects when the service is available and publishes it.

  3. After tasks are running and the proxy service is updated, the application is available at http://demo.local:

    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    

    Example output:

    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to demo.local (127.0.0.1) port 80 (#0)
    > GET /ping HTTP/1.1
    > Host: demo.local
    > User-Agent: curl/7.54.0
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Server: nginx/1.13.6
    < Date: Wed, 08 Nov 2017 20:28:26 GMT
    < Content-Type: text/plain; charset=utf-8
    < Content-Length: 120
    < Connection: keep-alive
    < Set-Cookie: session=1510172906715624280; Path=/; Expires=Thu, 09 Nov 2017 20:28:26 GMT; Max-Age=86400
    < x-request-id: f884cf37e8331612b8e7630ad0ee4e0d
    < x-proxy-id: 5ad7c31f9f00
    < x-server-info: interlock/2.0.0-development (147ff2b1) linux/amd64
    < x-upstream-addr: 10.0.2.4:8080
    < x-upstream-response-time: 1510172906.714
    <
    {"instance":"df20f55fc943","version":"0.1","metadata":"demo-version-1","request_id":"f884cf37e8331612b8e7630ad0ee4e0d"}
    

    The value of metadata is demo-version-1.


To deploy an updated service as a canary instance:

  1. Deploy an updated service as a canary instance:

    docker service create \
    --name demo-v2 \
    --network demo \
    --detach=false \
    --label com.docker.lb.hosts=demo.local \
    --label com.docker.lb.port=8080 \
    --env METADATA="demo-version-2" \
    --env VERSION="0.2" \
    mirantiseng/docker-demo
    

    Because this has one replica and the initial version has four replicas, 20% of application traffic is sent to demo-version-2:

    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    {"instance":"23d9a5ec47ef","version":"0.1","metadata":"demo-version-1","request_id":"060c609a3ab4b7d9462233488826791c"}
    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    {"instance":"f42f7f0a30f9","version":"0.1","metadata":"demo-version-1","request_id":"c848e978e10d4785ac8584347952b963"}
    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    {"instance":"c2a686ae5694","version":"0.1","metadata":"demo-version-1","request_id":"724c21d0fb9d7e265821b3c95ed08b61"}
    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    {"instance":"1b0d55ed3d2f","version":"0.2","metadata":"demo-version-2","request_id":"b86ff1476842e801bf20a1b5f96cf94e"}
    curl -vs -H "Host: demo.local" http://127.0.0.1/ping
    {"instance":"c2a686ae5694","version":"0.1","metadata":"demo-version-1","request_id":"724c21d0fb9d7e265821b3c95ed08b61"}
    
  2. Optional. Increase traffic to the new version by adding more replicas. For example:

    docker service scale demo-v2=4
    

    Example output:

    demo-v2
    
  3. Complete the upgrade by scaling the demo-v1 service to zero replicas:

    docker service scale demo-v1=0
    

    Example output:

    demo-v1
    

    This routes all application traffic to the new version. If you need to roll back your service, scale the v1 service back up and the v2 service back down.