Knative — Extending Kubernetes to Build, Deploy & Manage Applications and Modern Serverless Workloads
Kubernetes indeed is the highly used container orchestration tool which simplified management of sophisticated microservice infrastructure. Kubernetes can undoubtedly handle container management operations without a glitch, but creating and managing containers merely solves the infrastructure facilitating part. The real use case is how developers can leverage Kubernetes for pushing application code or a function spec (serverless!!), wherein Kubernetes on its own isn’t enough to perform the operations stated above.
Application deployment on Kubernetes can be a daunting task for any developers not familiar with the ecosystem. The developer needs to understand how to create spec files in specific DSL, author CI/CD scripts, and instrument tracing and logging. “PaaS” came into the picture to mitigate some of the issues by providing an abstraction layer on K8s for developers to readily use Kubernetes environment for application development (for example: Openshift).
Knative atop of K8s and Istio provides a set of middleware components that are essential to build modern, source-centric, and container-based applications that can run on premises, in the cloud, or a third-party data center with advanced network routing. In simpler terms a PaaS like abstraction on top of Kubernetes that leverage Istio to provide a level of abstraction for specifying, running and modifying applications while using Custom Resource Definitions (CRD’s) to extend the Kubernetes functionality..
With recent addition of “FaaS” also termed as serverless or functions to world of distributed systems that allows developers to easily run and deploy snippets of code on cloud native infrastructure, there is a need for common tooling for building functions. Knative by Google, Red Hat, IBM, and SAP is a set of components that enables modern CI/CD workflows that are native to kubernetes.
Architecture and Components
Knative uses Kubernetes for container orchestration layer building functionality using K8s primitives (pods and deployments). Istio for ingress networking and enabling advanced networking specs (service mesh). Along with this Knative adds three more components to manage application deployment life cycle:
- Build: Build containers from source code in a pluggable fashion using multiple methods (Kaniko, Bazel, Buildpack etc.) allowing flexible and extensible source code to container automation.
- Serving: Request driven operations, deploying and scaling functions at ease facilitaing on-demand scaling and revision control.
- Eventing: Publish-Subscribe for applications and abstracts the details of PubSub away from the developer.
Knative defines principle objects required for workload development, deployment, and management by defining primitive objects using CRD’s which extend on Kubernetes object model.
- Knative-Configuration is the desired state for a service which constitutes both code and configuration.
- Route facilitates reachability to a revision or multiple revisions of a service
- Revision represents an immutable point-in-time snapshot of users code and configuration
- Service is a combined package of all the objects to enable a use case
As shown above Knative-Configuration creates a revision(application container) which is built on K8s using Kubernetes objects.
Knative provides networking to the deployed applications using Istio. A user can reach the applications deployed using Istio ingress-gateway created atop of a virtual service.
A typical deployment with multiple revisions as shown above have a gateway serving revisions wherein Knative-Serving controls the concurrency between the revisions and traffic shifting is done to seamlessly reach the newly evolved revisions.
Knative on Kubernetes
All (Build, Serving and Eventing) controllers are deployed as deployments on Kubernetes in separate namespaces. Knative depends on Istio and injection should be enabled on the namespaces as required.
All Istio components are deployed in istio-system namespace and are used by Knative to implement advanced networking for deployed functions/applications.
Overall the Knative ecosystem (with Istio, monitoring and logging) on Kubernetes constitute multiple deployments as shown below:
Knative uses Kubernetes CRD’s (Custom Resource Definitions) to enable users to consume the abstractions. With installation of above components users should be able to utilize all the functionalities provided by Knative Build, Serving and Events along with Istio for networking.
End-to-End (Source-to-URL) Deployment of an Application with Knative- Build and Serving
A sample Go based application deployed from source code in a git repository to a running Application on Kubernetes with a URL using Knative.
Knative-Build facilitates users to use multiple templating options such as Kaniko, Bazel, Jib, Buildpack etc. and the functionality is extended using a BuildTemplate spec.
For example, the above template is a Kaniko (kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster from Google) build template. The template above encapsulates a shareable build process with limited parameters. By applying this the CRD’s provided by Knative enables Kubernetes to identify the BuildTemplate object and the Knative’s build controller syncs the template as shown below.
Pushing to Docker Hub requires a Build object with a ServiceAccount which needs a Secret for authentication (docker hub credentials stored in base64 format).
Now, deploying the Service using Knative serving requires a manifest with git-source information, template to be used and container information.
Build component builds the application container using the Kaniko template and Dockerfile from the Git-source provided simultaneously pushing the created image to Dockerhub provided in the manifest and serving-activator component formulates the networking required to access the application deployed using Istio.
As seen blow the application container is provisioned on Kubernetes as a deployment seamlessly.
Serving configures the service routing and enables users to reach the application created.
Knative seamlessly performs multiple aspects that are required for end-to-end deployment and management of the application created:
- Fetch the revision specified from GitHub and build it into a container
- Push the container to Docker Hub
- Create a new immutable revision for this version of the app.
- Network programming to create a route, ingress, service, and load balance for your app.
- Automatically scale your pods up and down (including to zero active pods).
With all routing configured users can access the application using istio-ingress-gateway load balancer object created.
The concurrency between the revisions will be controlled by the serving component and with newer revisions the route component automatically configures required routing aspects for shifting the traffic to newer revisions.
The Knative Eventing component is designed to abstract the backend details of working with events away from the developer. Eventing facilitates a way to consume and produce events designed to address common requirements for cloud native development. Knative decouples event producers and consumers and implements CNCF CloudEvents to streamline event processing.
- Flows abstract the path of an event from a source takes to reach an event consumer
- Sources abstraction layer for provisioning data sources from outside Kubernetes and routing them to the cluster
- Feeds bridge the event source into the eventing framework
- Buses k8s-native abstraction over message buses like NATS or Kafka
- Channels define an abstraction between the eventing infrastructure and the consumption and production of the events
- Event Sources represents the producer of events (e.g. GitHub)
- Event Types describes the types of events supported by the different event sources (e.g. Webhook for the above mentioned GitHub source)
- Event Consumers represents the target of your action (i.e. any route defined by Knative)
- Event Feeds is the binding or configuration connecting the event types to actions
Knative currently supports multiple implementations of Buses(Stub, Kafka, GCP PubSub), Sources(K8s events, Github, GCP PubSub). An example of a typical feed would be GitHub will be a EventSource, a Pull Request notification would be the EventType and the Feed describes the org/repo, credentials, the specific EventType and the consumer of the Feed events.
Knative is evolving with many more components being added to enable different abstractions which will ease the application deployment. Kubernetes and now Knative will all have a significant role to play as more and more companies start adapting to cloud native architectures. Knative also can be a key component in a multi-cloud scenario addressing the concerns of distributed application architectures allowing the programming models to run on any operational model. Although Knative build does not provide a complete standalone CI/CD solution, it can be a building block to enable integration and utilization in larger systems.