Skip to main content

Kargo Quickstart

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

  1. 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.

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

  3. Clean up.

info

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.

If you are a Docker Desktop user, you can follow these instructions to enable its built-in Kubernetes support.

info

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

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

Argo-dashboard-screenshot

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.

  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. Next, we'll create several Kargo resources:

    • A Project, which, when reconciled, will effect all boilerplate project initialization, including the creation of a specially-labeled Namespace with the same name as the Project

    • A Secret containing credentials for our GitOps repository

    • A Warehouse that subscribes to a container image repository

    • Three Stage resources -- test, uat, and prod

    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 the kargo CLI.

    info

    For demo purposes, using kubectl is the quickest way to declaratively define your first Project. The kargo 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.

    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 }}
    EOF
  3. Navigate to the Kargo Dashboard:

    1. Log in using the password admin.

      This will take you to a list of Projects. It currently includes only the one created in the previous step.

      Kargo-dashboard

    2. 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 Stages representing distinct instances of our demo application.

        Kargo-dashboard-screenshot

      • An interactive Freight Timeline with Freight ordered chronologically, with newer Freight to the left and older Freight to the right.

        Kargo-Freight-Timeline

  4. After a few seconds, a piece of Freight should appear in the Freight Timeline, if it isn't there already.

    note

    Note 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.

    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 public.ecr.aws/nginx/nginx container image.

Your First Promotion

  1. To promote Freight to the test Stage, select the target icon on the left border of test:

    Kargo-Promote

    Next, select the Freight from the Freight Timeline and confirm the promotion by selecting Yes:

    Kargo-Promote

    When promotion process is complete, you'll see a check mark next to test, indicating that the promotion was successful.

    Kargo-dashboard-screenshot

    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 Stages are actively using each piece of Freight.

  2. Select the test to reveal additional details about the Stage including its status, current Freight, and history.

  3. Select the Freight from the Freight Timeline to reveal additional details. Importantly, you can see that (by virtue of the test Stage having achieved a healthy state) the Freight is now verified in test, which designates it as eligible for promotion to the next Stage -- in our case, uat.

    Kargo-Freight-Verified

    note

    Although this example does not demonstrate it, it is also possible to verify the Freight in a Stage 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.

info

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 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 dashboard to progress the Freight from test 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!

Now let's clean up!

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