1
0
mirror of https://github.com/tektoncd/catalog.git synced 2024-11-24 06:15:46 +00:00

Add Canary Release Task using K8s and Istio

The following task can be used to do canary release using K8s and Istio.

Signed-off-by: vinamra28 <vinjain@redhat.com>
This commit is contained in:
vinamra28 2020-05-15 14:32:25 +05:30 committed by tekton-robot
parent 015142c05f
commit d3a2dd5a9d
7 changed files with 317 additions and 0 deletions

View File

@ -0,0 +1,60 @@
# Canary Release using Istio
The following task can be used to do canary deployment by doing a canary traffic routing to the deployed versions.
When the new version of application is deployed, you can start routing a few selected users to it. As you gain more confidence in the new version, you can start releasing it to more servers in your infrastructure and routing more users to it.
For more details about canary release please refer [here](https://martinfowler.com/bliki/CanaryRelease.html)
### **PRE-REQUISITE**: Istio should already be installed in the same cluster.
## Installing the tasks
1. For Application Manifests deployment we can use the existing `kubenetes-actions` task from the catalog
```bash
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/kubernetes-actions/0.1/kubernetes-actions.yaml
```
2. For Istio Services
```bash
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/istio-canary-release/0.1/istio-canary-release.yaml
```
## Installing the ClusterRoleBinding
```bash
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/task/istio-canary-release/0.1/support/clusterrolebinding.yaml
```
## Workspaces
- **deployment-manifest-dir**: The workspace in which `ConfigMap` containing all the deployment manifests will be mounted.
- **istio-manifest-dir**: The workspace in which `ConfigMap` containing the istio related manifests will be mounted.
## Params for Canary-Istio-Deploy
- **VS_NAME**: The name of the `VirtualService`
- **V1_WEIGHT**: The traffic weight to be diverted to existing version v1
- **V2_WEIGHT**: The traffic weight to be diverted to new version v2
**Note**: The above parameters are used in case we need to do traffic splitting using virtual service and for creating a `VirtualService` then use the `ConfigMap` as shown below.
# Usage
1. Create `ConfigMap` for `Istio` manifests
```bash
kubectl create configmap istio --from-file="./samples/application/app-gateway.yaml"
```
2. Create `ConfigMap` for `Deployment` manifests
```bash
kubectl create configmap deployment --from-file="isto-canary-release/samples/application/myapp.yaml"
```
In case of app deployment and configuring Istio follow [this](./samples/run.yaml) example.
In case of just re-configuring the Istio follow [this](./samples/taskrun.yaml) example.

View File

@ -0,0 +1,72 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: istio-canary-release
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: canary deployment, istio
tekton.dev/displayName: "istio canary release"
spec:
description: >-
This task can be used to perform deployment of an application
using canary release strategy.
Using this task we can route the traffic to the deployments
with the help of virtual service by specifying the weights to
individual deployment.
workspaces:
- name: istio-manifest-dir
description: >-
The workspace consisting of Istio manifests such as Gateway,
DestinationRule and VirtualService in case applying for the
first time.
params:
- name: VS_NAME
description: The virtual service name to be patched
type: string
default: ""
- name: V1_WEIGHT
description: The traffic percentage to be sent to version v1
type: string
default: ""
- name: V2_WEIGHT
description: The traffic percentage to be sent to version v2
type: string
default: ""
steps:
- name: canary-deploy
image: quay.io/openshift/origin-cli:latest
workingDir: $(workspaces.istio-manifest-dir.path)
script: |
#!/usr/bin/env bash
cat <<EOF >/tmp/patch.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: $(params.VS_NAME)
spec:
hosts:
- "*"
gateways:
- app-gateway
http:
- route:
- destination:
host: myapp
subset: v1
weight: $(params.V1_WEIGHT)
- destination:
host: myapp
subset: v2
weight: $(params.V2_WEIGHT)
EOF
if [ -n "$(params.V1_WEIGHT)" -a -n "$(params.V2_WEIGHT)" ]; then
kubectl replace -f /tmp/patch.yaml
else
kubectl apply -f ./
fi

View File

@ -0,0 +1,48 @@
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: app-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "*"
gateways:
- app-gateway
http:
- route:
- destination:
host: myapp
subset: v1
weight: 20
- destination:
host: myapp
subset: v2
weight: 80

View File

@ -0,0 +1,59 @@
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
type: ClusterIP
ports:
- port: 80
name: http
selector:
app: myapp
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 1
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v2
spec:
replicas: 1
selector:
matchLabels:
app: myapp
version: v2
template:
metadata:
labels:
app: myapp
version: v2
spec:
containers:
- name: myapp
image: janakiramm/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@ -0,0 +1,49 @@
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: canary-deployment
spec:
workspaces:
- name: deployment-manifest-dir
- name: istio-manifest-dir
- name: kubeconfig-dir
tasks:
- name: app-deploy
taskRef:
name: kubernetes-actions
params:
- name: args
value:
- apply
- -f
- "."
workspaces:
- name: manifest-dir
workspace: deployment-manifest-dir
- name: kubeconfig-dir
workspace: kubeconfig-dir
- name: deploy-istio-service
taskRef:
name: istio-canary-release
runAfter:
- app-deploy
workspaces:
- name: istio-manifest-dir
workspace: istio-manifest-dir
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: canary-deployment-run
spec:
pipelineRef:
name: canary-deployment
workspaces:
- name: deployment-manifest-dir
configMap:
name: deployment
- name: istio-manifest-dir
configMap:
name: istio
- name: kubeconfig-dir
emptyDir: {}

View File

@ -0,0 +1,17 @@
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata: istio-run
spec:
taskRef:
name: istio-canary-release
params:
- name: VS_NAME
value: myapp
- name: V1_WEIGHT
value: "50"
- name: V2_WEIGHT
value: "50"
workspaces:
- name: istio-manifest-dir
configMap:
name: istio

View File

@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: default-canary
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io