Series of reusable Cartographer Supply Chains and templates for driving workloads from source code to running Knative service in a cluster.
- Cartographer's ClusterSupplyChain and associated resources (templates)
The following configuration values can be set to customize the installation.
-
registry.server
(default: none, required): hostname of the registry server where app images are pushed to -
registry.repository
(default: none required): where the app images are stored in the image registry -
service_account
(default:default
): name of the serviceaccount to use by default in any children resources -
cluster_builder
(default:default
): name of the kpack clusterbuilder to use by default in any kpack image objects -
git_implementation
(default:go-git
): git implementation to use in flux gitrepository objects
The Cartographer supply chains provided in this package require all resources of which objects they create to be previously installed in the cluster, those being:
-
cartographer, for choreographing kubernetes resources according to the definition of the supply chains
-
kapp-controller, for providing both the packaging primitives for installing this package as well as the
App
CRD used by the supply chain to deploy the applications built according to the supply chains -
cartographer-conventions, for applying conventions to the podtemplatespec embeded in the final configuration generated for the application
-
kpack, for building container images out of source code
-
source-controller, for keeping track of changes to a git repository and making source code available internally in the cluster
-
knative serving, for running the application
With the dependencies met, proceed with the installation of this package:
-
Create a file named
ootb-supply-chains.yaml
that specifies the corresponding values to the properties you want to change. For example:cluster_builder: default service_account: default registry: server: REGISTRY-SERVER repository: REGISTRY-REPOSITORY
-
Having the configuration ready, install the package by running:
tanzu package install ootb-supply-chains \ --package-name ootb-supply-chains.community.tanzu.vmware.com \ --version ${OOTB_SUPPLY_CHAINS_PACKAGE_VERSION} \ --values-file ootb-supply-chains.yaml
Example output:
\ Installing package 'ootb-supply-chains.community.tanzu.vmware.com' | Getting package metadata for 'ootb-supply-chains.community.tanzu.vmware.com' | Creating service account 'ootb-supply-chains-default-sa' | Creating cluster admin role 'ootb-supply-chains-default-cluster-role' | Creating cluster role binding 'ootb-supply-chains-default-cluster-rolebinding' | Creating secret 'ootb-supply-chains-default-values' | Creating package resource - Waiting for 'PackageInstall' reconciliation for 'ootb-supply-chains' / 'PackageInstall' resource install status: Reconciling Added installed package 'ootb-supply-chains' in namespace 'default'
This Cartographer Supply Chain ties together a series of Kubernetes resources which drive a developer-provided Workload from source code to a running Knative Service in the Kubernetes cluster, updating it whenever changes occur to either source code or base image used for building the application.
flowchart RL
Kpack -- commit --> GitRepository
PodIntent -- container image --> Kpack
App -- podtemplatespec --> PodIntent
subgraph source-provider
GitRepository
end
subgraph image-builder
Kpack
end
subgraph conventions-applier
PodIntent
end
subgraph deployer
App
end
To make use of it, we must first have in the same namespace as where the Workload is submitted to a couple of objects that the resources managed by the supplychain need so they can properly do their work:
-
container image registry secret for providing credentials to the kpack Image objects created so the container images created can be pushed to the desired registry
-
serviceaccount for providing means of representing inside Kubernete's role-based access control system the permissions that the Cartographer controller can make use of in favor of the Workload
-
rolebinding for binding roles to the serviceaccount that represents the workload.
Using the Tanzu CLI, Create a secret with push credentials for the container
image registry configured in installation of this package (i.e., for the server
and repository described in registry.server
and registry.repository
of
ootb-supply-chain-values.yaml
):
tanzu secret registry add registry-credentials \
--server REGISTRY-SERVER \
--username REGISTRY-USERNAME \
--password REGISTRY-PASSWORD \
--namespace YOUR-NAMESPACE
Where:
-
REGISTRY-SERVER
is the URL of the registry.-
For Dockerhub, this must be
https://index.docker.io/v1/
. Specifically, it must have the leadinghttps://
, thev1
path, and the trailing/
. -
For GCR, this is
gcr.io
. The username can be_json_key
and the password can be the JSON credentials you get from the GCP UI (underIAM -> Service Accounts
create an account or edit an existing one and create a key with type JSON)
-
note: alternatively, you can create the secret using kubectl
:
kubectl create secret docker-registry registry-credentials \
--docker-server=REGISTRY-SERVER \
--docker-username=REGISTRY-USERNAME \
--docker-password=REGISTRY-PASSWORD
Create a ServiceAccount to be used by Cartographer to manage the supply chain resources as well as pass it down to them (the resources) so they are able to gather necessary data and/or credentials to deal with the Kubernetes API.
Here we also need to associate the previously created Secret
(registry-credentials
) to it so that anyone referencing such ServiceAccount
also gather the credentials to pull/push images to/from the container image
registry where the application should reside.
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
secrets:
- name: registry-credentials
imagePullSecrets:
- name: registry-credentials
Bind to the ServiceAccount the role that would then permit the controllers involved to act upon the objects managed by the supplychain
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ootb-supply-chain-source-to-url-workload
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ootb-supply-chain-source-to-url-workload
subjects:
- kind: ServiceAccount
name: default
With the namespace where the Workload will be submitted ready having all the three objects mentioned above (image secret, serviceaccount, and rolebinding), we can proceed with the creation of the Workload.
tanzu apps workload create hello-world \
--git-branch main \
--git-repo https://github.com/sample-accelerators/tanzu-java-web-app
--label app.kubernetes.io/part-of=tanzu-java-web-app \
--type web
Create workload:
1 + |---
2 + |apiVersion: carto.run/v1alpha1
3 + |kind: Workload
4 + |metadata:
5 + | labels:
6 + | apps.tanzu.vmware.com/workload-type: web
7 + | app.kubernetes.io/part-of: hello-world
8 + | name: hello-world
9 + | namespace: default
10 + |spec:
11 + | source:
12 + | git:
13 + | ref:
14 + | branch: main
15 + | url: https://github.com/sample-accelerators/tanzu-java-web-app
With the Workload submitted, you can follow the live logs using the tanzu
cli:
tanzu apps workload tail hello-world --since 10m
Eventually, the resources described by the supply chain will be created, all of
them being children objects of the Workload carrying the
app.kubernetes.io/part-of
label.
NAMESPACE NAME
default Workload/hello-world
default ├─GitRepository/hello-world
default ├─Image/hello-world
default │ ├─Build/hello-world-build-1
default │ ├─PersistentVolumeClaim/hello-world-cache
default │ └─SourceResolver/hello-world-source
default ├─PodIntent/hello-world
default └─App/hello-world
Because we installed the package with its default service account name to
default
and in the sections above both attached the secret and bound the
ClusterRole to the default
serviceaccount, we don't need to tweak any extra
fields in the spec.
For reference, below you'll find the full definition of a Workload for this supply chain:
apiVersion: carto.run/v1alpha1
kind: Workload
metadata:
name: hello-world
labels:
# the name of the higher-level applicaton that the objects involved
# in the supply chain should be part of (this label gets pushed down
# to them, including the final knative-service).
#
app.kubernetes.io/part-of: hello-world
# type of this workload. this is required in order to match this workload
# against the supplychain bundled in this package.
#
apps.tanzu.vmware.com/workload-type: web
spec:
# name of the serviceaccount to grant to Cartographer the necessary
# privileges for creating/watching/etc the resources defined by the
# supply chain.
#
serviceAccountName: default
params:
# name of the serviceaccount to pass down to the objects that need one
# (e.g, kpack and kapp-ctrl/App).
#
- name: service_account
value: default
# details about where source code can be found in order to keep track of
# changes to it so the resources managed by the supply chain can create new
# builds and deployments whenever new revisions are found.
#
source:
git:
url: https://github.com/kontinue/hello-world
ref: {branch: main}
In the workload.spec.params
field we can specify a couple parameters to
override the default behavior of certains components:
-
service_account
(string): overrides the default name of the serviceaccount (set inootb-supply-chain-values.yaml
) to pass on to the children objects. -
cluster_builder
(string): overrides the default name of the clusterbuilder (set inootb-supply-chain-values.yaml
) to be used by thekpack/Image
created by the supply chain. -
git_implementation
(string): overrides the default git implementation (set inootb-supply-chain-values.yaml
) to use for the GitRepository. Valid options: libgit2, go-git. -
git_secret
(string): name of a git secret in the same namespace as the Workload where the GitRepository object can find the credentials for pulling the git repository contents.
Copyright 2022 VMware Inc. All rights reserved