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

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

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

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.

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.

note

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.

  1. 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>
  2. Create namespaces for each of our three stages, a Secret containing repository credentials, and Argo CD Application 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
    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 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!

  1. Begin by logging into Kargo:

    kargo login https://localhost:8444 \
    --admin \
    --password admin \
    --insecure-skip-tls-verify
  2. Next, 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 CD Application 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
    EOF

    Use 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 20s
  3. Dissecting the manifest from the previous step, we see the test Stage subscribes directly to the nginx image repository. When a new version of the nginx container image matching the specified constraints is discovered, Kargo has discovered new Freight.

    info

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

    We can query the status of the test Stage to see the latest Freight 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 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 and is currently pending:

    kargo get promotions --project kargo-demo

    Sample output:

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

    We can repeat the command above until our Promotion has succeeded.

    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.

    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 not only Freight available to the Stage, but also 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:

    [
    {
    "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 a Healthy state with its current Freight, the sample output above shows the current Freight is now qualified, which designates it as eligible for promotion to the next Stage -- 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.

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