Documentation for version v0.49.x is no longer actively maintained. The version you are currently viewing is a static snapshot. For up-to-date documentation, see the latest version.
Package Management with GitOps
As you begin working with the package management APIs for kapp-controller, you may be wondering how to use kapp-controller’s gitops features to manage kapp-controller packages. This section will cover an example gitops workflow using kapp-controller’s package management resources.
GitOps Scenario ¶
An example gitops scenario with kapp-controller could be that a user wants to install a subset of Packages from a PackageRepository. The user wants to define which PackageRepository and Packages to install by defining these resources in a git repository. With this approach, a user can manage resources in a declarative fashion and track the history of changes to a Kubernetes cluster.
After making changes to the main branch of the git repository, the user expects that kapp-controller will sync these resources to the Kubernetes cluster where kapp-controller is installed. The user also expects kapp-controller to sync these resources based on updates (e.g. PackageRepository or Package version upgrades) to the main branch of the git repository.
Package Management GitOps Example ¶
To start, a user should already have kapp-controller installed on a Kubernetes cluster and have a git repository available.
First, a user can start by defining an App custom resource like below. NOTE: A user will also need to create a serviceaccount with associated RBAC permissions for the App to use.
apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
name: pkg-gitops-example
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-rule.create-order: "upsert after upserting rbac"
kapp.k14s.io/change-rule.delete-order: "delete before deleting rbac"
spec:
serviceAccountName: pkg-gitops-app-sa
fetch:
- git:
url: https://github.com/user/my-pkg-gitops-repo
ref: origin/main
subPath: packaging
template:
- ytt: {}
deploy:
- kapp: {}
The App will be pointed at the git repository branch where kapp-controller resources (e.g. PackageRepository and Packages) will be defined. Read more on setting the App up with a private git repository here.
By default, an App custom resource will sync the cluster with its fetch source every 30 seconds to prevent the cluster state from drifting from its source of truth, which is a git repository in this case.
NOTE: The App should be managed separately from any additional kapp-controller resources
stored in a git repository for a gitops workflow. One potential example could be storing the
App definition and associated RBAC in the same git repository it is fetching from and have a
CI/CD process redeploy only the App when a change is made to the App itself versus other resourcees
in the repository. For simplicity in the example above, the user is deploying the App with
kubectl
or kapp
manually.
After creating the App, a user can define a PackageRepository like below:
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageRepository
metadata:
name: tce-repository
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-group: "tce-repo"
spec:
fetch:
imgpkgBundle:
image: projects.registry.vmware.com/tce/main:0.10.0
This PackageRepository will install the Tanzu Community Edition packages on the cluster where kapp-controller is installed.
Next, a user can pick which Packages to install on the cluster by defining PackageInstall resources. The Tanzu Community Edition repository offers several Packages that are documented here.
For our gitops example, let’s say the user is installing cert-manager and contour on the cluster. To do this, a user could define the following PackageInstall along with associated RBAC. NOTE: The example below gives cluster admin permissions to the serviceaccount. Make sure to assess appropriate RBAC needed for your specific PackageInstalls.
RBAC:
apiVersion: v1
kind: ServiceAccount
metadata:
name: pkg-gitops-pkgi-sa
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-group: "packageinstall-setup"
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-admin-cluster-role
annotations:
kapp.k14s.io/change-group: "packageinstall-setup"
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-admin-cluster-role-binding
annotations:
kapp.k14s.io/change-group: "packageinstall-setup"
subjects:
- kind: ServiceAccount
name: pkg-gitops-pkgi-sa
namespace: pkg-gitops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin-cluster-role
PackageInstalls:
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
name: cert-manager
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-group: "cert-manager"
kapp.k14s.io/change-rule.create-order: "upsert after upserting packageinstall-setup"
kapp.k14s.io/change-rule.delete-order: "delete before deleting packageinstall-setup"
spec:
serviceAccountName: pkg-gitops-pkgi-sa
packageRef:
refName: cert-manager.community.tanzu.vmware.com
versionSelection:
constraints: 1.5.4
---
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
name: contour
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-rule.create-order: "upsert after upserting cert-manager"
kapp.k14s.io/change-rule.delete-order: "delete before deleting packageinstall-setup"
spec:
serviceAccountName: pkg-gitops-pkgi-sa
packageRef:
refName: contour.community.tanzu.vmware.com
versionSelection:
constraints: 1.17.1
The structure of the git repository might look like the example below. In this structure,
the App definition is stored under a folder called app. The App definition above uses a
property called subPath
to tell kapp-controller to only fetch and sync resources found
under the packaging folder of this git repository. The packaging folder will contain the
PackageRepository, PackageInstalls, and associated RBAC.
.
├── app
│ ├── app.yml
│ ├── rbac.yml
└── packaging
├── packageinstalls.yml
├── rbac.yml
└── repo.yml
The user can then check in and commit the App, PackageRepository, RBAC, and PackageInstalls to the main branch of the git repository and push up the resources.
To deploy the PackageRepository, RBAC, and PackageInstalls, create the App by running the following commands:
# Use kubectl
kubectl apply -f app/
# Use kapp
kapp deploy -a pkg-gitops -f app/
Once committed, the App custom resource created will create the PackageRepository, RBAC, and PackageInstalls on the cluster.
The user can view the status of the deployment through the App as well by running the following:
kubectl get apps/pkg-gitops-example -n pkg-gitops
When the App’s status is Reconcile succeeded
, cert-manager and contour should be installed on the
cluster. This can be verified by running the following command:
kubectl get pkgi -n pkg-gitops
Making an Update ¶
When it’s time to make an update to Packages installed on your cluster, a user can simply open a pull request to the main branch of the git repositoy, make necessary changes in the pull request review, and then merge when ready to introduce the change to the cluster.
To expand on the example above, a user may want to upgrade contour to a later version (e.g. 1.17.2). To do this, check out the git repository, edit the version used for the PackageInstall like below, and then commit the change to the main branch.
apiVersion: packaging.carvel.dev/v1alpha1
kind: PackageInstall
metadata:
name: contour
namespace: pkg-gitops
annotations:
kapp.k14s.io/change-rule.create-order: "upsert after upserting cert-manager"
kapp.k14s.io/change-rule.delete-order: "delete before deleting packageinstall-setup"
spec:
serviceAccountName: pkg-gitops-pkgi-sa
packageRef:
refName: contour.community.tanzu.vmware.com
versionSelection:
constraints: 1.17.2
Once committed, the App custom resource will eventually sync in the changes. The change can be verified by running the following command and checking in the kubectl output that the contour PackageInstall is now using version 1.17.2:
kubectl get pkgi/contour -n pkg-gitops
(Help improve our docs: edit this page on GitHub)