An open API service indexing awesome lists of open source software.

https://github.com/cloudacademy/knative-demo

Knative Demo
https://github.com/cloudacademy/knative-demo

async devops eventdriven knative kubernetes microservices serverless

Last synced: 11 months ago
JSON representation

Knative Demo

Awesome Lists containing this project

README

          

# Knative Deployment Instructions

The following instructions are used to demonstrate Knative Serving and Eventing configurations.

**Note**: The following instructions require a K8s cluster with a LoadBalancer service which exposes a publicly routable IPv4 address. Consider using a cluster hosted on EKS, GKE, or AKS.

**Update** (Wed 25 Nov 2020) - instructions upgraded to work with the following versions:
- Kubernetes: `v1.18.10`
- Istio: `v1.8.0`
- Knative: `v0.19.0`

# STEP 1:

Install Knative

## STEP 1.1:

Download and install ```istioctl``` command locally. This is used to now install Istio into the Kubernetes cluster:

```
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.8.0/bin
cp istioctl /usr/local/bin/
```

List the available Istio configuration [profiles](https://istio.io/latest/docs/setup/additional-setup/config-profiles/):

```
istioctl profile list
```

Install the **default** Istio configuration profile:

```
istioctl install --set profile=default -y
```

## STEP 1.2:

The following commands can be used to troubleshoot Istio installations:

```
kubectl get ns
kubectl get pods -n istio-system
kubectl get pods -n istio-system --watch
kubectl describe pod -n istio-system
kubectl describe deploy -n istio-system
```

## STEP 1.3:

Install Knative Serving

* Serving CRDs
* Serving Core Components
* Knative Istio Controller needed for Serving

```
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-crds.yaml
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-core.yaml
kubectl apply --filename https://github.com/knative/net-istio/releases/download/v0.19.0/release.yaml
```

## STEP 1.4:

Check Knative Serving pods are running

```
kubectl get pods -n knative-serving
```

## STEP 1.5:

Setup xip.io for custom domain - provides wildcarded dynamic dns

```
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.19.0/serving-default-domain.yaml

```

## STEP 1.6:

Install Eventing

* Eventing CRDs
* Eventing Core
* Default InMemory Channel (not suitable for production)
* Default Broker

```
kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/eventing-crds.yaml
kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/eventing-core.yaml
kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/in-memory-channel.yaml
kubectl apply --filename https://github.com/knative/eventing/releases/download/v0.19.0/mt-channel-broker.yaml
```

## STEP 1.7:

Check Eventing pods are running

```
kubectl get pods -n knative-eventing
```

# STEP 2:

Create the ```cloudacademy``` namespace

```
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: cloudacademy
labels:
name: cloudacademy
EOF
```

Configure the ```cloudacademy``` namespace to be the default

```
kubectl config set-context --current --namespace cloudacademy
```

# Step 3

Deploy Example Knative Service

# Step 3.1

Install example helloworld service

```
for version in {1..2}; do
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hellosvc
namespace: cloudacademy
spec:
template:
metadata:
name: hellosvc-v$version
spec:
containers:
- image: docker.io/cloudacademydevops/helloworld:v1
env:
- name: SENDER
value: "cloudacademy.knative.v$version"
EOF
done
```

Test the ```hellosvc``` knative service

```
kubectl get ksvc

HELLO_SVC_URL=$(kubectl get ksvc/hellosvc -o jsonpath="{.status.url}")
echo $HELLO_SVC_URL

curl $HELLO_SVC_URL/hello
```

Display current revisions

```
kubectl get revision
```

# Step 3.2

Install example helloworld service with traffic splitting

```
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hellosvc
namespace: cloudacademy
spec:
template:
metadata:
name: hellosvc-v3
spec:
containers:
- image: docker.io/cloudacademydevops/helloworld:v1
env:
- name: SENDER
value: "cloudacademy.knative.v3"
traffic:
- tag: prod
revisionName: hellosvc-v3
percent: 50
- tag: staging
revisionName: hellosvc-v2
percent: 50
- tag: latest
latestRevision: true
percent: 0
EOF
```

Test the ```hellosvc``` knative service traffic splitting

```
kubectl get ksvc

HELLO_SVC_URL=$(kubectl get ksvc/hellosvc -o jsonpath="{.status.url}")
echo $HELLO_SVC_URL

for i in {1..10}; do
curl $HELLO_SVC_URL/hello
done
```

Test tag based urls

```
HELLO_SVC_URL_PROD=${HELLO_SVC_URL/hellosvc/prod-hellosvc}
curl $HELLO_SVC_URL_PROD/hello

HELLO_SVC_URL_STAGING=${HELLO_SVC_URL/hellosvc/staging-hellosvc}
curl $HELLO_SVC_URL_STAGING/hello
```

```
kubectl get revision
```

# Step 4

Configure knative autoscaling using kpa and 2 requests in-flight per pod

```
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hellosvc
namespace: cloudacademy
spec:
template:
metadata:
name: hellosvc-v4
annotations:
# 2 requests in-flight per pod - for testing
autoscaling.knative.dev/class: kpa.autoscaling.knative.dev
autoscaling.knative.dev/metric: concurrency
autoscaling.knative.dev/target: "2"
autoscaling.knative.dev/minScale: "0"
autoscaling.knative.dev/maxScale: "20"
spec:
containers:
- image: docker.io/cloudacademydevops/helloworld:v4
imagePullPolicy: Always
env:
- name: SENDER
value: "cloudacademy.knative.v4"
EOF
```

Send 20 concurrent curl requests to service - 5 times - for a total of 100 requests

```
for i in {1..100}; do echo $HELLO_SVC_URL/hello?id=$i; done | xargs -P 20 -n 1 curl
```

Examine pods

Note: All pods should eventually scale to zero (terminate) when traffic has completed. Rerunning the previous command will cause the pods to auto scale out to a maximum of 20 to serve the incoming traffic.

```
kubectl get pods --watch
```

# Step 5

Install Eventing - Source to Sink

## Step 5.1

Install PingSource

```
cat << EOF | kubectl apply -f -
apiVersion: sources.knative.dev/v1alpha2
kind: PingSource
metadata:
name: ping-cloudacademy
namespace: cloudacademy
spec:
schedule: "* * * * *"
jsonData: '{"message": "knative rocks!!"}'
sink:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service
EOF
```

## Step 5.2

Install Service - SimpleLogger

```
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service-v1
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
EOF
```

## Step 5.3

Examine SimpleLogger pod log

```
SIMPLELOGGER_POD=$(kubectl get pod -l app=cloudacademy-service-v1 --no-headers=true -o custom-columns=:metadata.name)
echo $SIMPLELOGGER_POD

kubectl logs $SIMPLELOGGER_POD -c user-container --follow
```

# Step 6

Install Eventing - Channel and Subscription

## Step 6.1

Install InMemoryChannel

```
cat << EOF | kubectl apply -f -
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
metadata:
name: cloudacademy-channel
namespace: cloudacademy
EOF
```

## Step 6.2

Install PingSource

```
cat << EOF | kubectl apply -f -
apiVersion: sources.knative.dev/v1alpha2
kind: PingSource
metadata:
name: ping-cloudacademy
namespace: cloudacademy
spec:
schedule: "* * * * *"
jsonData: '{"message": "knative rocks!!", "from": "pingsource - channelsub"}'
sink:
ref:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
name: cloudacademy-channel
EOF
```

## Step 6.3

Install 2x Service - SimpleLogger

```
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service1
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service1-v1
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service2
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service2-v1
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
EOF
```

## Step 6.4

Install 2x Subscription

```
cat << EOF | kubectl apply -f -
apiVersion: messaging.knative.dev/v1
kind: Subscription
metadata:
name: cloudacademy-sub1
namespace: cloudacademy
spec:
channel:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
name: cloudacademy-channel
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service1
---
apiVersion: messaging.knative.dev/v1
kind: Subscription
metadata:
name: cloudacademy-sub2
namespace: cloudacademy
spec:
channel:
apiVersion: messaging.knative.dev/v1
kind: InMemoryChannel
name: cloudacademy-channel
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service2
EOF
```

## Step 6.5

Examine SimpleLogger pods - log

```
SIMPLELOGGER_SVC1_POD=$(kubectl get pod -l app=cloudacademy-service1-v1 --no-headers=true -o custom-columns=:metadata.name)
SIMPLELOGGER_SVC2_POD=$(kubectl get pod -l app=cloudacademy-service2-v1 --no-headers=true -o custom-columns=:metadata.name)

echo $SIMPLELOGGER_SVC1_POD
echo $SIMPLELOGGER_SVC2_POD

kubectl logs $SIMPLELOGGER_SVC1_POD -c user-container --follow
kubectl logs $SIMPLELOGGER_SVC2_POD -c user-container --follow
```

# Step 7

Install Eventing - Broker and Trigger

## Step 7.1

Configure automatic knative eventing injection

```
kubectl label ns cloudacademy knative-eventing-injection=enabled
```

Install default Broker

```
cat << EOF | kubectl apply -f -
apiVersion: eventing.knative.dev/v1
kind: broker
metadata:
name: default
namespace: cloudacademy
EOF
```

Get the broker url for the cloudacademy namespace

```
kubectl config set-context --current --namespace cloudacademy
kubectl get broker default
```

## Step 7.2

Install PingSource

```
cat << EOF | kubectl apply -f -
apiVersion: sources.knative.dev/v1alpha2
kind: PingSource
metadata:
name: ping-cloudacademy
namespace: cloudacademy
spec:
schedule: "* * * * *"
jsonData: '{"message": "knative rocks!!", "from": "pingsource - brokertrigger"}'
sink:
ref:
apiVersion: eventing.knative.dev/v1
kind: Broker
name: default
EOF
```

## Step 7.3

Install 3x Service - SimpleLogger

```
cat << EOF | kubectl apply -f -
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service1
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service1-v1
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service2
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service2-v1
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
---
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: cloudacademy-service3
namespace: cloudacademy
spec:
template:
metadata:
name: cloudacademy-service3-v1
annotations:
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: cloudacademydevops/simplelogger:v1
ports:
- containerPort: 8080
EOF
```

## Step 7.4

Install 3x Trigger

```
cat << EOF | kubectl apply -f -
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: cloudacademy-trigger1
namespace: cloudacademy
spec:
broker: default
filter:
attributes:
type: dev.knative.sources.ping
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service1
---
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: cloudacademy-trigger2
namespace: cloudacademy
spec:
broker: default
filter:
attributes:
type: dev.knative.sources.ping
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service2
---
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
name: cloudacademy-trigger3
namespace: cloudacademy
spec:
broker: default
filter:
attributes:
type: cloudacademy.app.blah
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: cloudacademy-service3
EOF
```

## Step 7.5

Create Curler Pod

```
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
labels:
run: curler
name: curler
namespace: cloudacademy
spec:
containers:
- name: curler
image: fedora:latest
tty: true
EOF
```

## Step 7.6

Retrieve broker url

```
BROKER_URL=$(kubectl get broker default -o jsonpath='{.status.address.url}')
echo BROKER_URL: $BROKER_URL
```

## Step 7.7

Perform an HTTP POST - send CloudEvent message

```
kubectl exec -it curler -- curl -v $BROKER_URL \
-H "Ce-Id: say-hello" \
-H "Ce-Specversion: 1.0" \
-H "Ce-Type: cloudacademy.app.blah" \
-H "Ce-Source: mycurl" \
-H "Content-Type: application/json" \
-d '{"key":"curl cloudevent message!!"}'
```

## Step 7.8

Examine SimpleLogger pods - log

```
SIMPLELOGGER_SVC1_POD=$(kubectl get pod -l app=cloudacademy-service1-v1 --no-headers=true -o custom-columns=:metadata.name)
SIMPLELOGGER_SVC2_POD=$(kubectl get pod -l app=cloudacademy-service2-v1 --no-headers=true -o custom-columns=:metadata.name)
SIMPLELOGGER_SVC3_POD=$(kubectl get pod -l app=cloudacademy-service3-v1 --no-headers=true -o custom-columns=:metadata.name)

echo $SIMPLELOGGER_SVC1_POD
echo $SIMPLELOGGER_SVC2_POD
echo $SIMPLELOGGER_SVC3_POD

kubectl logs $SIMPLELOGGER_SVC1_POD -c user-container --follow
kubectl logs $SIMPLELOGGER_SVC2_POD -c user-container --follow
kubectl logs $SIMPLELOGGER_SVC3_POD -c user-container --follow
```