mirror of https://github.com/knative/docs.git
Deleting updating-existing-app.md; merging with (#166)
* Deleting blue-green-deployment.md; moving content into Updating an Existing App * Restoring blue-green-deployment.md * Deleting updating-existing-app.md; merging with blue/green sample * Updating link in README to new location
This commit is contained in:
parent
3d4ac54a57
commit
2c623deec2
|
@ -10,7 +10,7 @@ real-world Kubernetes-based frameworks and applications, such as:
|
||||||
|
|
||||||
- [Orchestrating source-to-container workflows on Kubernetes](build/README.md)
|
- [Orchestrating source-to-container workflows on Kubernetes](build/README.md)
|
||||||
- [Deploying a container to Knative](install/getting-started-knative-app.md)
|
- [Deploying a container to Knative](install/getting-started-knative-app.md)
|
||||||
- [Updating your application without downtime](serving/updating-existing-app.md)
|
- [Updating your application without downtime](serving/samples/blue-green-deployment.md)
|
||||||
- [Automatic scaling and sizing applications based on demand](serving/auto-scaling-with-knative.md)
|
- [Automatic scaling and sizing applications based on demand](serving/auto-scaling-with-knative.md)
|
||||||
- [Binding events to functions, apps, and containers with Knative](events/)
|
- [Binding events to functions, apps, and containers with Knative](events/)
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
# Advanced deploy (aka blue/green)
|
# Advanced deploy (aka blue/green)
|
||||||
|
|
||||||
Simple blue/green-like application deployment pattern illustrating process of updating live application without dropping any traffic.
|
This sample demonstrates updating an application to a new version using a
|
||||||
|
blue/green traffic routing pattern. With Knative, you can safely reroute traffic
|
||||||
|
from a live version of an application to a new version by changing the routing
|
||||||
|
configuration.
|
||||||
|
|
||||||
> Note, this demo assumes you mapped domain to your cluster. For purposes of this demo we will use `project-serverless.com`. Substitude with your own domain.
|
## Before you begin
|
||||||
|
|
||||||
## Deploy app (blue)
|
You need:
|
||||||
|
* A Kubernetes cluster with [Knative installed](../install/README.md).
|
||||||
|
* (Optional) [A custom domain configured](../serving/using-a-custom-domain.md) for use with Knative.
|
||||||
|
|
||||||
First the initial version of the applicaiton (blue). Save the beloow manifest as `stage1.yaml`
|
## Deploying Version 1 (Blue)
|
||||||
|
|
||||||
|
We'll be deploying an image of a sample application that displays the text
|
||||||
|
"App v1" on a blue background.
|
||||||
|
|
||||||
|
First, create a new file called `stage1.yaml`and copy this into it:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Route
|
kind: Route
|
||||||
metadata:
|
metadata:
|
||||||
name: route-demo
|
name: route-demo # The name of our route; appears in the URL to access the app
|
||||||
namespace: default
|
namespace: default # The namespace we're working in; also appears in the URL to access the app
|
||||||
spec:
|
spec:
|
||||||
traffic:
|
traffic:
|
||||||
- configurationName: route-demo-config-v1
|
- configurationName: route-demo-config-v1
|
||||||
percent: 100
|
percent: 100 # All traffic goes to this configutation
|
||||||
---
|
---
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Configuration
|
kind: Configuration
|
||||||
|
@ -31,39 +41,59 @@ spec:
|
||||||
knative.dev/type: container
|
knative.dev/type: container
|
||||||
spec:
|
spec:
|
||||||
container:
|
container:
|
||||||
image: gcr.io/knative-samples/knative-route-demo:blue
|
image: gcr.io/knative-samples/knative-route-demo:blue # The URL to the sample app
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
env:
|
env:
|
||||||
- name: T_VERSION
|
- name: T_VERSION
|
||||||
value: "blue"
|
value: "blue"
|
||||||
```
|
```
|
||||||
|
|
||||||
And then apply that manifest.
|
Save the file, then deploy the application to your cluster:
|
||||||
|
```bash
|
||||||
|
kubectl apply -f stage1.yaml
|
||||||
|
|
||||||
`kubectl apply -f stage1.yaml`
|
route "route-demo" configured
|
||||||
|
configuration "route-demo-config-v1" configured
|
||||||
|
```
|
||||||
|
|
||||||
When route created and IP assigned, navigate to http://route-demo.default.project-serverless.com to show deployed app. Let's call this blue (aka v1) version of the app.
|
You'll now be able to view the sample app at
|
||||||
|
http://route-demo.default.YOUR_CUSTOM_DOMAIN.com (replace `YOUR_CUSTOM_DOMAIN`)
|
||||||
|
with the [custom domain](../serving/using-a-custom-domain.md) you configured for
|
||||||
|
use with Knative.
|
||||||
|
|
||||||
## Deploy new (green) version of the app
|
> Note: If you don't have a custom domain configured for use with Knative, you can interact
|
||||||
|
with your app using cURL requests if you have the host URL and IP address:
|
||||||
|
`curl -H "Host: route-demo.default.example.com" http://IP_ADDRESS`
|
||||||
|
Knative creates the host URL by combining the name of your Route object,
|
||||||
|
the namespace, and `example.com`, if you haven't configured a custom domain.
|
||||||
|
For example, `[route-name].[namespace].example.com`.
|
||||||
|
You can get the IP address by entering `kubectl get svc knative-ingressgateway -n istio-system`
|
||||||
|
and copying the `EXTERNAL-IP` returned by that command.
|
||||||
|
See [Interacting with your app](../install/getting-started-knative-app.md#interacting-with-your-app)
|
||||||
|
for more information.
|
||||||
|
|
||||||
Again, save the following manifest representing application update to `stage2.yaml`
|
## Deploying Version 2 (Green)
|
||||||
|
|
||||||
|
Version 2 of the sample application displays the text "App v2" on a green background.
|
||||||
|
|
||||||
|
Create a new file called `stage2.yaml` and copy this into it:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Route
|
kind: Route
|
||||||
metadata:
|
metadata:
|
||||||
name: route-demo
|
name: route-demo # Route name is unchanged, since we're updating an existing Route
|
||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
traffic:
|
traffic:
|
||||||
- configurationName: route-demo-config-v1
|
- configurationName: route-demo-config-v1
|
||||||
percent: 100
|
percent: 100 # All traffic still going to the first version
|
||||||
- configurationName: route-demo-config-v2
|
- configurationName: route-demo-config-v2
|
||||||
percent: 0
|
percent: 0
|
||||||
name: v2
|
name: v2
|
||||||
---
|
---
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Configuration
|
kind: Configuration # Adding a new Configuration for the second app version
|
||||||
metadata:
|
metadata:
|
||||||
name: route-demo-config-v2
|
name: route-demo-config-v2
|
||||||
namespace: default
|
namespace: default
|
||||||
|
@ -74,90 +104,109 @@ spec:
|
||||||
knative.dev/type: container
|
knative.dev/type: container
|
||||||
spec:
|
spec:
|
||||||
container:
|
container:
|
||||||
image: gcr.io/knative-samples/knative-route-demo:green
|
image: gcr.io/knative-samples/knative-route-demo:green # URL to the second version of the app
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
env:
|
env:
|
||||||
- name: T_VERSION
|
- name: T_VERSION
|
||||||
value: "green"
|
value: "green"
|
||||||
```
|
```
|
||||||
|
|
||||||
And then apply that file to your cluster
|
This updates the existing Route's configuration to add the second configuration,
|
||||||
|
and adds the Configuration for the second version of the app. We start with zero
|
||||||
|
percent of traffic routed to Version 2.
|
||||||
|
|
||||||
`kubectl apply -f stage2.yaml`
|
Save the file, then deploy the application to your cluster:
|
||||||
|
```bash
|
||||||
|
kubectl apply -f stage2.yaml
|
||||||
|
|
||||||
This will only stage v2. That means:
|
route "route-demo" configured
|
||||||
|
configuration "route-demo-config-v2" configured
|
||||||
|
```
|
||||||
|
|
||||||
* Won't route any of v1 (blue) traffic to that new (green) version, and
|
Version 2 of the app is staged at this point. That means:
|
||||||
* Create new named route (`v2`) for testing of new the newlly deployed version
|
|
||||||
|
|
||||||
Refresh v1 (http://route-demo.default.project-serverless.com) to show our v2 takes no traffic,
|
* No traffic will be routed to version 2 at the main URL, http://route-demo.default.YOUR_CUSTOM_DOMAIN.com
|
||||||
and navigate to http://v2.route-demo.default.project-serverless.com to show the new `v2` named route.
|
* Knative creates a new route named v2 for testing the newly deployed version at http://v2.route-demo.default.YOUR_CUSTOM_DOMAIN.com
|
||||||
|
|
||||||
## Migrate portion of v1 (blew) traffic to v2 (green)
|
This allows you to validate that the new version of the app is behaving as expected before switching
|
||||||
|
any traffic over to it.
|
||||||
|
|
||||||
Now we are going to migrate traffic. Save this manofest to `stage3.yaml`
|
|
||||||
|
## Migrating traffic to the new version
|
||||||
|
|
||||||
|
Create a new file called `stage3.yaml` and copy this into it:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Route
|
kind: Route
|
||||||
metadata:
|
metadata:
|
||||||
name: route-demo
|
name: route-demo # Updating our existing route
|
||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
traffic:
|
traffic:
|
||||||
- configurationName: route-demo-config-v1
|
- configurationName: route-demo-config-v1
|
||||||
percent: 50
|
percent: 50 # Updating the percentage from 100 to 50
|
||||||
- configurationName: route-demo-config-v2
|
- configurationName: route-demo-config-v2
|
||||||
percent: 50
|
percent: 50 # Updating the percentage from 0 to 50
|
||||||
name: v2
|
name: v2
|
||||||
```
|
```
|
||||||
|
|
||||||
And then apply it
|
Save the file, then deploy the updated routing configuration to your cluster:
|
||||||
|
|
||||||
`kubectl apply -f stage3.yaml`
|
```bash
|
||||||
|
kubectl apply -f stage3.yaml
|
||||||
|
|
||||||
Refresh (a few times) the original route http://route-demo.default.project-serverless.com to show part of traffic going to v2
|
route "route-demo" configured
|
||||||
|
```
|
||||||
|
|
||||||
> Note, demo uses 50/50 split to assure you don't have to refresh too much, normally you would start with 1-2% maybe
|
Refresh the original route (http://route-demo.default.YOUR_CUSTOM_DOMAIN.com) a
|
||||||
|
few times to see that some traffic now goes to version 2 of the app.
|
||||||
|
|
||||||
## Re-route 100% of traffic to v2 (green)
|
> Note: This sample shows a 50/50 split to assure you don't have to refresh too much,
|
||||||
|
but it's recommended to start with 1-2% of traffic in a production environment
|
||||||
|
|
||||||
Finally, we will migeate all traffic to the green version. Save the following manofest to `stage4.yaml`
|
|
||||||
|
## Rerouting all traffic to the new version
|
||||||
|
|
||||||
|
Create a new file called `stage4.yaml` and copy this into it:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
apiVersion: serving.knative.dev/v1alpha1
|
||||||
kind: Route
|
kind: Route
|
||||||
metadata:
|
metadata:
|
||||||
name: route-demo
|
name: route-demo # Updating our existing route
|
||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
traffic:
|
traffic:
|
||||||
- configurationName: route-demo-config-v1
|
- configurationName: route-demo-config-v1
|
||||||
percent: 0
|
percent: 0
|
||||||
name: v1
|
name: v1 # Adding a new named route for v1
|
||||||
- configurationName: route-demo-config-v2
|
- configurationName: route-demo-config-v2
|
||||||
percent: 100
|
percent: 100
|
||||||
|
# Named route for v2 has been removed, since we don't need it anymore
|
||||||
```
|
```
|
||||||
|
|
||||||
`kubectl apply -f stage4.yaml`
|
Save the file, then deploy the updated routing configuration to your cluster:
|
||||||
|
|
||||||
This will complete the deployment by sending all traffic to the new (green) version.
|
```bash
|
||||||
|
kubectl apply -f stage4.yaml
|
||||||
|
|
||||||
Refresh original route http://route-demo.default.project-serverless.com bunch of times to show that all traffic goes to v2 (green) and v1 (blue) no longer takes traffic.
|
route "route-demo" configured
|
||||||
|
```
|
||||||
|
|
||||||
Optionally, I like to pointing out that:
|
Refresh the original route (http://route-demo.default.YOUR_CUSTOM_DOMAIN.com) a
|
||||||
|
few times to verify that no traffic is being routed to v1 of the app.
|
||||||
|
|
||||||
* I kept v1 (blue) entry with 0% traffic for speed of reverting, if ever necessary
|
We added a named route to v1 of the app, so you can now access it at
|
||||||
* I added named route `v1` to the old (blue) version of the app to allow access for comp reasons
|
http://v1.route-demo.default.YOUR_CUSTOM_DOMAIN.com.
|
||||||
|
|
||||||
Navigate to http://v1.route-demo.default.project-serverless.com to show the old version accessible by `v1` named route
|
## Cleaning up
|
||||||
|
|
||||||
|
To delete the sample app, enter the following commands:
|
||||||
## Cleanup
|
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl delete -f stage4.yaml --ignore-not-found=true
|
kubectl delete -f stage4.yaml
|
||||||
kubectl delete -f stage3.yaml --ignore-not-found=true
|
kubectl delete -f stage3.yaml
|
||||||
kubectl delete -f stage2.yaml --ignore-not-found=true
|
kubectl delete -f stage2.yaml
|
||||||
kubectl delete -f stage1.yaml --ignore-not-found=true
|
kubectl delete -f stage1.yaml
|
||||||
```
|
```
|
|
@ -1,195 +0,0 @@
|
||||||
# Updating an Existing App
|
|
||||||
|
|
||||||
This guide demonstrates how to update an application that is serving
|
|
||||||
traffic to a new version. With Knative, you can reroute traffic
|
|
||||||
from one version of an application to another by changing the routing
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
A sample app is used to demonstrate the flow of updating an
|
|
||||||
application, but the same principles can be applied to your own Knative
|
|
||||||
application.
|
|
||||||
|
|
||||||
## Before you begin
|
|
||||||
|
|
||||||
You need:
|
|
||||||
* A Kubernetes cluster with [Knative installed](../install/README.md).
|
|
||||||
* (Optional) [A custom domain configured](../serving/using-a-custom-domain.md) for use with Knative.
|
|
||||||
|
|
||||||
## Deploying the first version
|
|
||||||
|
|
||||||
We'll be deploying an image of a demo application that displays the text
|
|
||||||
"App v1" on a blue background.
|
|
||||||
|
|
||||||
First, create a new file called `stage1.yaml`and copy this into it:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Route
|
|
||||||
metadata:
|
|
||||||
name: route-demo # The name of our route; appears in the URL to access the app
|
|
||||||
namespace: default # The namespace we're working in; also appears in the URL to access the app
|
|
||||||
spec:
|
|
||||||
traffic:
|
|
||||||
- configurationName: route-demo-config-v1
|
|
||||||
percent: 100 # All traffic goes to this configutation
|
|
||||||
---
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Configuration
|
|
||||||
metadata:
|
|
||||||
name: route-demo-config-v1
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
revisionTemplate:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
knative.dev/type: container
|
|
||||||
spec:
|
|
||||||
container:
|
|
||||||
image: gcr.io/knative-samples/knative-route-demo:blue # The URL to the sample app
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: T_VERSION
|
|
||||||
value: "blue"
|
|
||||||
```
|
|
||||||
|
|
||||||
Save the file, then deploy the application to your cluster:
|
|
||||||
```bash
|
|
||||||
kubectl apply -f stage1.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
You'll now be able to view the sample app at
|
|
||||||
http://route-demo.default.YOUR_CUSTOM_DOMAIN.com (replace `YOUR_CUSTOM_DOMAIN`)
|
|
||||||
with the [custom domain](../serving/using-a-custom-domain.md) you configured for
|
|
||||||
use with Knative.
|
|
||||||
|
|
||||||
> Note: If you don't have a custom domain configured for use with Knative, you can interact
|
|
||||||
with your app using cURL requests if you have the host URL and IP address:
|
|
||||||
`curl -H "Host: route-demo.default.example.com" http://IP_ADDRESS`
|
|
||||||
Knative creates the host URL by combining the name of your Route object,
|
|
||||||
the namespace, and `example.com`, if you haven't configured a custom domain.
|
|
||||||
For example, `[route-name].[namespace].example.com`.
|
|
||||||
You can get the IP address by entering `kubectl get svc knative-ingressgateway -n istio-system`
|
|
||||||
and copying the `EXTERNAL-IP` returned by that command.
|
|
||||||
See [Interacting with your app](../install/getting-started-knative-app.md#interacting-with-your-app)
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
## Deploying the second version
|
|
||||||
|
|
||||||
Create a new file called `stage2.yaml` and copy this into it:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Route
|
|
||||||
metadata:
|
|
||||||
name: route-demo # Route name is unchanged, since we're updating an existing Route
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
traffic:
|
|
||||||
- configurationName: route-demo-config-v1
|
|
||||||
percent: 100 # All traffic still going to the first version
|
|
||||||
- configurationName: route-demo-config-v2
|
|
||||||
percent: 0
|
|
||||||
name: v2
|
|
||||||
---
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Configuration # Adding a new Configuration for the second app version
|
|
||||||
metadata:
|
|
||||||
name: route-demo-config-v2
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
revisionTemplate:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
knative.dev/type: container
|
|
||||||
spec:
|
|
||||||
container:
|
|
||||||
image: gcr.io/knative-samples/knative-route-demo:green # URL to the second version of the app
|
|
||||||
imagePullPolicy: Always
|
|
||||||
env:
|
|
||||||
- name: T_VERSION
|
|
||||||
value: "green"
|
|
||||||
```
|
|
||||||
|
|
||||||
This updates the existing Route's configuration to add the second configuration, and adds
|
|
||||||
the configuration for the second version of the app. We start with the percentage of traffic
|
|
||||||
going to the new version at zero.
|
|
||||||
|
|
||||||
Version 2 of the demo application displays the text "App v2" on a green background.
|
|
||||||
|
|
||||||
Save the file, then deploy the application to your cluster:
|
|
||||||
```bash
|
|
||||||
kubectl apply -f stage2.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Version 2 of the app is staged at this point. That means:
|
|
||||||
|
|
||||||
* No traffic will be routed version 2 at the main URL, http://route-demo.default.YOUR_CUSTOM_DOMAIN.com
|
|
||||||
* Knative creates a new route named v2 for testing the newly deployed version at http://v2.route-demo.default.YOUR_CUSTOM_DOMAIN.com
|
|
||||||
|
|
||||||
This allows you to validate that the new version of the app is behaving as expected before switching
|
|
||||||
any traffic over to it.
|
|
||||||
|
|
||||||
|
|
||||||
## Migrating traffic to the new version
|
|
||||||
|
|
||||||
Create a new file called `stage3.yaml` and copy this into it:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Route
|
|
||||||
metadata:
|
|
||||||
name: route-demo # Updating our existing route
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
traffic:
|
|
||||||
- configurationName: route-demo-config-v1
|
|
||||||
percent: 50 # Updating the percentage from 100 to 50
|
|
||||||
- configurationName: route-demo-config-v2
|
|
||||||
percent: 50 # Updating the percentage from 0 to 50
|
|
||||||
name: v2
|
|
||||||
```
|
|
||||||
|
|
||||||
Save the file, then deploy the updated routing configuration to your cluster:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f stage3.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Refresh the original route (http://route-demo.default.YOUR_CUSTOM_DOMAIN.com) a
|
|
||||||
few times to see that some traffic now goes to version 2 of the app.
|
|
||||||
|
|
||||||
> Note: This sample shows a 50/50 split to assure you don't have to refresh too much,
|
|
||||||
but it's recommended to start with 1-2% of traffic in a production environment
|
|
||||||
|
|
||||||
|
|
||||||
## Rerouting all traffic to the new version
|
|
||||||
|
|
||||||
Create a new file called `stage4.yaml` and copy this into it:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: serving.knative.dev/v1alpha1
|
|
||||||
kind: Route
|
|
||||||
metadata:
|
|
||||||
name: route-demo # Updating our existing route
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
traffic:
|
|
||||||
- configurationName: route-demo-config-v1
|
|
||||||
percent: 0
|
|
||||||
name: v1 # Adding a new named route for v1
|
|
||||||
- configurationName: route-demo-config-v2
|
|
||||||
percent: 100
|
|
||||||
# Named route for v2 has been removed, since we don't need it anymore
|
|
||||||
```
|
|
||||||
|
|
||||||
Save the file, then deploy the updated routing configuration to your cluster:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f stage4.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Refresh the original route (http://route-demo.default.YOUR_CUSTOM_DOMAIN.com) a
|
|
||||||
few times to verify that no traffic is being routed to v1 of the app.
|
|
||||||
|
|
||||||
We added a named route to v1 of the app, so you can now access it at
|
|
||||||
http://v1.route-demo.default.YOUR_CUSTOM_DOMAIN.com.
|
|
Loading…
Reference in New Issue