Getting Started with kpack to Automate Builds using Cloud Native Buildpacks
Tyler Britten & Ivan Tarin
kpack
is a Kubernetes-native build service that builds container images on Kubernetes using Cloud Native Buildpacks. It takes source code repositories (like GitHub), builds the code into a container image, and uploads it to the container registry of your choice.
Before You Begin
There are a few things you need to do before getting started with kpack
:
-
Have access to a Kubernetes cluster. If you don’t, you can use local options like Docker Desktop or Minikube.
-
Check out Getting Started with Kubernetes on KubeAcademy, particularly if you’ve never worked with Kubernetes before.
-
Optionally install
stern
, a tool that makes it easy to tail the logs during builds.- Command to install with Homebrew on Mac OS
brew install stern
- Command to install with Homebrew on Mac OS
-
Have the kubectl CLI to interact with your cluster.
- Command to install with Homebrew on Mac OS
brew install kubectl
- Command to install with Homebrew on Mac OS
-
Accessible Docker V2 Registry, DockerHub will suffice it is free and creating an account is easy.
-
Follow the documentation for installing
kpack
in your Kubernetes cluster.
Initial kpack
Configuration
Among the things you will need before you get started are a code repository with compatible code (I’m using Spring Java in this case) and a container registry (I’m using Google GCR).
To make sure your kpack
environment is ready after following the install instructions above, run.
kubectl get pods --namespace kpack --watch
Using kpack
Set Up Container Registry Secret
The first thing you need to do is tell kpack
how to access the container registry to upload the completed images when they’re done.
You’ll need a secret with credentials to access GCR, so you’ll create a manifest like this and apply it with kubectl apply -f
.
For more details see the kpack
secrets documentation.
Also note the annotation of kpack.io/docker
; it tells kpack
which registries to use these credentials for. In the case of gcr-registry-credentials.yaml
, any image tagged for us.gcr.io.
Set Up Container Registry Service Account
Now you need a service account referencing those credentials in your secret. The manifest is pretty simple:
Create your Store
A store is a repository of buildpacks packaged into buildpackages that kpack uses to build images. You can add more languages by including more buildpacks you create or from Paketo Buildpacks we have only included a few bellow.
The store will be referenced by a builder resource.
kubectl apply -f store.yaml
Apply a Cluster Stack
A stack provides the buildpack lifecycle with build-time and run-time environments in the form of images.
The pack CLI command: pack suggest-stacks
will display a list of recommended stacks that can be used. We recommend starting with the io.buildpacks.stacks.bionic
base stack.
kubectl apply -f stack.yaml
Apply a Builder
A builder is an image that bundles all the bits and information on how to build your apps, like
- A buildpack
- An implementation of the lifecycle
- A build-time environment that platforms may use to execute the lifecycle
kpack will push the builder image to your registry.
kubectl apply -f builder.yaml
Create an Image Configuration
Now you’re all ready to start building images and pushing them to your registry. To create a manifest that builds containers off the application code on GitHub:
You can see the GitHub URL, and that you’re building off master. Also, you configured the desired image tag (including the registry) and included the service account and builders you created. Once you apply this manifest, it will begin building.
By running kubectl get images
you should see the image created but not complete:
NAME LATESTIMAGE READY
petclinic-image Unknown
Watching the Build
If you run a kubectl get pods
, you’ll see a pod created (with a series of init containers) to build the image.
Since it includes six different containers, it’s hard to use kubectl logs
because you have to know which container to specify at which stage. It’s much easier to use the stern
tool mentioned at the beginning.
The pod that is created has a name that starts with image-name-build
; so in this case, petclinic-image-build.
The command to run to see the logs is stern petclinic-image-build,
and you’ll see all the logs pass by during the build and upload.
Once it’s complete you can recheck the image with kubectl get images
:
NAME LATESTIMAGE READY
petclinic-image us.gcr.io/pgtm-tbritten/spring-petclinic@sha256:<sha hash> True
You can now run docker pull us.gcr.io/<project>/<spring-petclinic>
to download the completed image. Or you can create a Kubernetes manifest to run the image.
As mentioned in the previous section on image configuration, the spec.source.git.revision
is the commit used to build, try changing it to trigger a new build!
Bonus - Deploy your app to Kubernetes
kpack is best used in conjunction with a CI/CD tool, but if you want to deploy your app to Kubernetes now you can very easily.
You will reuse your secret with your registry and pull from the repository that holds the container image. You created this repo in the Create an Image Configuration section and can be found at spec.tag
place it after --image=$DH_USERNAME/app
.
Create a deployment with the image kpack made with your source code
kubectl create deployment kpack-demo --image=<registry-name>/<app-repo>
To verify deployment
kubectl get deployments
Expose the Pod to the public internet using the kubectl expose command:
kubectl expose deployment kpack-demo --type=LoadBalancer --port=8080
The --type=LoadBalancer
flag exposes your Service outside of the cluster.
The application code inside the image k8s.gcr.io/echoserver
only listens on TCP port 8080.
To verify your service
kubectl get services
On cloud providers that support load balancers, an external IP address would be provisioned to access the Service.
On minikube, the LoadBalancer type makes the Service accessible using:
minikube service kpack-demo