The previous tutorial taught you how to setup Knative Build on a Kubernetes cluster. You ran a simple Build that prints "Hello, World!".
Let's try a more concrete build: building a Docker image.
- This new tutorial, will show you how to build a Docker image described by a Dockerfile.
- You'll setup credentials to push that image to a registry.
- It'll show you how to extract common build configuration into a Build Template.
Time to complete:
Are you ready? Then click the Continue
button to get started...
We are going to build a very simple website with nginx. The sources are on GitHub. A Dockerfile describes the image to be built.
Open the file editor. Here's the Kubernetes yaml manifest to express such a build:
apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
name: docker-build
spec:
serviceAccountName: knative-build
source:
git:
url: https://github.com/dgageot/hello.git
revision: master
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.1.0
args:
- --dockerfile=/workspace/Dockerfile
- --destination=gcr.io/[PROJECT-NAME]/hello-nginx
A few things look different than the simpler "Hello, World!" build, right?
Click the Continue
button to understand those differences...
This time, the build will need sources to build an artifact. So we define a source where to get those sources from:
source:
git:
url: https://github.com/dgageot/hello.git
revision: master
Kaniko
Kaniko will be used
to build a Docker image. Just running docker build
would be unsafe on a
shared cluster.
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.1.0
Service Account
Once the image is built, it'll be pushed to Google Container Registry. Or any registry in fact, but we'll demonstrate with GCR. The build requires a service account to be granted the right to push.
serviceAccountName: knative-build
This will be done by creating a Kubernetes Service Account that has access to a Google Cloud Service Account.
That's a lot of Service Accounts! Click the Continue
button to do this step by step...
Giving a Build the permisison to push to Google Container Registry requires 4 steps:
- Create a Service Account in your Google Cloud project. It needs to be be granted push access to GCR.
- Create a JSON key for that Service Account.
- Store this key in a Kubernetes Secret.
- Create a Kubernetes Service Account that has access to this secret.
Once those steps are done, we can create as many builds as we want that share those permissions.
Click the Continue
button to follow those steps...
The first part of the configuration is on the Google Cloud side.
gcloud config set project [YOUR_PROJECTID]
PROJECTID=$(gcloud config get-value project)
gcloud iam service-accounts create knative-build --display-name "Knative Build"
gcloud projects add-iam-policy-binding $PROJECTID --member serviceAccount:knative-build@$PROJECTID.iam.gserviceaccount.com --role roles/storage.admin
gcloud iam service-accounts keys create knative-key.json --iam-account knative-build@$PROJECTID.iam.gserviceaccount.com
This creates a knative-key.json file on your drive.
You are almost there! You completed the Google Cloud part.
Click the Continue
button to complete the Kubernetes part...
First, create a Kubernetes secret from the JSON key:
kubectl create secret generic knative-build-auth --type="kubernetes.io/basic-auth" --from-literal=username="_json_key" --from-file=password=knative-key.json
To tell the Build to use those parameters when pushing to gcr.io
, we
need to add an annotation to the secret. That's called Guided credential selection.
kubectl annotate secret knative-build-auth build.knative.dev/docker-0=https://gcr.io
We can eventually create a Service Account in Kubernetes:
kubectl apply -f docker-build/service-account.yaml
You are done! Continue to next step to run the build...
OK, we've got everything configured to let the Build push images to a registry.
One last step is to edit docker-build/build.yaml
and replace [PROJECT-NAME]
with your project id.
This way, the build will push the image to the Google Container Registry linked to your project.
Run the build:
kubectl apply -f docker-build/build.yaml
The build is running:
kubectl get builds
Tail the logs with:
logs docker-build
Congratulations! You have built and pushed a Docker image with Knative Build.
Continue to next step, to improve the build file...
Now that you became familiar with expressing Docker builds, you will want to avoid copy/pasting the same boilerplate yaml each time a new image needs to be built.
Build Templates solve that problem by extracting the common yaml to a shared parameterized template.
A Build Template for a Docker build looks like that:
apiVersion: build.knative.dev/v1alpha1
kind: BuildTemplate
metadata:
name: docker-build
spec:
parameters:
- name: IMAGE
description: Where to publish the resulting image.
- name: DIRECTORY
description: The directory containing the build context.
default: "/workspace"
- name: DOCKERFILE_NAME
description: The name of the Dockerfile
default: Dockerfile
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.1.0
args:
- --dockerfile=/${DIRECTORY}/{DOCKERFILE_NAME}
- --destination=${IMAGE}
It's a list of steps and a list of parameters, some of which have default values that can be overriden by a build.
Let's register this template into Kubernetes.
kubectl apply -f docker-build/template.yaml
Now, the Build can be simplified by referencing the template and by providing the right values for each parameter.
apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
name: docker-build-hello
spec:
serviceAccountName: knative-build
source:
git:
url: https://github.com/dgageot/hello.git
revision: master
template:
name: docker-build
arguments:
- name: IMAGE
value: gcr.io/[PROJECT-NAME]/hello-nginx
Click the Continue
button to run the templated build...
Warning: don't forget to replace [PROJECT-NAME]
with you actual
project name in
docker-build/build-hello.yaml
Run the build:
kubectl apply -f docker-build/build-hello.yaml
The build is running:
kubectl get builds
Tail the logs with:
logs docker-build-hello
Woot! You've used a Build Template for the first time. You are an advanced user now!
Why not build a more complicated Java application?
Copyright 2018 Google LLC All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.