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