Carvel Logo

Lightweight continuous delivery to Kubernetes

Codify your application deployment in a first-class Kubernetes resource — App CR. Have Kubernetes fetch application configuration from various sources, template and customize it, and see it converge continuously.

Consistent

App CR provides a common consistent API for configuring and deploying your applications regardless if it is a Helm chart, plain YAML configuration, ytt templates, etc.

Composable

Take advantage of different tools for each stage -- fetch, template and deploy. For example, fetch Helm templates from a Git repository, use Helm to template them, make modifications with ytt overlays, and finally deploy with kapp.

Lightweight

kapp-controller delegates all the heavy lifting to existing configuration management and deployment tools. In doing so, kapp-controller itself is kept very simple, and therefore provides a high degree of reliability.

Basic Usage

Describe in simple-app.yml how to fetch, template, and deploy your application:

apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
  name: simple-app
  namespace: default
spec:
  serviceAccountName: default-ns-sa
  fetch:
  - git:
      url: https://github.com/vmware-tanzu/carvel-simple-app-on-kubernetes
      ref: origin/develop
      subPath: config-step-1-minimal
  template:
  - ytt: {}
  deploy:
  - kapp: {}

Let's apply configuration to your cluster and see it get reconciled.

$ kubect apply -f simple-app.yml

$ kubectl get app
NAME         DESCRIPTION           SINCE-DEPLOY   AGE
simple-app   Reconcile succeeded   6s             28s

Also take a look at more detailed information about deployed app via kubectl get app simple-app -oyaml.

apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
  name: simple-app
  namespace: default
  creationTimestamp: "2020-12-15T00:51:48Z"
  generation: 1
  resourceVersion: "37396"
  uid: dbbb639d-1f58-4a1e-ade6-39bc22ee6d82
  finalizers:
  - finalizers.kapp-ctrl.k14s.io/delete
spec:
  serviceAccountName: default-ns-sa
  fetch:
  - git:
      url: https://github.com/vmware-tanzu/carvel-simple-app-on-kubernetes
      ref: origin/develop
      subPath: config-step-1-minimal
  template:
  - ytt: {}
  deploy:
  - kapp: {}
status:
  observedGeneration: 1
  conditions:
  - status: "True"
    type: ReconcileSucceeded
  friendlyDescription: Reconcile succeeded
  fetch:
    exitCode: 0
    startedAt: "2020-12-15T00:52:10Z"
    updatedAt: "2020-12-15T00:52:10Z"
  template:
    exitCode: 0
    updatedAt: "2020-12-15T00:52:10Z"
  deploy:
    exitCode: 0
    finished: true
    startedAt: "2020-12-15T00:52:10Z"
    stdout: |-
      Target cluster 'https://10.96.0.1:443'
      Changes
      Namespace  Name        Kind        Conds.  Age  Op      Op st.  Wait to    Rs  Ri
      default    simple-app  Deployment  -       -    create  -       reconcile  -   -
      ^          simple-app  Service     -       -    create  -       reconcile  -   -
      Op:      2 create, 0 delete, 0 update, 0 noop
      Wait to: 2 reconcile, 0 delete, 0 noop
      12:52:10AM: ---- applying 2 changes [0/2 done] ----
      12:52:10AM: create service/simple-app (v1) namespace: default
      12:52:12AM: create deployment/simple-app (apps/v1) namespace: default
      12:52:12AM: ---- waiting on 2 changes [0/2 done] ----
      12:52:12AM: ok: reconcile service/simple-app (v1) namespace: default
      12:52:12AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default
      12:52:12AM:  ^ Waiting for generation 2 to be observed
      12:52:12AM:  L ok: waiting on replicaset/simple-app-69f4586488 (apps/v1) namespace: default
      12:52:12AM:  L ongoing: waiting on pod/simple-app-69f4586488-9qrx2 (v1) namespace: default
      12:52:12AM:     ^ Pending: ContainerCreating
      12:52:12AM: ---- waiting on 1 changes [1/2 done] ----
      12:52:12AM: ongoing: reconcile deployment/simple-app (apps/v1) namespace: default
      12:52:12AM:  ^ Waiting for 1 unavailable replicas
      12:52:12AM:  L ok: waiting on replicaset/simple-app-69f4586488 (apps/v1) namespace: default
      12:52:12AM:  L ongoing: waiting on pod/simple-app-69f4586488-9qrx2 (v1) namespace: default
      12:52:12AM:     ^ Pending: ContainerCreating
      12:52:13AM: ok: reconcile deployment/simple-app (apps/v1) namespace: default
      12:52:13AM: ---- applying complete [2/2 done] ----
      12:52:13AM: ---- waiting complete [2/2 done] ----
      Succeeded      
    updatedAt: "2020-12-15T00:52:13Z"
  inspect:
    exitCode: 0
    stdout: |-
      Target cluster 'https://10.96.0.1:443'
      Resources in app 'simple-app-ctrl'
      Namespace  Name                         Kind        Owner    Conds.  Rs  Ri  Age
      default    simple-app                   Deployment  kapp     2/2 t   ok  -   3s
      ^          simple-app                   Endpoints   cluster  -       ok  -   3s
      ^          simple-app                   Service     kapp     -       ok  -   3s
      ^          simple-app-69f4586488        ReplicaSet  cluster  -       ok  -   3s
      ^          simple-app-69f4586488-9qrx2  Pod         cluster  4/4 t   ok  -   3s
      Rs: Reconcile state
      Ri: Reconcile information
      5 resources
      Succeeded      
    updatedAt: "2020-12-15T00:52:13Z"

Getting started

To help you get started, see the documentation.