This article was written using Kargo version 0.3.1.
Introduction#
Last month I presented Flamingo, which combines both Argo CD and Flux CD to take advantage of these two tools and adopt a GitOps approach.
However, GitOps or the above tools do not define a means of promoting changes that have been made from a development environment to a qualification or production environment.
In fact, Argo CD and Flux CD are responsible to deploy one or more target environments without any link or relationship between them.
However, it is possible to adopt a Branching Model to promote these changes. If you’re not familiar with the term, I recommend you take a look at this article.
Fortunately, a solution appeared a few months ago, even if it’s still in the development phase and therefore not ready to be used in production. In this article, I’d like to give you an overview of the potential of this tool.
Kargo, the answer#
Who hasn’t dreamt of pressing a button to transfer changes from one environment to another? The most classic example is a new container image that is tested on a development environment before being deployed on a qualification environment.
This is exactly what Kargo can do, although it goes even further than image version management: it is capable of applying the different configurations of your Kubernetes objects.
Moreover, Kargo is part of the Argo Project (the same family as Argo CD) and is a 100% open source tool.
In a nutshell, Kargo is a continuous delivery platform which gives you the opportunity to orchestrate the lifecycle of applications on Kubernetes from one environment to another, using existing tools.
That’s right, Kargo works directly with Argo CD, which does what it does best: deploying Kubernetes objects.
Features#
As mentioned above, Kargo is still a very young tool, but it has a number of features:
- Promotion of configurations or containerised images from one environment to another;
- Writing changes to Git: As soon as a change is approved, Kargo generates a Pull Request and commits the changes;
- Ability to roll back changes in the event of an error;
- Creation of tests to validate the correct operation of an environment, particularly with Argo Rollouts;
- Canary and A/B testing can be used to deploy to a target environment.
This list maybe changed in future versions of Kargo. In fact, the team’s objective is to enhance the product in future versions until it reaches a first major version (1.0.0) in order to encourage the adoption of Kargo in production environments.
Kargo has a user interface that allows changes to be tracked at a glance:
This interface also allows you to view the images or configurations associated with the defined environments. This makes it possible to have a history and to audit all the actions within Kargo.
Finally, the large black bar at the top is called the freight line (Freight), as in the case of goods transport. Now, you see the link between that and Kargo, right?
How does it work?#
Let’s discuss about how Kargo works and how it manages environments, especially when a new image version is available.
Here is the sequence of operations in order:
- The CI, whatever the platform, creates a new container image;
- The image is pushed in a container registry;
- Depending on the configurations defined, Kargo analyses the Git repository containing the Kubernetes objects (1) and searches for any new associated images (2);
- Depending on the new images retrieved, the developer has the choice to promote these changes on the first environment configured, which in this case will be development;
- Once the developer has validated the changes, Kargo pushes them into Git;
- With the previous action, Argo CD is triggered and detects an update to the files in the development environment;
- Argo CD synchronises the changes on the Kubernetes cluster;
- Kargo retrieves the status of the deployed objects and enables tests to be carried out;
- If everything is OK, the developer can approve these changes for the next environment.
On the installation side, Kargo is best deployed with a Helm chart, and it is recommended that it is positioned as close as possible to the Argo CD, as it interacts directly with it.
As you can see, Kargo allows you to chain one or more environments according to your deployment cycle. These environments are embodied in a Kubernetes object called a Stage
:
apiVersion: v1
kind: Namespace
metadata:
name: kargo-demo
labels:
kargo.akuity.io/project: "true"
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
name: docker-registry
namespace: kargo-demo
spec:
subscriptions:
- image:
repoURL: nginx
semverConstraint: ^1.24.0
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: dev
namespace: kargo-demo
spec:
subscriptions:
warehouse: docker-registry
promotionMechanisms:
gitRepoUpdates:
- repoURL: ${GITOPS_REPO_URL}
writeBranch: main
kustomize:
images:
- image: nginx
path: overlays/dev
argoCDAppUpdates:
- appName: nginx-dev
appNamespace: argocd
Here’s an example of how to generate a dev environment within Kargo. This is made up of several Kustomize base
, overlays/dev
, overlays/uat
and overlays/prod
folders to reference the specific configurations of each environment. Note that this code repository deploys a simple deployment containing an nginx image.
If you want to reproduce this at home, I advise you to use this example which provides the steps to follow to test Kargo.
I’ve made a few small changes to the basic version. Instead of creating a branch for each environment, I use the main branch with the writeBranch: main
parameter.
As you can see, the dev environment listens on a docker-regitry Warehouse
object which retrieves new nginx
images by following the associated semver constraint (^1.24.0
). In addition, the argoCDAppUpdates
block links up with Argo CD, which orchestrates deployment once the changes have been approved.
Note that creating a Namespace
with the label kargo.akuity.io/project: "true"
is essential for referencing the kargo-demo project within the tool.
Here are the steps between an image registry and a development environment. Of course, it’s possible to go further and add environments in succession in this way, always in the form of stages
.
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: uat
namespace: kargo-demo
spec:
subscriptions:
upstreamStages:
- name: dev
promotionMechanisms:
gitRepoUpdates:
- repoURL: ${GITOPS_REPO_URL}
writeBranch: main
kustomize:
images:
- image: nginx
path: overlays/uat
argoCDAppUpdates:
- appName: nginx-uat
appNamespace: argocd
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: prod
namespace: kargo-demo
spec:
subscriptions:
upstreamStages:
- name: uat
promotionMechanisms:
gitRepoUpdates:
- repoURL: ${GITOPS_REPO_URL}
writeBranch: main
kustomize:
images:
- image: nginx
path: overlays/prod
argoCDAppUpdates:
- appName: nginx-prod
appNamespace: argocd
Your Kargo pipeline should look like this:
The promotion mechanism can be used directly from the interface or on the command line:
As mentioned above, the promotion will commit directly to your code repository, triggering deployment within Argo CD :
It is entirely possible to continue and update subsequent environments by carrying out the same steps for uat and prod.
Finally, Kargo makes it possible to work with several types of source within the warehouse object, including image registries, Git code repositories and Helm chart registries.
A few final words…#
Rather than fiddling with a CI/CD chain based on diff
and sed
to promote your changes, Kargo brings with it a lack often expressed when talking about GitOps tools: orchestration between environments.
Once again, Kargo is still very young, but I personally think it has great potential. In the future, it may even become essential with any Argo CD installation.
Don’t hesitate to follow Kargo releases and updates on GitHub.