Skip to main content

Quickstart

This guide presents a basic introduction to Kargo. Together, we will:

  1. Create a local Kubernetes cluster with Kargo and its dependencies already installed.

  2. Install the Kargo CLI.

  3. Demonstrate how Kargo can progress changes through multiple stages by interacting with your GitOps repository and Argo CD Application resources.

  4. 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:

curl -L https://raw.githubusercontent.com/akuity/kargo/main/hack/quickstart/kind.sh | sh
note

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

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.

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.

  1. Visit https://github.com/akuity/kargo-demo and fork the repository into your own GitHub account.

  2. 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>/.

    note

    This layout is typical of a GitOps repository using Kustomize for configuration management and is not at all Kargo-specific.

    Kargo also works just as well with Helm.

  3. 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 Applications 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.

info

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.

  1. 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>
  2. Then, log into Kargo:

    kargo login https://localhost:8444 \
    --admin \
    --password admin \
    --insecure-skip-tls-verify
  3. Next, we'll create a Kargo project, which is really a specially labeled Kubernetes Namespace:

    kargo create project kargo-demo
  4. To create some credentials (a Kubernetes Secret) for writing to our GitOps repository, we will fall back on kubectl:

    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}
    EOF
    info

    Falling back on kubectl for credential management is necessary at this time because the Kargo API server lacks sufficient permissions to manage Kubernetes Secret resources.

    This will be addressed in future versions.

  5. Next, returning to the kargo CLI, we create a Warehouse and three Kargo Stage resources. All of this his can be thought of as an orchestration layer for our GitOps repository and Argo CD Application 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
  6. Use the CLI to view our Warehouse resource:

    kargo get warehouses --project kargo-demo

    Sample output:

    NAME         AGE
    kargo-demo 13s
  7. 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
  8. Our Warehouse, which subscribes to the nginx image repository, also should have already produced Freight:

    kargo get freight --project kargo-demo

    Sample output:

    NAME                                       AGE
    47b33c0c92b54439e5eb7fb80ecc83f8626fe390 5m49s
    info

    Freight 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 the nginx container image.

  9. 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})
  10. Now, let's promote the Freight into the test 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 a Pending phase, but more than likely, it will almost immediately be Running, or even Succeeded:

    NAME                                      STAGE   FREIGHT                                    PHASE     AGE
    test.01haswttm2p4qwcenpnn5s1m96.b73f9d1 test b73f9d1afaca87254b64e64e5439557e86dcba79 Running 7s

    Once the Promotion has succeeded, we can again view all Stage resources in our project, and at a glance, see that the test Stage is now either in a Progressing or Healthy state.

    kargo get stages --project kargo-demo

    Sample output:

    NAME   CURRENT FREIGHT                            HEALTH        AGE
    prod Healthy 6m55s
    test b73f9d1afaca87254b64e64e5439557e86dcba79 Progressing 6m55s
    uat Healthy 6m55s

    We can repeat the command above until our Promotion is in a Healthy 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 our test Stage in more detail, we will see that it now reflects its current Freight, and the history of all Freight 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"
    }
    ],
    }
    ]
    }
  11. If we look at our Freight in greater detail, we'll see that by virtue of the test Stage having achieved a Healthy state, the Freight is now qualified in test, which designates it as eligible for promotion to the next Stage -- 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.

info

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 Stages both subscribe to other, upstream Stages, thereby forming a pipeline:

  1. uat subscribes to test
  2. prod subscribes to uat.

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.

info

The uat and prod instances of our site should be accessible at:

info

It is possible to automate promotion of new, qualified Freight for designated Stages 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 delete cluster --name kargo-quickstart