Today Google announced knative a new Open Source project that defines a set of primitives to go from source to Kubernetes operation quickly.

knative is a Kubernetes extension or I should say extensions (plural), meaning that it uses Kubernetes Custom Resource Definitions to define a new set of APIs that make building, deploying, scaling and routing traffic to an app easier.

Definitely knative targets the serverless realm and you will read a lot about this in the coming days/months. One very interestingl knative feature is that it implements a scale down to 0 and a scale up from 0 of your replicas (currently via Istio) depending on how many requests are hitting your microservice.

I will write about knative in more details in the coming days, it is a complex system. But for now :) one very interesting API that knative brings to the mix is the Build API object. A build is necessary if you need to put compiled language functions in production, but a Build can also be used to define your CI pipeline.

I have had the chance to get a preview of it, so let me share the gist about the Build API. For folks who know Kubernetes, it is a CRD with its own controller, you get it in your cluster with:

knative Build is pretty much the open sourcing of Google Container Builder. It defines a set of steps that are implemented as init-containers in a Pod.

Steps

Here is a toy Build manifest that executes /bin/date .



apiVersion: build.knative.dev/v1alpha1

kind: Build

metadata:

name: test

spec:

steps:

— name: date

image: debian:stable-slim

args: [‘/bin/date’]



It has a single step based on the debian:stable-slim Docker image and it runs /bin/date .

In a Build every step share a /workspace directory and every step executes within a Docker container, under the hood as mentioned a step is a Kubernetes init-container. When you create this object, the knative build controller will create a Pod with the proper init-containers and volumes setup.

Source

But to build you need source code, so a Build object also defines a source . Typically you can clone a repository and then perform steps on it, like so:



apiVersion: build.knative.dev/v1alpha1

kind: Build

metadata:

name: test

spec:

source:

git:

url:

revision: master

steps:

— name: ls

image: busybox

args: [‘ls’]

apiVersion: build.knative.dev/v1alpha1kind: Buildmetadata:name: testspec:source:git:url: https://github.com/sebgoa/functions.git revision: mastersteps:— name: lsimage: busyboxargs: [‘ls’]

So far so good, A build is based on source code pulled down and a set of steps that most likely perform actions on that source.

Templates

To simplify build manifests you can define templates as yet another API object. I invite you to look at the templates repository as it is a good way to learn about the Build objet. For example to build a Docker image within Kubernetes and push the resulting image, you can use Kaniko. I showed you how to do it with a standard Kubernetes Job. The main benefit of it being that you can do a Docker build within an unprivileged container.

Here is a basic template to build and push a Docker image with Kaniko:



apiVersion: build.knative.dev/v1alpha1

kind: BuildTemplate

metadata:

name: kaniko

spec:

parameters:

— name: IMAGE

description: The name of the image to push

— name: DOCKERFILE

description: Path to the Dockerfile to build.

default: /workspace/Dockerfile

steps:

— name: build-and-push

image: gcr.io/kaniko-project/executor

args:

- --dockerfile=${DOCKERFILE}

— --destination=${IMAGE}

— name: fail

image: busybox

args: [‘foo’]



Note that I keep a fail step for debugging otherwise we do not see the logs of the build steps (fresh zero day software FWIW :) ).

With a Template defined, your Build becomes simpler:



apiVersion: build.knative.dev/v1alpha1

kind: Build

metadata:

name: kaniko-test

spec:

serviceAccountName: build

source:

git:

url:

revision: master

template:

name: kaniko

arguments:

— name: IMAGE

value: docker.io/runseb/bazbaz

apiVersion: build.knative.dev/v1alpha1kind: Buildmetadata:name: kaniko-testspec:serviceAccountName: buildsource:git:url: https://github.com/sebgoa/functions.git revision: mastertemplate:name: kanikoarguments:— name: IMAGEvalue: docker.io/runseb/bazbaz

The serviceAccountName is needed to be able to push properly to your Docker hub repo. See https://github.com/knative/build-templates/tree/master/kaniko for detail documentation.

Connection with Google Container Builder

The connection with GCB is quite clear if you have been using GCB. A great service actually. The schema of a Build object is basically your cloudbuild.yaml file.

For example to build a Go app you would have the following cloudbuild.yaml in the root of your source code:



steps:

- name: ‘gcr.io/cloud-builders/go’

args: [‘install’, ‘.’]

env: [‘PROJECT_ROOT=hello’]

- name: ‘gcr.io/cloud-builders/go’

args: [‘build’, ‘hello’]

env: [‘PROJECT_ROOT=hello’]



Something that you can now do within Kubernetes using Knative Builds. Yeah !!!!

Conclusions

Certainly GCB is more than just the new knative Build but the Open sourcing of knative brings us very close to it and gives us a tool to build CI pipelines and put our code in production faster.