Devoxx UK 2019 - Knative demo
- Create GKE cluster fronted by DNS
- Update docker-secret.yaml with Docker Hub credentials.
kubectl apply -f setupto create secret with Docker Hub credentials associated with
kubectl apply -f https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
- Follow the setup instructions in the GCP Pub/Sub Knative sample.
Deploy Knative service
- helloworld.go is a simple Go web server. Note the use of
PORTpassed in by Knative.
- It has been built with Dockerfile and pushed to Docker Hub at
- service.yaml defines a Knative service which specifies the Docker image in its configuration along with an environment variable that is output in the response.
kubectl apply -f service.yaml
curl helloworld-go.default.knative.currie.cloudshould return
v1: Hello World!.
Deploy a second revision of the service
curl helloworld-go.default.knative.currie.cloudshould now return
v2: Hello World!. A new revision of the service has been created and, because we are using
runLatestin the service definition, requests are automatically routed to the new revision once it has become available.
Unlike, say, a Function-as-a-Service platform, container instances are expected to handle multiple requests and, by default, handle concurrent requests.
- By default, the number of pods for a revision scales down to zero. This can be great as it means old revisions to which traffic is no longer being routed don't cost anything. It may not be desirable though if traffic is the container for a service takes time to become ready. Add the annotation
autoscaling.knative.dev/minScale: "2"and re-apply the
kubectl get podshould now show two pods for the latest revision.
- By default, auto-scaling is triggered based on a target maximum concurrency of 100. We'll lower that target to make triggering a scaling decision easier. Remove the
minScaleannotation and add the annotation
autoscaling.knative.dev/target: "1"and re-apply the
- We'll use hey to drive some load. Run
hey -z 10s -c 100 http://helloworld-go.default.knative.currie.cloud && kubectl get pods. Although the default averaging window is 60 seconds, when the concurrency breaches double the target then the auto-scaler enters panic mode and starts scaling up the number of instances so you should see additional pods.
Manual blue-green deployment
kubectl get revisionand note the name of the revision for the latest generation.
v3. Add a
releasewhich lists the latest revision noted in the previous step.
curl helloworld-go.default.knative.currie.cloudshould still return
v2: Hello World!.
kubectl get revisionand note the name of the revision for the third generation.
- Add the new revision into
service.yamlunder the existing one. Then add a
rolloutPercent: 0as a sibling of the
revisionselement. Apply the updated YAML. 1.
curl helloworld-go.default.knative.currie.cloudis still returning
v2: Hello World!.
- Although no default traffic is being routed to the new service revision, it is now tagged
candidateand is available via
- Increase the rollout percentage to
curl helloworld-go.default.knative.currie.cloudrepeatedly and note that the workload is now balanced across the two revisions.
- Remove the
rolloutPercentand the old revision and re-apply.
curl helloworld-go.default.knative.currie.cloudrepeatedly and you should now only see the latest version.
kubectl delete -f service.yaml
- Take a look at service-with-build.yaml. It adds a
buildconfiguration that points to the GitHub repo containing this application. It also specifies a service account configured with Docker Hub credentials and a Kaniko build template.
- Retrieve the build template with
kubectl get buildtemplate kaniko -o yaml. Note how it takes the image name as a parameter. This template only contains a single step which specifies the kaniko
executorimage that will build an image and push it to a registry.
- Apply the service configuration with
kubectl apply -f service-with-build.yaml.
- Watch the pods with
kubectl get pods -w.
- Note that the build pod contains three init containers. Two are always injected: one to set up credentials (e.g. mounting in the Docker and/or Git credentials) and the second to check out the source from Git. These are followed by a container for each step in the build. They are run as init containers so that execute sequentially.
- Once the build has complete, the service will be deployed.
- Create eventing source with
kubectl apply -f gcp-pubsub-source.yaml.
- Create the trigger to subscribe with
kubectl apply -f trigger.yaml.
- Publish a message
gcloud pubsub topics publish devoxx --message "Devoxx"
- Look at the logs for the application and note that it has been driven by the message.
- Look at helloworld.go again to see how it handles the event.
kubectl delete -f service-with-build.yaml
kubectl delete -f trigger.yaml
kubectl delete -f gcp-pubsub-source.yaml