Skip to content

Commit

Permalink
feat: Apache APISIX support. Fixes argoproj#2395 (argoproj#2437)
Browse files Browse the repository at this point in the history
* feat: Apache APISIX support

Signed-off-by: Gallardot <[email protected]>

* feat: Apache APISIX support

Signed-off-by: Gallardot <[email protected]>

* feat: Improve the apisix route

Signed-off-by: Gallardot <[email protected]>

* chore: add apisix doc and examples

Signed-off-by: Gallardot <[email protected]>

* chore: add apisix doc and examples

Signed-off-by: Gallardot <[email protected]>

* chore: add UT

Signed-off-by: Gallardot <[email protected]>

* doc: update README

Signed-off-by: Gallardot <[email protected]>

Signed-off-by: Gallardot <[email protected]>
  • Loading branch information
Gallardot authored and Travis Perdue committed Jan 12, 2023
1 parent a588b31 commit fc4bb12
Show file tree
Hide file tree
Showing 32 changed files with 2,812 additions and 117 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ cmd/**/debug
debug.test
coverage.out
coverage.html
junit.xml
rerunreport.txt
site/
vendor/
# generated
Expand Down
33 changes: 19 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@

# Argo Rollouts - Progressive Delivery for Kubernetes

[![codecov](https://codecov.io/gh/argoproj/argo-rollouts/branch/master/graph/badge.svg)](https://codecov.io/gh/argoproj/argo-rollouts)
[![slack](https://img.shields.io/badge/slack-argoproj-brightgreen.svg?logo=slack)](https://argoproj.github.io/community/join-slack)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3834/badge)](https://bestpractices.coreinfrastructure.org/projects/3834)
[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/argo-rollouts)](https://artifacthub.io/packages/helm/argo/argo-rollouts)

## What is Argo Rollouts?
Argo Rollouts is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes.

Argo Rollouts is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes.

Argo Rollouts (optionally) integrates with ingress controllers and service meshes, leveraging their traffic shaping abilities to gradually shift traffic to the new version during an update. Additionally, Rollouts can query and interpret metrics from various providers to verify key KPIs and drive automated promotion or rollback during an update.

[![Argo Rollotus Demo](https://img.youtube.com/vi/hIL0E2gLkf8/0.jpg)](https://youtu.be/hIL0E2gLkf8)

## Quick Start

```
```bash
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
```

Follow the full [getting started guide](docs/getting-started.md) to walk through creating and then updating a rollout object.
Follow the full [getting started guide](docs/getting-started.md) to walk through creating and then updating a rollout object.

## Why Argo Rollouts?

Kubernetes Deployments provides the `RollingUpdate` strategy which provide a basic set of safety guarantees (readiness probes) during an update. However the rolling update strategy faces many limitations:

* Few controls over the speed of the rollout
* Inability to control traffic flow to the new version
* Readiness probes are unsuitable for deeper, stress, or one-time checks
Expand All @@ -32,6 +36,7 @@ Kubernetes Deployments provides the `RollingUpdate` strategy which provide a bas
For these reasons, in large scale high-volume production environments, a rolling update is often considered too risky of an update procedure since it provides no control over the blast radius, may rollout too aggressively, and provides no automated rollback upon failures.

## Features

* Blue-Green update strategy
* Canary update strategy
* Fine-grained, weighted traffic shifting
Expand All @@ -43,23 +48,25 @@ For these reasons, in large scale high-volume production environments, a rolling
* Metric provider integration: Prometheus, Wavefront, Kayenta, Web, Kubernetes Jobs, Datadog, New Relic, InfluxDB

## Supported Traffic Shaping Integrations
| Traffic Shaping Integration | SetWeight | SetWeightExperiments | SetMirror | SetHeader |
|------------------------------|------------------------------|-----------------------------|----------------------------|----------------------------|
| ALB Ingress Controller | :white_check_mark: (stable) | :white_check_mark: (stable) | :x: | :white_check_mark: (alpha) |
| Ambassador | :white_check_mark: (stable) | :x: | :x: | :x: |
| Istio | :white_check_mark: (stable) | :white_check_mark: (stable) | :white_check_mark: (alpha) | :white_check_mark: (alpha) |
| Nginx Ingress Controller | :white_check_mark: (stable) | :x: | :x: | :x: |
| SMI | :white_check_mark: (stable) | :white_check_mark: (stable) | :x: | :x: |
| Traefik | :white_check_mark: (beta) | :x: | :x: | :x: |
| Traffic Shaping Integration | SetWeight | SetWeightExperiments | SetMirror | SetHeader |
|-----------------------------------|------------------------------|-----------------------------|----------------------------|----------------------------|
| ALB Ingress Controller | :white_check_mark: (stable) | :white_check_mark: (stable) | :x: | :white_check_mark: (alpha) |
| Ambassador | :white_check_mark: (stable) | :x: | :x: | :x: |
| Apache APISIX Ingress Controller | :white_check_mark: (alpha) | :x: | :x: | :x: |
| Istio | :white_check_mark: (stable) | :white_check_mark: (stable) | :white_check_mark: (alpha) | :white_check_mark: (alpha) |
| Nginx Ingress Controller | :white_check_mark: (stable) | :x: | :x: | :x: |
| SMI | :white_check_mark: (stable) | :white_check_mark: (stable) | :x: | :x: |
| Traefik | :white_check_mark: (beta) | :x: | :x: | :x: |

:white_check_mark: = Supported

:x: = Not Supported

## Documentation

To learn more about Argo Rollouts go to the [complete documentation](https://argoproj.github.io/argo-rollouts/).

## Community
## Community

You can reach the Argo Rollouts community and developers via the following channels:

Expand Down Expand Up @@ -89,5 +96,3 @@ You can reach the Argo Rollouts community and developers via the following chann
* [How Scalable is Argo-Rollouts: A Cloud Operator’s Perspective](https://www.youtube.com/watch?v=rCEhxJ2NSTI)
* [Minimize Impact in Kubernetes Using Argo Rollouts](https://medium.com/@arielsimhon/minimize-impact-in-kubernetes-using-argo-rollouts-992fb9519969)
* [Progressive Application Delivery with GitOps on Red Hat OpenShift](https://www.youtube.com/watch?v=DfeL7cdTx4c)


186 changes: 186 additions & 0 deletions docs/features/traffic-management/apisix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Apache APISIX

You can use the [Apache APISIX](https://apisix.apache.org/) and [Apache APISIX Ingress Controller](https://apisix.apache.org/docs/ingress-controller/getting-started/) for traffic management with Argo Rollouts.

The [ApisixRoute](https://apisix.apache.org/docs/ingress-controller/concepts/apisix_route/) is the object that supports the ability for [weighted round robin load balancing](https://apisix.apache.org/docs/ingress-controller/concepts/apisix_route/#weight-based-traffic-split) when using Apache APISIX Ingress Controller as ingress.

This guide shows you how to integrate ApisixRoute with Argo Rollouts using it as weighted round robin load balancer

## Prerequisites

Argo Rollouts requires Apache APISIX v2.15 or newer and Apache APISIX Ingress Controller v1.5.0 or newer.

Install Apache APISIX and Apache APISIX Ingress Controller with Helm v3:

```bash
helm repo add apisix https://charts.apiseven.com
kubectl create ns apisix

helm upgrade -i apisix apisix/apisix --version=0.11.3 \
--namespace apisix \
--set ingress-controller.enabled=true \
--set ingress-controller.config.apisix.serviceNamespace=apisix
```

## Bootstrap

First, we need to create the ApisixRoute object using its ability for weighted round robin load balancing.

```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: rollouts-apisix-route
spec:
http:
- name: rollouts-apisix
match:
paths:
- /*
hosts:
- rollouts-demo.apisix.local
backends:
- serviceName: rollout-apisix-canary-stable
servicePort: 80
- serviceName: rollout-apisix-canary-canary
servicePort: 80
```
```bash
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/examples/apisix/route.yaml
```

Notice, we don't specify the `weight` field. It is necessary to be synced with ArgoCD. If we specify this field and Argo Rollouts controller changes it, then the ArgoCD controller will notice it and will show that this resource is out of sync (if you are using Argo CD to manage your Rollout).

Secondly, we need to create the Argo Rollouts object.

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollout-apisix-canary
spec:
replicas: 5
strategy:
canary:
canaryService: rollout-apisix-canary-canary
stableService: rollout-apisix-canary-stable
trafficRouting:
apisix:
route:
name: rollouts-apisix-route
rules:
- rollouts-apisix
steps:
- setWeight: 20
- pause: {}
- setWeight: 40
- pause:
duration: 15
- setWeight: 60
- pause:
duration: 15
- setWeight: 80
- pause:
duration: 15
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollout-apisix-canary
template:
metadata:
labels:
app: rollout-apisix-canary
spec:
containers:
- name: rollout-apisix-canary
image: argoproj/rollouts-demo:blue
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 5m
```
```bash
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/examples/apisix/rollout.yaml
```

Finally, we need to create the services for the Argo Rollouts object.

```yaml
apiVersion: v1
kind: Service
metadata:
name: rollout-apisix-canary-canary
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollout-apisix-canary
# This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
# rollouts-pod-template-hash: 7bf84f9696
---
apiVersion: v1
kind: Service
metadata:
name: rollout-apisix-canary-stable
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollout-apisix-canary
# This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
# rollouts-pod-template-hash: 789746c88d
```

```bash
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/examples/apisix/services.yaml
```

Initial creations of any Rollout will immediately scale up the replicas to 100% (skipping any canary upgrade steps, analysis, etc...) since there was no upgrade that occurred.

The Argo Rollouts kubectl plugin allows you to visualize the Rollout, its related resources (ReplicaSets, Pods, AnalysisRuns), and presents live state changes as they occur. To watch the rollout as it deploys, run the get rollout --watch command from plugin:

```bash
kubectl argo rollouts get rollout rollout-apisix-canary --watch
```

## Updating a Rollout

Next it is time to perform an update. Just as with Deployments, any change to the Pod template field (`spec.template`) results in a new version (i.e. ReplicaSet) to be deployed. Updating a Rollout involves modifying the rollout spec, typically changing the container image field with a new version, and then running `kubectl apply` against the new manifest. As a convenience, the rollouts plugin provides a `set image` command, which performs these steps against the live rollout object in-place. Run the following command to update the `rollout-apisix-canary` Rollout with the "yellow" version of the container:

```shell
kubectl argo rollouts set image rollout-apisix-canary \
rollout-apisix-canary=argoproj/rollouts-demo:yellow
```

During a rollout update, the controller will progress through the steps defined in the Rollout's update strategy. The example rollout sets a 20% traffic weight to the canary, and pauses the rollout indefinitely until user action is taken to unpause/promote the rollout.

You can check ApisixRoute's backend weights by the following command
```bash
kubectl describe apisixroute rollouts-apisix-route

......
Spec:
Http:
Backends:
Service Name: rollout-apisix-canary-stable
Service Port: 80
Weight: 80
Service Name: rollout-apisix-canary-canary
Service Port: 80
Weight: 20
......
```

The `rollout-apisix-canary-canary` service gets 20% traffic through the Apache APISIX.
1 change: 1 addition & 0 deletions docs/features/traffic-management/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Argo Rollouts enables traffic management by manipulating the Service Mesh resour

- [AWS ALB Ingress Controller](alb.md)
- [Ambassador Edge Stack](ambassador.md)
- [Apache APISIX](apisix.md)
- [Istio](istio.md)
- [Nginx Ingress Controller](nginx.md)
- [Service Mesh Interface (SMI)](smi.md)
Expand Down
48 changes: 48 additions & 0 deletions examples/apisix/rollout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: rollout-apisix-canary
spec:
replicas: 5
strategy:
canary:
canaryService: rollout-apisix-canary-canary
stableService: rollout-apisix-canary-stable
trafficRouting:
apisix:
route:
name: rollouts-apisix-route
rules:
- rollouts-apisix
steps:
- setWeight: 20
- pause: { }
- setWeight: 40
- pause:
duration: 15
- setWeight: 60
- pause:
duration: 15
- setWeight: 80
- pause:
duration: 15
revisionHistoryLimit: 2
selector:
matchLabels:
app: rollout-apisix-canary
template:
metadata:
labels:
app: rollout-apisix-canary
spec:
containers:
- name: rollouts-demo
image: argoproj/rollouts-demo:blue
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
requests:
memory: 32Mi
cpu: 5m
23 changes: 23 additions & 0 deletions examples/apisix/route.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: rollouts-apisix-route
spec:
http:
- name: rollouts-apisix
match:
paths:
- /*
methods:
- GET
- POST
- PUT
- DELETE
- PATCH
hosts:
- rollouts-demo.apisix.local
backends:
- serviceName: rollout-apisix-canary-stable
servicePort: 80
- serviceName: rollout-apisix-canary-canary
servicePort: 80
29 changes: 29 additions & 0 deletions examples/apisix/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: v1
kind: Service
metadata:
name: rollout-apisix-canary-canary
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollout-apisix-canary
# This selector will be updated with the pod-template-hash of the canary ReplicaSet. e.g.:
# rollouts-pod-template-hash: 7bf84f9696
---
apiVersion: v1
kind: Service
metadata:
name: rollout-apisix-canary-stable
spec:
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: rollout-apisix-canary
# This selector will be updated with the pod-template-hash of the stable ReplicaSet. e.g.:
# rollouts-pod-template-hash: 789746c88d
Loading

0 comments on commit fc4bb12

Please sign in to comment.