Quickstart
This guide presents a basic introduction to Kargo. Together, we will:
-
Create a local Kubernetes cluster with Kargo and its dependencies already installed.
-
Install the Kargo CLI.
-
Demonstrate how Kargo can progress changes through multiple stages by interacting with your GitOps repository and Argo CD
Application
resources. -
Clean up.
Prerequisites
- Docker
- kind or k3d: These
instructions were tested with:
- kind: v0.17.0
- k3d: v5.4.9
- Helm v3.13.1 or greater
Starting a Local Cluster
With our prerequisites met, we can execute a helper script to launch a kind or k3d cluster and install Kargo along with its dependencies:
- kind
- k3d
- More Info
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/kind.sh | sh
curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/k3d.sh | sh
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.
Either script should only:
- Launch a kind or k3d cluster
- Install cert-manager
- Install Argo CD
- 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:8443.
The username and password are both
admin
. -
The Kargo dashboard will be accessible at localhost:8444.
The admin password is
admin
. -
You can safely ignore all cert errors for both of the above.
Installing the Kargo CLI
- Mac, Linux, or WSL
- Windows Powershell
To download the Kargo CLI:
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 kargo
Then move kargo
to a location in your file system that is included in the
value of your PATH
environment variable.
To download the Kargo CLI:
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 your PATH
environment variable.
Trying It Out
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 create 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: Application
metadata:
name: kargo-demo-test
namespace: argocd
annotations:
kargo.akuity.io/authorized-stage: kargo-demo:test
spec:
project: default
source:
repoURL: ${GITOPS_REPO_URL}
targetRevision: stage/test
path: stages/test
destination:
server: https://kubernetes.default.svc
namespace: kargo-demo-test
syncPolicy:
syncOptions:
- CreateNamespace=true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kargo-demo-uat
namespace: argocd
annotations:
kargo.akuity.io/authorized-stage: kargo-demo:uat
spec:
project: default
source:
repoURL: ${GITOPS_REPO_URL}
targetRevision: stage/uat
path: stages/uat
destination:
server: https://kubernetes.default.svc
namespace: kargo-demo-uat
syncPolicy:
syncOptions:
- CreateNamespace=true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kargo-demo-prod
namespace: argocd
annotations:
kargo.akuity.io/authorized-stage: kargo-demo:prod
spec:
project: default
source:
repoURL: ${GITOPS_REPO_URL}
targetRevision: stage/prod
path: stages/prod
destination:
server: https://kubernetes.default.svc
namespace: kargo-demo-prod
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.
Our three stages all existing in a single cluster is for the sake of expediency. A single Argo CD control plane can manage multiple clusters, so these could just as easily have been spread across multiple clusters.
Hands on with the Kargo CLI
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> -
Then, log into Kargo:
kargo login https://localhost:8444 \
--admin \
--password admin \
--insecure-skip-tls-verify -
Next, we'll create a Kargo project, which is really a specially labeled Kubernetes
Namespace
:kargo create project kargo-demo
-
To create some credentials (a Kubernetes
Secret
) for writing to our GitOps repository, we will fall back onkubectl
:cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: kargo-demo-repo
namespace: kargo-demo
labels:
kargo.akuity.io/secret-type: repository
stringData:
type: git
project: default
url: ${GITOPS_REPO_URL}
username: ${GITHUB_USERNAME}
password: ${GITHUB_PAT}
EOFinfoFalling back on
kubectl
for credential management is necessary at this time because the Kargo API server lacks sufficient permissions to manage KubernetesSecret
resources.This will be addressed in future versions.
-
Next, returning to the
kargo
CLI, we create aWarehouse
and three KargoStage
resources. All of this his can be thought of as an orchestration layer for our GitOps repository and Argo CDApplication
resources.cat <<EOF | kargo apply -f -
apiVersion: kargo.akuity.io/v1alpha1
kind: Warehouse
metadata:
name: kargo-demo
namespace: kargo-demo
spec:
subscriptions:
- image:
repoURL: nginx
semverConstraint: ^1.24.0
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: test
namespace: kargo-demo
spec:
subscriptions:
warehouse: kargo-demo
promotionMechanisms:
gitRepoUpdates:
- repoURL: ${GITOPS_REPO_URL}
writeBranch: stage/test
kustomize:
images:
- image: nginx
path: stages/test
argoCDAppUpdates:
- appName: kargo-demo-test
appNamespace: argocd
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: uat
namespace: kargo-demo
spec:
subscriptions:
upstreamStages:
- name: test
promotionMechanisms:
gitRepoUpdates:
- repoURL: ${GITOPS_REPO_URL}
writeBranch: stage/uat
kustomize:
images:
- image: nginx
path: stages/uat
argoCDAppUpdates:
- appName: kargo-demo-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: stage/prod
kustomize:
images:
- image: nginx
path: stages/prod
argoCDAppUpdates:
- appName: kargo-demo-prod
appNamespace: argocd
EOF -
Use the CLI to view our
Warehouse
resource:kargo get warehouses --project kargo-demo
Sample output:
NAME AGE
kargo-demo 13s -
Use the CLI to view our three
Stage
resources:kargo get stages --project kargo-demo
Sample output:
NAME CURRENT FREIGHT HEALTH AGE
prod Healthy 20s
test Healthy 20s
uat Healthy 20s -
Our
Warehouse
, which subscribes to thenginx
image repository, also should have already producedFreight
:kargo get freight --project kargo-demo
Sample output:
NAME AGE
47b33c0c92b54439e5eb7fb80ecc83f8626fe390 5m49sinfoFreight
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 thenginx
container image. -
-
We'll use it later, so save the ID of the
Freight
to an environment variable:export FREIGHT_ID=$(kargo get freight --project kargo-demo --output jsonpath={.id})
-
Now, let's promote the
Freight
into thetest
Stage
:kargo stage promote kargo-demo test --freight $FREIGHT_ID
Sample output:
Promotion Created: "test.01haswttm2p4qwcenpnn5s1m96.b73f9d1"
Query for
Promotion
resources within our project to see one has been created:kargo get promotions --project kargo-demo
Our
Promotion
may briefly appear to be in aPending
phase, but more than likely, it will almost immediately beRunning
, or evenSucceeded
:NAME STAGE FREIGHT PHASE AGE
test.01haswttm2p4qwcenpnn5s1m96.b73f9d1 test b73f9d1afaca87254b64e64e5439557e86dcba79 Running 7sOnce the
Promotion
has succeeded, we can again view allStage
resources in our project, and at a glance, see that thetest
Stage
is now either in aProgressing
orHealthy
state.kargo get stages --project kargo-demo
Sample output:
NAME CURRENT FREIGHT HEALTH AGE
prod Healthy 6m55s
test b73f9d1afaca87254b64e64e5439557e86dcba79 Progressing 6m55s
uat Healthy 6m55sWe can repeat the command above until our
Promotion
is in aHealthy
state and we can further validate the success of this entire process by visiting the test instance of our site at localhost:8081.If we once again view the
status
of ourtest
Stage
in more detail, we will see that it now reflects its currentFreight
, and the history of allFreight
that have passed through this stage. (The collection is ordered most to least recent.)kargo get stage test --project kargo-demo --output jsonpath-as-json={.status}
Truncated sample output:
{
"currentFreight": {
"id": "b73f9d1afaca87254b64e64e5439557e86dcba79",
"images": [
{
"repoURL": "nginx",
"tag": "1.25.3"
}
],
},
...
"history": [
{
"id": "b73f9d1afaca87254b64e64e5439557e86dcba79",
"images": [
{
"repoURL": "nginx",
"tag": "1.25.3"
}
],
}
]
} -
If we look at our
Freight
in greater detail, we'll see that by virtue of thetest
Stage
having achieved aHealthy
state, theFreight
is now qualified intest
, which designates it as eligible for promotion to the nextStage
-- in our case,uat
.kargo get freight $FREIGHT_ID --project kargo-demo --output jsonpath-as-json={.status}
Sample output:
{
"qualifications": {
"test": {}
}
}
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
within the stages/test/
directory, and written the modified configuration to a
stage-specific branch -- the same branch referenced by the test
Argo CD
Applicaton
's targetRevision
field.
Although not strictly required for all cases, using stage-specific branches is a
suggested practice that enables Kargo to transition each Stage
into any new or
previous state, at any time, with a new commit that replaces the entire contents
of the branch -- all without disrupting the main
branch.
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 kargo stage promote
command to progress the Freight
from stage
to uat
and again from uat
to
prod
.
The uat
and prod
instances of our site should be accessible at:
uat
: localhost:8082prod
: localhost:8083
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!
To clean up, we will simply destroy our kind or k3d cluster:
- kind
- k3d
kind delete cluster --name kargo-quickstart
k3d cluster delete kargo-quickstart