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: These instructions were tested with v3.11.2.
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 403
it is likely that docker
is
configured to authenticate to ghcr.io
with an expired token.
To resolve this, remove or renew the credentials using one of:
docker logout ghcr.io
docker login 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 a base/
directory as well as stage-specific overlays in
paths of the form stages/<stage name>/
. Kustomize
is used as a configuration management tool that combines base configuration with
stage-specific configuration.
This layout is typical of a GitOps repository using Kustomize and is not at all Kargo-specific.
Kargo also works just as well with Helm and with plain YAML.
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.
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 the location of your GitOps repository, your GitHub handle, and your personal access token in environment variables:
export GITOPS_REPO_URL=<your repo URL, starting with https://>
export GITHUB_USERNAME=<your github handle>
export GITHUB_PAT=<your personal access token>Create namespaces for each of our three stages, a
Secret
containing repository credentials, and Argo CDApplication
resources for each stage:cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: kargo-demo-test
---
apiVersion: v1
kind: Namespace
metadata:
name: kargo-demo-uat
---
apiVersion: v1
kind: Namespace
metadata:
name: kargo-demo-prod
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: kargo-demo-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
annotations:
kargo.akuity.io/authorized-projects: kargo-demo
stringData:
type: git
project: default
url: ${GITOPS_REPO_URL}
username: ${GITHUB_USERNAME}
password: ${GITHUB_PAT}
---
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
---
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
---
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
EOFIf 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 theirtargetRevision
fields do not even exist yet.infoOur 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 also 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!
Begin by logging into Kargo:
kargo login https://localhost:8444 \
--admin \
--password admin \
--insecure-skip-tls-verifyNext, we'll create a Kargo project (a specially labeled namespace) and three Kargo
Stage
resources. This can be thought of as an orchestration layer for our GitOps repository and Argo CDApplication
resources.cat <<EOF | kargo apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: kargo-demo
labels:
kargo.akuity.io/project: "true"
---
apiVersion: kargo.akuity.io/v1alpha1
kind: Stage
metadata:
name: test
namespace: kargo-demo
spec:
subscriptions:
repos:
images:
- repoURL: nginx
semverConstraint: ^1.24.0
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
EOFUse the CLI to view the three
Stage
resources in our new project:kargo get stages --project kargo-demo
Sample output:
NAME CURRENT FREIGHT HEALTH AGE
prod Healthy 20s
test Healthy 20s
uat Healthy 20sDissecting the manifest from the previous step, we see the
test
Stage
subscribes directly to thenginx
image repository. When a new version of thenginx
container image matching the specified constraints is discovered, Kargo has discovered newFreight
.infoFreight
is a set of references to one or more versioned artifacts, which and 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 can query the status of the
test
Stage
to see the latestFreight
available to it:kargo get stage test --project kargo-demo --output jsonpath-as-json={.status}
Truncated sample output:
[
{
"availableFreight": [
{
"firstSeen": "2023-09-20T18:09:05Z",
"id": "b73f9d1afaca87254b64e64e5439557e86dcba79",
"images": [
{
"repoURL": "nginx",
"tag": "1.25.2"
}
],
"qualified": true
}
],
...
}
]Save the ID of the available
Freight
to an environment variable for convenience:export FREIGHT_ID=$(kargo get stage test --project kargo-demo --output jsonpath={.status.availableFreight\[0\].id})
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 and is currently pending:kargo get promotions --project kargo-demo
Sample output:
NAME STAGE FREIGHT PHASE AGE
test.01haswttm2p4qwcenpnn5s1m96.b73f9d1 test b73f9d1afaca87254b64e64e5439557e86dcba79 Pending 7sWe can repeat the command above until our
Promotion
has succeeded.Once 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.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 not onlyFreight
available to theStage
, but also 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:
[
{
"availableFreight": [
...
],
"currentFreight": {
"firstSeen": "2023-09-20T18:52:12Z",
"id": "b73f9d1afaca87254b64e64e5439557e86dcba79",
"images": [
{
"repoURL": "nginx",
"tag": "1.25.2"
}
],
"qualified": true
},
...
"history": [
{
"firstSeen": "2023-09-20T18:52:12Z",
"id": "b73f9d1afaca87254b64e64e5439557e86dcba79",
"images": [
{
"repoURL": "nginx",
"tag": "1.25.2"
}
],
"qualified": true
}
]
}
]Importantly, by virtue of the
test
Stage
having achieved aHealthy
state with its currentFreight
, the sample output above shows the currentFreight
is now qualified, which designates it as eligible for promotion to the nextStage
--uat
.
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