-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Add TCPRoute support Signed-off-by: Philipp Plotnikov <[email protected]> * refactor: split plugin.go file content to the several files Signed-off-by: Philipp Plotnikov <[email protected]> * test: change tests Signed-off-by: Philipp Plotnikov <[email protected]> * refactor: run lint Signed-off-by: Philipp Plotnikov <[email protected]> * test: add TCPRoute tests Signed-off-by: Philipp Plotnikov <[email protected]> * docs: add documentation about TCPRoute Signed-off-by: Philipp Plotnikov <[email protected]> * refactor: change the location of httpRoute examples Signed-off-by: Philipp Plotnikov <[email protected]> --------- Signed-off-by: Philipp Plotnikov <[email protected]>
- Loading branch information
1 parent
474fe43
commit d8d5410
Showing
10 changed files
with
788 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
# Using Traefik Gateway API with Argo Rollouts | ||
|
||
This guide will describe how to use Traefik proxy an an implementation | ||
for the Gateway API in order to do split traffic with Argo Rollouts. | ||
|
||
Note that Argo Rollouts also [supports Traefik natively](https://argoproj.github.io/argo-rollouts/features/traffic-management/traefik/). | ||
|
||
## Step 1 - Enable Gateway Provider and create Gateway entrypoint | ||
|
||
Before enabling a Gateway Provider you also need to install Traefik. Follow the official [installation instructions](https://doc.traefik.io/traefik/getting-started/install-traefik/). | ||
|
||
You should also read the documentation on how [Traefik implements the Gateway API](https://doc.traefik.io/traefik/providers/kubernetes-gateway/). | ||
|
||
1. Register [Gateway API CRD](https://gateway-api.sigs.k8s.io/guides/#install-standard-channel) | ||
|
||
``` | ||
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.6.1/standard-install.yaml | ||
``` | ||
|
||
2. Create the same deployment resource with service account | ||
|
||
```yaml | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: traefik | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: argo-rollouts-traefik-lb | ||
template: | ||
metadata: | ||
labels: | ||
app: argo-rollouts-traefik-lb | ||
spec: | ||
serviceAccountName: traefik-controller | ||
containers: | ||
- name: traefik | ||
image: traefik:v2.9 | ||
args: | ||
- --entrypoints.web.address=:80 | ||
- --entrypoints.websecure.address=:443 | ||
- --experimental.kubernetesgateway | ||
- --providers.kubernetesgateway | ||
ports: | ||
- name: web | ||
containerPort: 80 | ||
``` | ||
3. Create the same ServiceAccount | ||
```yaml | ||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: traefik-controller | ||
``` | ||
4. Create Cluster Role resource with needed permissions for Gateway API provider. | ||
```yaml | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
name: traefik-controller-role | ||
namespace: aws-local-runtime | ||
rules: | ||
- apiGroups: | ||
- "*" | ||
resources: | ||
- "*" | ||
verbs: | ||
- "*" | ||
``` | ||
Note that these permission are not very strict. You should lock them down according to your needs. | ||
5. Create Cluster Role Binding | ||
With the following role we allow Traefik to have write access to Http Routes and Gateways. | ||
```yaml | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: traefik-admin | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: traefik-controller-role | ||
subjects: | ||
- namespace: default | ||
kind: ServiceAccount | ||
name: traefik-controller | ||
``` | ||
## Step 2 - Create GatewayClass and Gateway resources | ||
After we enabled the Gateway API provider in our controller we can create a GatewayClass and Gateway: | ||
- GatewayClass | ||
```yaml | ||
apiVersion: gateway.networking.k8s.io/v1beta1 | ||
kind: GatewayClass | ||
metadata: | ||
name: argo-rollouts-gateway-class | ||
spec: | ||
controllerName: traefik.io/gateway-controller | ||
``` | ||
- Gateway | ||
```yaml | ||
apiVersion: gateway.networking.k8s.io/v1beta1 | ||
kind: Gateway | ||
metadata: | ||
name: argo-rollouts-gateway | ||
spec: | ||
gatewayClassName: argo-rollouts-gateway-class | ||
listeners: | ||
- protocol: TCP | ||
name: tcp | ||
port: 80 # one of Gateway entrypoint that we created at 1 step | ||
``` | ||
## Step 3 - Create cluster entrypoint and map it with our Gateway entrypoint | ||
In different controllers entry points can be created differently. For Traefik controller we can create entry point like this: | ||
```yaml | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: argo-rollouts-traefik-lb | ||
spec: | ||
type: LoadBalancer | ||
selector: | ||
app: argo-rollouts-traefik-lb # selector of Gateway provider(step 1) | ||
ports: | ||
- protocol: TCP | ||
port: 8080 | ||
targetPort: web # map with Gateway entrypoint | ||
name: web | ||
``` | ||
This concludes the setup that is specific to Traefik Proxy. The rest of the steps are generic to any implementation of the Gateway API. | ||
## Step 4 - Create TCPRoute that defines a traffic split | ||
Create TCPRoute and connect to the created Gateway resource | ||
```yaml | ||
apiVersion: gateway.networking.k8s.io/v1beta1 | ||
kind: TCPRoute | ||
metadata: | ||
name: argo-rollouts-tcp-route | ||
spec: | ||
parentRefs: | ||
- group: gateway.networking.k8s.io | ||
kind: Gateway | ||
name: argo-rollouts-gateway | ||
sectionName: tcp | ||
rules: | ||
- backendRefs: | ||
- name: argo-rollouts-stable-service | ||
port: 80 | ||
- name: argo-rollouts-canary-service | ||
port: 80 | ||
``` | ||
## Step 5 - Create canary and stable services for your application | ||
- Canary service | ||
```yaml | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: argo-rollouts-canary-service | ||
spec: | ||
ports: | ||
- port: 80 | ||
targetPort: http | ||
protocol: TCP | ||
name: http | ||
selector: | ||
app: rollouts-demo | ||
``` | ||
- Stable service | ||
```yaml | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: argo-rollouts-stable-service | ||
spec: | ||
ports: | ||
- port: 80 | ||
targetPort: http | ||
protocol: TCP | ||
name: http | ||
selector: | ||
app: rollouts-demo | ||
``` | ||
## Step 6 - Grant argo-rollouts permissions to view and modify Gateway TCPRoute resources | ||
The argo-rollouts service account needs the ability to be able to view and mofiy TCPRoutes as well as its existing permissions. Edit the `argo-rollouts` cluster role to add the following permissions: | ||
|
||
```yaml | ||
rules: | ||
- apiGroups: | ||
- gateway.networking.k8s.io | ||
resources: | ||
- tcproutes | ||
verbs: | ||
- '*' | ||
``` | ||
|
||
## Step 7 - Create argo-rollouts resources | ||
|
||
We can finally create the definition of the application. | ||
|
||
```yaml | ||
apiVersion: argoproj.io/v1alpha1 | ||
kind: Rollout | ||
metadata: | ||
name: rollouts-demo | ||
spec: | ||
replicas: 5 | ||
strategy: | ||
canary: | ||
canaryService: argo-rollouts-canary-service # our created canary service | ||
stableService: argo-rollouts-stable-service # our created stable service | ||
trafficRouting: | ||
plugins: | ||
argoproj-labs/gatewayAPI: | ||
tcpRoute: argo-rollouts-tcp-route # our created tcproute | ||
namespace: default # namespace where this rollout resides. | ||
steps: | ||
- setWeight: 30 | ||
- pause: {} | ||
- setWeight: 40 | ||
- pause: { duration: 10 } | ||
- setWeight: 60 | ||
- pause: { duration: 10 } | ||
- setWeight: 80 | ||
- pause: { duration: 10 } | ||
revisionHistoryLimit: 2 | ||
selector: | ||
matchLabels: | ||
app: rollouts-demo | ||
template: | ||
metadata: | ||
labels: | ||
app: rollouts-demo | ||
spec: | ||
containers: | ||
- name: rollouts-demo | ||
image: argoproj/rollouts-demo:red | ||
ports: | ||
- name: http | ||
containerPort: 8080 | ||
protocol: TCP | ||
resources: | ||
requests: | ||
memory: 32Mi | ||
cpu: 5m | ||
``` | ||
|
||
Apply all the yaml files to your cluster | ||
|
||
## Step 8 - Test the canary | ||
|
||
Perform a deployment like any other Rollout and the Gateway plugin will split the traffic to your canary by instructing Traefik proxy via the Gateway API | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,69 @@ | ||
module github.com/argoproj-labs/rollouts-plugin-trafficrouter-gatewayapi | ||
|
||
go 1.19 | ||
go 1.20 | ||
|
||
require ( | ||
github.com/argoproj/argo-rollouts v1.4.0-rc1.0.20230310073321-5fef78a8e47b | ||
github.com/hashicorp/go-plugin v1.4.9 | ||
github.com/sirupsen/logrus v1.9.0 | ||
github.com/stretchr/testify v1.8.2 | ||
k8s.io/client-go v0.26.0 | ||
sigs.k8s.io/gateway-api v0.6.1 | ||
github.com/argoproj/argo-rollouts v1.5.1 | ||
github.com/hashicorp/go-plugin v1.4.10 | ||
github.com/sirupsen/logrus v1.9.3 | ||
github.com/stretchr/testify v1.8.4 | ||
k8s.io/client-go v0.28.0 | ||
sigs.k8s.io/gateway-api v0.7.1 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect | ||
github.com/fatih/color v1.12.0 // indirect | ||
github.com/fatih/color v1.15.0 // indirect | ||
github.com/google/gnostic-models v0.6.8 // indirect | ||
github.com/google/go-cmp v0.5.9 // indirect | ||
github.com/hashicorp/go-hclog v0.14.1 // indirect | ||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect | ||
github.com/imdario/mergo v0.3.13 // indirect | ||
github.com/mattn/go-colorable v0.1.12 // indirect | ||
github.com/mattn/go-isatty v0.0.14 // indirect | ||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect | ||
github.com/google/uuid v1.3.0 // indirect | ||
github.com/hashicorp/go-hclog v1.5.0 // indirect | ||
github.com/hashicorp/yamux v0.1.1 // indirect | ||
github.com/imdario/mergo v0.3.16 // indirect | ||
github.com/mattn/go-colorable v0.1.13 // indirect | ||
github.com/mattn/go-isatty v0.0.19 // indirect | ||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect | ||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
github.com/oklog/run v1.0.0 // indirect | ||
github.com/oklog/run v1.1.0 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
golang.org/x/oauth2 v0.5.0 // indirect | ||
golang.org/x/term v0.5.0 // indirect | ||
golang.org/x/oauth2 v0.11.0 // indirect | ||
golang.org/x/term v0.11.0 // indirect | ||
golang.org/x/time v0.3.0 // indirect | ||
google.golang.org/appengine v1.6.7 // indirect | ||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect | ||
google.golang.org/grpc v1.53.0 // indirect | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 // indirect | ||
google.golang.org/grpc v1.57.0 // indirect | ||
sigs.k8s.io/yaml v1.3.0 // indirect | ||
) | ||
|
||
require ( | ||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect | ||
github.com/go-logr/logr v1.2.3 // indirect | ||
github.com/go-openapi/jsonpointer v0.19.5 // indirect | ||
github.com/go-openapi/jsonreference v0.20.0 // indirect | ||
github.com/go-openapi/swag v0.21.1 // indirect | ||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect | ||
github.com/go-logr/logr v1.2.4 // indirect | ||
github.com/go-openapi/jsonpointer v0.20.0 // indirect | ||
github.com/go-openapi/jsonreference v0.20.2 // indirect | ||
github.com/go-openapi/swag v0.22.4 // indirect | ||
github.com/gogo/protobuf v1.3.2 // indirect | ||
github.com/golang/protobuf v1.5.3 // indirect | ||
github.com/google/gnostic v0.6.9 // indirect | ||
github.com/google/gofuzz v1.2.0 // indirect | ||
github.com/josharian/intern v1.0.0 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/mailru/easyjson v0.7.7 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
golang.org/x/net v0.7.0 // indirect | ||
golang.org/x/sys v0.5.0 // indirect | ||
golang.org/x/text v0.7.0 // indirect | ||
google.golang.org/protobuf v1.29.0 // indirect | ||
golang.org/x/net v0.14.0 // indirect | ||
golang.org/x/sys v0.11.0 // indirect | ||
golang.org/x/text v0.12.0 // indirect | ||
google.golang.org/protobuf v1.31.0 // indirect | ||
gopkg.in/inf.v0 v0.9.1 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
k8s.io/api v0.26.0 // indirect | ||
k8s.io/apimachinery v0.26.0 | ||
k8s.io/klog/v2 v2.80.1 // indirect | ||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect | ||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect | ||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect | ||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect | ||
k8s.io/api v0.28.0 // indirect | ||
k8s.io/apimachinery v0.28.0 | ||
k8s.io/klog/v2 v2.100.1 // indirect | ||
k8s.io/kube-openapi v0.0.0-20230816210353-14e408962443 // indirect | ||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect | ||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect | ||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect | ||
) |
Oops, something went wrong.