Build a container image inside a K8s cluster and push it to IBM Cloud Container Registry
Tags: ibm, cloud, istio, kubernetes
Published: 2019-03-15 05:36:26

---
title: Build a container image inside a K8s cluster and push it to IBM Cloud Container Registry
published: true
tags: ibm,cloud,istio,kubernetes
canonical_url: https://medium.com/vmacwrites/build-a-container-image-inside-a-k8s-cluster-and-push-it-to-ibm-cloud-container-registry-abac9b1e5246
---

### Build a container image inside a Kubernetes cluster and push it to IBM Cloud Container Registry

Learn how to build a source into a container image from a Dockerfile inside a Kubernetes cluster and push the image to IBM Cloud Container Registry; all of this using Google’s [Kaniko](https://github.com/GoogleContainerTools/kaniko) tool.

### So, What is Kaniko?

> Kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster.

![](https://cdn-images-1.medium.com/max/1024/1*VKL-Byx-GSAOl82ytNe8RQ.png)<figcaption>Kaniko logo</figcaption>

> If you don’t have a Kubernetes cluster with Knative and Istio installed, it’s recommended to follow the instructions mentioned in my previous post that also introduces you to the components of Knative —[ Install Knative with Istio and deploy an app on IBM Cloud](https://medium.com/@VidyasagarMSC/install-knative-with-istio-on-iks-cluster-and-deploy-an-app-on-ibm-cloud-7b7d368b9833)

This tutorial uses the [Build](https://github.com/knative/docs/blob/master/build/README.md) and [Serving](https://github.com/knative/docs/blob/master/serving/README.md) components of Knative to orchestrate an end-to-end deployment.

A Knative [build](https://github.com/knative/docs/tree/master/build) extends [Kubernetes](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and utilizes existing Kubernetes primitives to provide you with the ability to run on-cluster container builds from source. For example, you can write a build that uses Kubernetes-native resources to obtain your source code from a repository, build it into container a image, and then run that image.

Knative Serving builds on Kubernetes and Istio to support deploying and serving of serverless applications and functions. Serving is easy to get started with and scales to support advanced scenarios.

### What is a Build Template?

A BuildTemplateis one of the key features of Knative build used to defined reusable templates and encapsulates a shareable build process with some limited parameterization capabilities. A set of curated and supported build templates is available in the [build-templates](https://github.com/knative/build-templates) repo. We will be using the **Kaniko BuildTemplate** in the tutorial

> Kaniko doesn’t depend on a Docker daemon and executes each command within a Dockerfile completely in userspace. This enables building container images in environments that can’t easily or securely run a Docker daemon, such as a standard Kubernetes cluster.

Let’s start by creating a Kaniko BuildTemplate and saving this as kaniko.yaml

{% gist https://gist.github.com/VidyasagarMSC/0c4933afbb04b6213111dcd0dcfa2b4e %}

#### Parameters

- IMAGE: The Docker image name to apply to the newly built image.(_required_) Replace <region>and <namespace> with appropriate values. **Remember these values as you have to replace these values in the**  **YAMLscripts below.**
- DOCKERFILE: The path to the Dockerfile to execute (_default:_ ./Dockerfile)

> **_Note:_** _To check your region, run_ _ibmcloud cr regionand to setup a new namespace, refer_ [_this link_](https://console.bluemix.net/docs/services/Registry/index.html#registry_namespace_add)

If you are looking for a sample with Dockerfile, try [https://github.com/VidyasagarMSC/knative-deploy](https://github.com/VidyasagarMSC/knative-deploy)

Kaniko builds an image and pushes it to the destination defined as a parameter. In order to properly authenticate to the remote container registry (IBM Cloud Container Registry), the build needs to have the proper credentials. This is achieved using a build ServiceAccount.

Before this, let’s define a Secret containing the username and password that the build should use to authenticate(basic) to IBM Cloud Container Registry:

{% gist https://gist.github.com/VidyasagarMSC/6e065f765f561f7dd77942b403f0f7fb %}

For <password>, run the below command

```
$ ibmcloud cr token-add --description “This is a token” --non-expiring --readwrite

**_Returns:_** 
Token identifier 58669dd6–3ddd-5c78–99f9-ad0a5aabd9ad 
Token <token_value>
```

Use the returned token_value as your password and save the file as secret.yaml . For more details related to token, refer [this link](https://console.bluemix.net/docs/services/Registry/registry_tokens.html#registry_tokens)

Now you can create aserviceaccount.yaml file with the ServiceAccount using the secret as shown below

{% gist https://gist.github.com/VidyasagarMSC/824d247ddc4e7e380f42cb44ee4e5b8d %}

Let’s use ServiceAccount in our Build and save the file asbuild.yaml

{% gist https://gist.github.com/VidyasagarMSC/8b7ff4b3fa360c700aab25edc8a0b30a %}

Execute the build

```
$ kubectl apply --filename kaniko.yaml
$ kubectl apply --filename secret.yaml
$ kubectl apply --filename serviceaccount.yaml
$ kubectl apply --filename build.yaml
```

The build should have been kicked off. Let’s take a look.

Runningkubectl get pods , you should see a pod named kaniko-build with a postfix(say XXXXX).

![](https://cdn-images-1.medium.com/max/1024/1*bPl6PUNMUPBV9uS5Qtv5Hg.png)

For logs, run this command

```
$ kubectl logs kaniko-build-XXXXX -c build-step-build-and-push
```

![](https://cdn-images-1.medium.com/max/1024/1*cg_fo41pgNhIuNvbFVMylQ.png)

If everything runs as expected, you should see the image in the list when you run the below command

```
$ ibmcloud cr images
```

Hurray!! you have just created a container image without a Docker Daemon. Let’s deploy and serve the app so that we can access it from anywhere. For this, lets create a service.yaml file:

{% gist https://gist.github.com/VidyasagarMSC/92de03c7be5204e9df62452fc13d8c99 %}

Execute the service

```
$ kubectl apply --filename service.yaml
```

To find the IP address for your service, use kubectl get svc knative-ingressgateway -n istio-system to get the ingress IP for your cluster. If your cluster is new, it may take sometime for the service to get assigned an external IP address.

```
$ export IP_ADDRESS=$(kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.status.loadBalancer.ingress[0].ip}')
```

To find the URL for your service, use kubectl get services.serving.knative.dev knative-node-app --output jsonpath='{.status.domain}'

```
$ export HOST_URL=$(kubectl get services.serving.knative.dev knative-node-kaniko --output jsonpath='{.status.domain}')
```

Now you can make a request to your app to see the result.

```
$ curl -H "Host: ${HOST_URL}" http://${IP_ADDRESS}

**Response:** Kaniko Node App running on IBM Cloud
```

![](https://cdn-images-1.medium.com/max/1024/1*QTEHgz3oAv9F0uupRRBD4g.png)

> For a sample with all these YAML templates and scripts, refer [https://github.com/VidyasagarMSC/knative-deploy/tree/master/kaniko](https://github.com/VidyasagarMSC/knative-deploy/tree/master/kaniko)

### Clean up

Run the below command to remove the sample app from your cluster

```
$ kubectl delete --filename service.yaml
```

To delete other secret,ServiceAccount and Build

```
$ kubectl delete --filename build.yaml
$ kubectl delete --filename serviceaccount.yaml
$ kubectl delete --filename secret.yaml
$ kubectl delete --filename kaniko.yaml
```

To delete the cluster (removes everything), enter the following command:

```
$ ibmcloud cs cluster-rm $CLUSTER_NAME
```

* * *