Skip to content

Commit

Permalink
add linkerd example with header baed routing
Browse files Browse the repository at this point in the history
Signed-off-by: Alon Gluz <[email protected]>
  • Loading branch information
AlonGluz committed Nov 11, 2024
1 parent 420ef9a commit 4e365c0
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 0 deletions.
92 changes: 92 additions & 0 deletions examples/linkerd-header-based/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Using Linkerd with Argo Rollouts

[Linkerd](https://linkerd.io/) is a service mesh for Kubernetes. It makes running services easier and safer by giving you runtime debugging, observability, reliability, and security—all without requiring any changes to your code.

## Prerequisites

A Kubernetes cluster. If you do not have one, you can create one using [kind](https://kind.sigs.k8s.io/), [minikube](https://minikube.sigs.k8s.io/), or any other Kubernetes cluster. This guide will use Kind.

Linkerd installed in your Kubernetes cluster.


## Step 1 - Create a Kind cluster by running the following command:

```shell
kind delete cluster &>/dev/null
kind create cluster --config ./kind-cluster.yaml
```

## Step 2 - Install Linkerd and Linkerd Viz by running the following commands:

I will use the Linkerd CLI to install Linkerd in the cluster. You can also install Linkerd using Helm or kubectl.
I tested this guide with Linkerd version 2.13.0

```shell
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f - && linkerd check
linkerd viz install | kubectl apply -f - && linkerd check
```


## Step 3 - Install Argo Rollouts and Argo Rollouts plugin to allow Linkerd to manage the traffic:

```shell
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
kubectl apply -k https://github.com/argoproj/argo-rollouts/manifests/crds\?ref\=stable
kubectl apply -f argo-rollouts-plugin.yaml
kubectl rollout restart deploy -n argo-rollouts
```

## Step 4 - Grant Argo Rollouts SA access to the Gateway/Http Route
```shell
kubectl apply -f cluster-role.yaml
```
__Note:__ These permission are very permissive. You should lock them down according to your needs.

With the following role we allow Argo Rollouts to have Admin access to HTTPRoutes and Gateways.

```shell
kubectl apply -f cluster-role-binding.yaml
```
## Step 5 - Create HTTPRoute that defines a traffic split between two services

Create HTTPRoute and connect to the created Gateway resource

```shell
kubectl apply -f httproute.yaml
```
## Step 6 - Create the services required for traffic split

Create three Services required for canary based rollout stratedy

```shell
kubectl apply -f service.yaml
```

## Step 7 - Create the services required for traffic split

Add Linkerd annotaions to the namespace where the services are deployed

```shell
kubectl apply -f namespace.yaml
```

## Step 8 - Create an example Rollout

Deploy a rollout to get the initial version.
```shell
kubectl apply -f rollout.yaml
```

## Step 9 - Watch the rollout
```shell
watch "kubectl -n default get httproute.gateway.networking.k8s.io/argo-rollouts-http-route -o custom-columns=NAME:.metadata.name,PRIMARY_SERVICE:.spec.rules[0].backendRefs[0].name,PRIMARY_WEIGHT:.spec.rules[0].backendRefs[0].weight,CANARY_SERVICE:.spec.rules[0].backendRefs[1].name,CANARY_WEIGHT:.spec.rules[0].backendRefs[1].weight"
```

## Step 10 - Patch the rollout to see the canary deployment
```shell
kubectl patch rollout rollouts-demo --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/env/0/value", "value": "1.1.0"}]'
```


10 changes: 10 additions & 0 deletions examples/linkerd-header-based/argo-rollouts-plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argo-rollouts-config # must be so name
namespace: argo-rollouts # must be in this namespace
data:
trafficRouterPlugins: |-
- name: "argoproj-labs/gatewayAPI"
location: "https://github.com/argoproj-labs/rollouts-plugin-trafficrouter-gatewayapi/releases/download/v0.2.0/gateway-api-plugin-linux-arm64"
13 changes: 13 additions & 0 deletions examples/linkerd-header-based/cluster-role-binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: gateway-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gateway-controller-role
subjects:
- namespace: argo-rollouts
kind: ServiceAccount
name: argo-rollouts
13 changes: 13 additions & 0 deletions examples/linkerd-header-based/cluster-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: gateway-controller-role
namespace: argo-rollouts
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "*"
22 changes: 22 additions & 0 deletions examples/linkerd-header-based/httproute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: argo-rollouts-http-route
namespace: default
spec:
parentRefs:
- group: "core"
name: argo-rollouts-service
kind: Service
port: 80
rules:
- backendRefs:
- name: argo-rollouts-stable-service
group: "core"
port: 80
kind: Service
- name: argo-rollouts-canary-service
group: "core"
port: 80
kind: Service
17 changes: 17 additions & 0 deletions examples/linkerd-header-based/kind-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
8 changes: 8 additions & 0 deletions examples/linkerd-header-based/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: default
annotations:
linkerd.io/inject: enabled
spec: {}
54 changes: 54 additions & 0 deletions examples/linkerd-header-based/rollout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
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:
httpRoute: argo-rollouts-http-route # our created httproute
namespace: default # namespace where this rollout resides
useHeaderRoutes: true
steps:
- pause: {}
- setCanaryScale:
replicas: 1
- setHeaderRoute:
name: header-route
match:
- headerName: X-Test
headerValue:
exact: test
- pause: {}
- setHeaderRoute: # remove header route
name: header-route

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
env:
- name: APP_VERSION
value: "1.0.0"
resources:
requests:
memory: 32Mi
cpu: 5m
33 changes: 33 additions & 0 deletions examples/linkerd-header-based/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
apiVersion: v1
kind: Service
metadata:
name: argo-rollouts-service
spec:
ports:
- port: 80
targetPort: http
selector:
app: rollouts-demo
---
apiVersion: v1
kind: Service
metadata:
name: argo-rollouts-canary-service
spec:
ports:
- port: 80
targetPort: http
selector:
app: rollouts-demo
---
apiVersion: v1
kind: Service
metadata:
name: argo-rollouts-stable-service
spec:
ports:
- port: 80
targetPort: http
selector:
app: rollouts-demo
18 changes: 18 additions & 0 deletions examples/linkerd-header-based/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
kind delete cluster &>/dev/null
kind create cluster --config manifests/kind-cluster.yaml
kubectl ns default

linkerd install --crds | kubectl apply -f -

linkerd install | kubectl apply -f - && linkerd check

linkerd viz install | kubectl apply -f - && linkerd check

kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
kubectl apply -k https://github.com/argoproj/argo-rollouts/manifests/crds\?ref\=stable

kubectl apply -k manifests/
kubectl rollout restart deploy -n argo-rollouts

11 changes: 11 additions & 0 deletions examples/linkerd-header-based/steps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# watch Route
kubectl -n argo-demo get httproute.gateway.networking.k8s.io/argo-rollouts-http-route -o custom-columns=NAME:.metadata.name,PRIMARY_SERVICE:.spec.rules[0].backendRefs[0].name,PRIMARY_WEIGHT:.spec.rules[0].backendRefs[0].weight,CANARY_SERVICE:.spec.rules[0].backendRefs[1].name,CANARY_WEIGHT:.spec.rules[0].backendRefs[1].weight

# View traffic
linkerd viz -n argo-demo stat rs --from deploy/slow-cooker

# View Rollout
kubectl argo rollouts -n argo-demo get rollout rollouts-demo

watch k argo rollouts -n argo-demo get rollout rollouts-demo

0 comments on commit 4e365c0

Please sign in to comment.