This post is part one of a three-part series discussing how to integrate Jenkins, Tanzu Build Service, and ArgoCD.
- Part 1: Iterative Development
- Part 2: Intake of Buildpack updates
- Part 3: Promoting code to production
Why Tanzu Build Service.
One of the most significant issues with adopting Kubernetes is developing a workflow that allows for building production-ready container images. Images need to be built and frequently in a repeatable manner.
Tanzu Build Services (TBS) leverages something called a Buildpack to build containers. A Buildpack is a standard approach to ingesting application source code and converting it into a runnable container. Since Buildpacks are based on a standard implementation, multiple vendors can provide Buildpacks. VMware bundles an extended set of Buildpacks based on the Packeto open-source project.
Normally containers based on BuildPacks are built using a CLI command called pack
. The pack
tool scans source code the determine what type of BuildPacks to use and applies its configuration to a base operating system image.
Tanzu Build Service extends the cli
by creating builds with a declarative manifest. Containers are rebased by TBS when newer BuildPacks are imported into the cluster.
Developer Perspective
As a software developer:
- I don’t want to understand how to build Docker containers.
- I don’t want to be responsible for maintaining and patching containers.
Given some source code, I just want to be able to run it on Kubernetes.
CTO Perspective
As a CTO
- I want to ensure my organization’s applications are always running the latest patches available.
- I want my developers only to run software from a trustworthy repository.
- I want my developers to spend more time developing new features and not patching operating systems.
Given a Kubernetes application, I want any easy way to update the container to fix the latest CVEs.
Development Iteration
The above diagram depicts the flow when a developer commits new code.
- Jenkins Fires a new Job when a check in to GIT on to the master branch. At this point, Jenkins can run unit tests, code coverage, and other static analysis tasks.
- After the compilation/test phase is complete, Jenkins submits the artifact to the Tanzu Build Service.
- After Tanzu Build Service completes the creation of the Image, Jenkins, updates the kustomization manifest automatically
- ArgoCD applies the latest configuration to the development cluster.
Argo Out of Sync
Any differences between the GIT Baseline and what is deployed by Argo are reconciled automatically. Logging in Argo will show when and why artifacts changed.
Argo visits service changed
Implementing This.
Although any continuous delivery tool could be used to implement this workflow, I chose Jenkins for its ubiquity. If you want to follow along and run my pipelines, you will want to make sure you have Jenkins configured to run builds inside Kubernetes containers.
Jenkins Prerequisites
The following plugins must be installed:
- kubernetes:1.29.2
- job-dsl:1.77
- envinject:2.4.0
- ssh-agent:1.22
- kubernetes-credentials-provider:0.18-1
I have included the versions of the plugins I am using. The Jenkins plugin ecosystem is very volatile, so version numbers may vary for you over time.
App Seed
In the Spirit of Configuration as Code, I have a groovy script that is used to seed jobs within Jenkins. Adding a new Job is as simple as adding a new entry to the script and committing the changes to GIT. In the code below, I have the name of the project and the name of the pipeline file that should be used to build the result. Since all my apps are Spring Boot, they all can use the same pipeline. A pipeline file is nothing more than a Groovy script that instructs Jenkins on executing a job.
|
|
The complete script is available here
The Pipeline
The pipeline implements several stages.
- Fetch from GitHub
- Create Image
- Update Deployment Manifest
All of these steps are performed in a clean docker container as defined in the pod template.
|
|
Since our pod needs access to a remote Kubernetes cluster, I have mounted a service account KUBECONFIG into the pod as a secret.
- Fetch from GitHub
|
|
- Create an Image with TBS. Use the
-w
flag to wait until the build is complete.
|
|
Images Monitored by TBS
- Update Deployment Manifest
Since we use Kustomize
to maintain our deployment versions. We update the kustomization.yaml
using kustomize
itself.
|
|
All of these steps run within the “k8s” container, which was pulled from Harbor.
harbor.ellin.net/library/docker-build
This image is based on the following Dockerfile.
|
|
It’s a standard docker image with some utilities that we commonly need to use.
- bash
- git
- openssh
- curl
- jq
- helm
- kubectl
- kustomize
The complete script is available here
All the source code for the pet-clinic
and its deployment are available on GitHub
In the following article, I will include an example of how to automate promoting artifacts to a stage/prod environment using GitOps.
Last modified on 2021-05-16