3 min read | by Jordi Prats
Shipwright is a framework that allow us to build container images and push them to remote registries from within a Kubernetes clusters. It supports popular tools such as Kaniko, Cloud Native Buildpacks and Buildah
To install shipwright we will need to install tekton, shipwright itself and predefined build strategies that they provide. We can do it using the following commands:
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.34.1/release.yaml
kubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.9.0/release.yaml
kubectl apply -f https://github.com/shipwright-io/build/releases/download/v0.9.0/sample-strategies.yaml
If we need to work with private repositories we will need to create some Kubernetes Secrets containing the key to use to be able to fetch the repository we want to build. To import ~/.ssh/id_rsa into a Kubernetes ssh-auth secret named githubssh we can use the following command:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: githubssh
type: kubernetes.io/ssh-auth
data:
ssh-privatekey: $(base64 -w0 ~/.ssh/id_rsa)
EOF
Again, to be able to push the container image, we are, most likely, going to have to authenticate against it. In case we want to push it to docker Hub we can use the following command (just needing to set docker-username, docker-username and docker-email to the appropriate values)
kubectl create secret docker-registry hubdocker \
--docker-server=https://index.docker.io/v1/ \
--docker-username=demouser \
--docker-username=passw0rd \
--docker-email=demouser@pet2cattle.com
We can, of course, use other solutions like KES to dynamically fetch secrets from an external source.
To start defining the build process we'll have to create the Build object defining the template:
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: build
spec:
source:
url: https://github.com/jordiprats/flask-pet2cattle
credentials:
name: githubssh
strategy:
name: kaniko
kind: ClusterBuildStrategy
output:
image: docker.io/jordiprats/shipwright-test:latest
credentials:
name: hubdocker
Using the Build as a template, we can now create a BuildRun that will create a Pod to actually build the container and upload it to the registry:
Using this object we can override the image name that it's going to use using spec.output.name:
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
name: buildrun
spec:
buildRef:
name: build
output:
image: {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}
As soon as we apply these objects on the cluster, it will start the build process: Building the container image and then uploading it to the registry using the image name defined on the BuildRun object:
$ kubectl get build
NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME
build True Succeeded ClusterBuildStrategy kaniko 8m10s
$ kubectl get buildrun
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
buildrun True Succeeded 8m16s 7m39s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
buildrun-rj2wv-pod-q4np5 0/2 Completed 0 8m26s
Posted on 30/05/2022