Creating a ClusterStack based on Red Hat UBI Image in Tanzu Build Service (TBS)

I have written few blogs about basics of TBS, it’s installation and also creating a container image from source code. Feel free to take a look on those.

In this post, I would like to help you with the step by step instructions on creating a ClusterStack based on RHEL UBI image. VMware brought in this feature in TBS v1.3. By default, TBS comes with few ClusterStacks based on Ubuntu bionic image, however in many cases, clients may like to use their own hardened image instead of TBS provided.

Once the ClusterStack is created, you can create ClusterBuilder or Builder for building container image and I will not cover it here. Something for the next post 🙂

So, Lets get started:


ClusterStack is a collection of build and run images.

  1. The build image of a stack provides the base image from which the build environment is constructed. The build environment is the containerized environment in which the lifecycle (and thereby buildpacks) are executed.
  2. The run image of a stack provides the base image from which application images are built.

Buildpacks are created based on ClusterStack by installing additional packages based on the required buldpack e.g. buildpack for Java, Python etc.

When you build the container image from source code, we refer ClusterBuilder or Builder and it’s based on ClusterStack.


Here are the list of pre-requirements before you start creating the ClusterStack.

  • Kubernetes Cluster is up and running, in this example, TKG 1.4 is being used
  • TBS v1.3 is installed on a Kubernetes Cluster and working
  • UBI image is available on the container registry
  • Login credentials for the container registry with the image push permission
  • Kubernetes secret for the container registry is created

Creating a ClusterStack

In order to create a ClusterStack, we will be creating a CRD called CustomStack provided by TBS. Below is the reference yaml file for creating a CustomStack.

kind: CustomStack
  name: ubi8-stack
        image: dineshtripathi30/ubi8@sha256:8ee9d7bbcfc19d383f9044316a5c5fbcbe2df6be3c97f6c7a5422527b29bdede
        image: dineshtripathi30/ubi8@sha256:8ee9d7bbcfc19d383f9044316a5c5fbcbe2df6be3c97f6c7a5422527b29bdede
    stack: # Optional
      name: ubi8stack
      kind: ClusterStack
  serviceAccountName: default
  user: # Optional
    userID: 1000
    groupID: 1000

Here are the key points to know about file:

  • source: The location of base images used for building the stack. See more info in Source Configuration.
  • destination: The location to publish built images and optional ClusterStack. See more info in Destination Configuration.
  • service-account-name: Name of service account with secret containing credentials to push to registry.
  • user: User and group ID of the CNB user
    • Not required if the user is already present in metadata.
    • If the user and/or group ID do not exist on the image, they will be created.

– Now, lets create the CustomStack resource.

k apply -f cust.yaml -n spring created

– Monitor the status of pod created, it will move to Completed status in few mins.

k get po -n spring
NAME                                  READY   STATUS       RESTARTS   AGE
stack-pod-ubi8-stack-1                0/2     Completed    0          70m

– See the CustomStack status

k get customstack -n spring
NAME           AGE
ubi8-stack     94m

– Now, let see the created ClusterStack, noticed the bold one

k get clusterstack
NAME                         READY
base                         True
default                      True
full                         True
stack-sample-cluster-stack   True
tiny                         True
ubi8stack                    True

– Describe the ClusterStack and see the build and run images

kp clusterstack status ubi8stack
Status:         Ready
Id:             io.buildpacks.rhel.8.5
Run Image:
Build Image:

– ClusterStack is now ready to use. You can use ClusterBuilder or Builder to use this ClusterStack and create the image.

– Verify the image on the container registry, in my case it’s dockerhub.


I noticed few limitations when creating CustomStack with UBI images:

  • You can not add packages in ClusterStack, In case you are trying to add the packages, you may see the below error while creating the ClusterStack.
    • Error Message: failed to mutate image: failed to add packages: adding packages is not yet supported on Nonbionic
  • Currently, only the Java Tanzu Buildpacks support CustomStacks that use UBI images
  • You can only use image digest in CustomStack configuration file under source image

Reference Doc

You can refer TBS official documentation to know more about creating CustomStack.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s