Kargo Quickstart
This guide presents a basic introduction to Kargo. Together, we will:
-
Install Kargo and its dependencies into an existing, local Kubernetes cluster.
OR
Create a new local Kubernetes cluster with Kargo and its dependencies already installed.
-
Demonstrate how Kargo can progress changes through multiple stages by interacting with your GitOps repository and Argo CD
Application
resources. -
Clean up.
If you're looking to contribute to Kargo, you may wish to consult the contributor guide instead.
Starting a Local Cluster
Any of the following approaches require Helm v3.13.1 or greater to be installed.
- Docker Desktop
- OrbStack
- kind
- k3d
- More Info
If you are a Docker Desktop user, you can follow these instructions to enable its built-in Kubernetes support.
Although this is one of the fastest paths to a local Kubernetes cluster, be aware that Docker Desktop supports only a single Kubernetes cluster. If that cluster reaches a state you are dissatisfied with, resetting it will remove not just Kargo-related resources, but all your workloads and data.
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/install.sh | sh
OrbStack is a fast, lightweight, drop-in replacement for Docker Desktop for Mac OS only. You can follow these instructions to enable its built-in Kubernetes support.
Although this is one of the fastest paths to a local Kubernetes cluster, be aware that OrbStack supports only a single Kubernetes cluster. If that cluster reaches a state you are dissatisfied with, resetting it will remove not just Kargo-related resources, but all your workloads and data.
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/install.sh | sh
If you have any Docker-compatible container runtime installed (including native Docker, Docker Desktop, or OrbStack), you can easily launch a disposable cluster just for this quickstart using kind.
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/kind.sh | sh
While this option is a bit more complex than using Docker Desktop or OrbStack directly, it offers the advantage of being fully-disposable. If your cluster reaches a state you are dissatisfied with, you can simply destroy it and launch a new one.
If you have any Docker-compatible container runtime installed (including native Docker, Docker Desktop, or OrbStack), you can easily launch a disposable cluster just for this quickstart using k3d.
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/k3d.sh | sh
While this option is a bit more complex than using Docker Desktop or OrbStack directly, it offers the advantage of being fully-disposable. If your cluster reaches a state you are dissatisfied with, you can simply destroy it and launch a new one.
If you are averse to piping a downloaded script directly into a shell, please feel free to download the applicable script and inspect its contents prior to execution.
Any approach you select should only:
- Launch a new, local Kubernetes cluster, if applicable
- Install cert-manager
- Install Argo CD
- Install Argo Rollouts
- Install Kargo
If Kargo installation fails with a 401
, verify that you are using Helm v3.13.1
or greater.
If Kargo installation fails with a 403
, it is likely that Docker is configured
to authenticate to ghcr.io
with an expired token. The Kargo chart and images
are accessible anonymously, so this issue can be resolved simply by logging out:
docker logout ghcr.io
At the end of this process:
-
The Argo CD dashboard will be accessible at localhost:31443.
The username and password are both
admin
. -
The Kargo dashboard will be accessible at localhost:31444.
The admin password is
admin
. -
You can safely ignore all cert errors for both of the above.
Create a GitOps Repository
Let's begin by creating a repository on GitHub to house variations of our application manifests for three different stages of a sample application: test, UAT, and production.
-
Visit https://github.com/akuity/kargo-demo and fork the repository into your own GitHub account.
-
You can explore the repository and see that the
main
branch contains common configuration in abase/
directory as well as stage-specific overlays in paths of the formstages/<stage name>/
. -
We'll be using it later, so save the location of your GitOps repository in an environment variable:
export GITOPS_REPO_URL=<your repo URL, starting with https://>
Create Argo CD Application Resources
In this step, we will use an Argo CD ApplicationSet
resource to create and
manage three Argo CD Application
resources that deploy the sample application
at three different stages of its lifecycle, with three slightly different
configurations, to three different namespaces in our local cluster:
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: kargo-demo
namespace: argocd
spec:
generators:
- list:
elements:
- stage: test
- stage: uat
- stage: prod
template:
metadata:
name: kargo-demo-{{stage}}
annotations:
kargo.akuity.io/authorized-stage: kargo-demo:{{stage}}
spec:
project: default
source:
repoURL: ${GITOPS_REPO_URL}
targetRevision: stage/{{stage}}
path: .
destination:
server: https://kubernetes.default.svc
namespace: kargo-demo-{{stage}}
syncPolicy:
syncOptions:
- CreateNamespace=true
EOF
If you visit your Argo CD dashboard, you will notice
all three Argo CD Application
s have not yet synced because they're not
configured to do so automatically, and in fact, the branches referenced by their
targetRevision
fields do not even exist yet.
Your First Kargo Project
Up to this point, we haven't done anything with Kargo -- in fact everything we've done thus far should be familiar to anyone who's already using Argo CD and Kustomize. Now it's time to see what Kargo can do!
To get started, you will need a GitHub personal access token with adequate permissions to read from and write to the repository you forked in the previous section.
-
Save your GitHub handle and your personal access token in environment variables:
export GITHUB_USERNAME=<your github handle>
export GITHUB_PAT=<your personal access token> -
Next, we'll create several Kargo resources:
-
A
Project
, which, when reconciled, will effect all boilerplate project initialization, including the creation of a specially-labeledNamespace
with the same name as theProject
-
A
Secret
containing credentials for our GitOps repository -
A
Warehouse
that subscribes to a container image repository -
Three
Stage
resources --test
,uat
, andprod
Although we will use Kargo's UI throughout most of this quickstart, with the amount of configuration we're about to create, it is easiest to do it declaratively using either
kubectl
or thekargo
CLI.infoFor demo purposes, using
kubectl
is the quickest way to declaratively define your firstProject
. Thekargo
CLI, however, does offer Kargo-specific functionality, and for Kargo users who lack direct access to the underlying cluster, it also offers authentication via OpenID Connect. You might consider choosing this option below if you wish to become more familiar with it.- Using kubectl
- Using the Kargo CLI
To create Kargo resources, use the following command:
cat <<EOF | kubectl apply -f -
apiVersion: kargo.akuity.io/v1alpha1
kind: Project
metadata:
name: kargo-demo
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: kargo-demo-repo
namespace: kargo-demo
labels:
kargo.akuity.io/cred-type: git
stringData:
repoURL: ${GITOPS_REPO_URL}
username: ${GITHUB_USERNAME}
password: ${GITHUB_PAT}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
name: kargo-demo
namespace: kargo-demo
spec:
subscriptions:
- image:
repoURL: public.ecr.aws/nginx/nginx
semverConstraint: ^1.26.0
discoveryLimit: 5
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: test
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
direct: true
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: uat
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
stages:
- test
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: prod
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
stages:
- uat
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
EOFInstall the Kargo CLI:
- Mac, Linux, or WSL
- Windows Powershell
arch=$(uname -m)
[ "$arch" = "x86_64" ] && arch=amd64
curl -L -o kargo https://github.com/akuity/kargo/releases/latest/download/kargo-"$(uname -s | tr '[:upper:]' '[:lower:]')-${arch}"
chmod +x kargoThen move
kargo
to a location in your file system that is included in the value of yourPATH
environment variable.Invoke-WebRequest -URI https://github.com/akuity/kargo/releases/latest/download/kargo-windows-amd64.exe -OutFile kargo.exe
Then move
kargo.exe
to a location in your file system that is included in the value of yourPATH
environment variable.Log in:
kargo login https://localhost:31444 \
--admin \
--password admin \
--insecure-skip-tls-verifyTo create Kargo resources, use the following command:
cat <<EOF | kargo apply -f -
apiVersion: kargo.akuity.io/v1alpha1
kind: Project
metadata:
name: kargo-demo
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: kargo-demo-repo
namespace: kargo-demo
labels:
kargo.akuity.io/cred-type: git
stringData:
repoURL: ${GITOPS_REPO_URL}
username: ${GITHUB_USERNAME}
password: ${GITHUB_PAT}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
name: kargo-demo
namespace: kargo-demo
spec:
subscriptions:
- image:
repoURL: public.ecr.aws/nginx/nginx
semverConstraint: ^1.26.0
discoveryLimit: 5
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: test
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
direct: true
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: uat
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
stages:
- test
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: prod
namespace: kargo-demo
spec:
requestedFreight:
- origin:
kind: Warehouse
name: kargo-demo
sources:
stages:
- uat
promotionTemplate:
spec:
vars:
- name: gitopsRepo
value: ${GITOPS_REPO_URL}
- name: imageRepo
value: public.ecr.aws/nginx/nginx
- name: srcPath
value: ./src
- name: outPath
value: ./out
steps:
- uses: git-clone
config:
repoURL: \${{ vars.gitopsRepo }}
checkout:
- branch: main
path: \${{ vars.srcPath }}
- branch: stage/\${{ ctx.stage }}
create: true
path: \${{ vars.outPath }}
- uses: git-clear
config:
path: \${{ vars.outPath }}
- uses: kustomize-set-image
as: update-image
config:
path: \${{ vars.srcPath }}/base
images:
- image: \${{ vars.imageRepo }}
tag: \${{ imageFrom(vars.imageRepo).Tag }}
- uses: kustomize-build
config:
path: \${{ vars.srcPath }}/stages/\${{ ctx.stage }}
outPath: \${{ vars.outPath }}/manifests.yaml
- uses: git-commit
as: commit
config:
path: \${{ vars.outPath }}
messageFromSteps:
- update-image
- uses: git-push
config:
path: \${{ vars.outPath }}
- uses: argocd-update
config:
apps:
- name: kargo-demo-\${{ ctx.stage }}
sources:
- repoURL: \${{ vars.gitopsRepo }}
desiredRevision: \${{ outputs.commit.commit }}
EOF -
-
Navigate to the Kargo Dashboard:
-
Log in using the password
admin
.This will take you to a list of
Project
s. It currently includes only the one created in the previous step. -
Select kargo-demo:
Here you can see a detailed overview of the
Project
we previously created. It includes:-
An interactive, visual representation of your pipeline, composed of:
- A container image repository.
- A
Warehouse
that discovers new images as they are pushed to the repository. - Three
Stage
s representing distinct instances of our demo application.
-
An interactive Freight Timeline with
Freight
ordered chronologically, with newerFreight
to the left and olderFreight
to the right.
-
-
-
After a few seconds, a piece of
Freight
should appear in the Freight Timeline, if it isn't there already.noteNote that the timeline may not refresh automatically and you may need to refresh the page to see new
Freight
.This inconvenience will be addressed in a forthcoming update.
infoFreight
is a set of references to one or more versioned artifacts, which may include:-
Container images (from image repositories)
-
Kubernetes manifests (from Git repositories)
-
Helm charts (from chart repositories)
This introductory example has
Freight
that references only a specific version of thepublic.ecr.aws/nginx/nginx
container image. -
Your First Promotion
-
To promote
Freight
to thetest
Stage
, select the target icon on the left border of test:Next, select the
Freight
from the Freight Timeline and confirm the promotion by selecting Yes:When promotion process is complete, you'll see a check mark next to test, indicating that the promotion was successful.
Following the promotion, health checks will run periodically. When a
Stage
is in a healthy state, this will be reflected with a heart icon. You can also verify the status by visiting the test instance of the demo application at localhost:30081.The Freight Timeline will also automatically update following the promotion. It is color-coded to indicate which
Stage
s are actively using each piece ofFreight
. -
Select the test to reveal additional details about the
Stage
including its status, currentFreight
, and history. -
Select the
Freight
from the Freight Timeline to reveal additional details. Importantly, you can see that (by virtue of thetest
Stage
having achieved a healthy state) theFreight
is now verified intest
, which designates it as eligible for promotion to the nextStage
-- in our case,uat
.noteAlthough this example does not demonstrate it, it is also possible to verify the
Freight
in aStage
using user-defined processes. See the relevant section of the concepts page to learn more.
Behind the Scenes
So what has Kargo done behind the scenes?
Visiting our fork of https://github.com/akuity/kargo-demo, we will see that
Kargo has recently created a stage/test
branch for us. It has taken the latest
manifests from the main
branch as a starting point, run kustomize edit set image
and kustomize build
within the stages/test/
directory, and written
the resulting manifests to a stage-specific branch -- the same branch referenced
by the test
Argo CD Application
's targetRevision
field.
Although not required for all uses cases, using stage-specific branches is a practice highly recommended by the Kargo team.
Promote to UAT and then Production
Unlike our test
Stage
, which subscribes directly to an image repository,
our uat
and prod
Stage
s both subscribe to other, upstream Stage
s,
thereby forming a pipeline:
uat
subscribes totest
prod
subscribes touat
.
We leave it as an exercise to the reader to use the dashboard to progress the
Freight
from test
to uat
and again from uat
to prod
.
The uat
and prod
instances of our site should be accessible at:
uat
: localhost:30082prod
: localhost:30083
It is possible to automate promotion of new, qualified Freight
for designated
Stage
s and also possible to used RBAC to limit who can trigger manual
promotions for each Stage
, however, both these topics are beyond the scope of
this introduction.
Cleaning up
Congratulations! You've just gotten hands on with Kargo for the first time!
Now let's clean up!
- Docker Desktop
- OrbStack
- kind
- k3d
Docker Desktop supports only a single Kubernetes cluster. If you are comfortable deleting not just just Kargo-related resources, but all your workloads and data, the cluster can be reset from the Docker Desktop Dashboard.
If, instead, you wish to preserve non-Kargo-related workloads and data, you will need to manually uninstall Kargo and its prerequisites:
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/uninstall.sh | sh
OrbStack supports only a single Kubernetes cluster. If you are comfortable deleting not just just Kargo-related resources, but all your workloads and data, you can destroy the cluster with:
orb delete k8s
If, instead, you wish to preserve non-Kargo-related workloads and data, you will need to manually uninstall Kargo and its prerequisites:
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/uninstall.sh | sh
Simply destroy the cluster:
kind delete cluster --name kargo-quickstart
Simply destroy the cluster:
k3d cluster delete kargo-quickstart