Deploying Applications with Flux and Keptn
Flux is a tool that keeps Kubernetes clusters synchronized with sources of configuration (such as Git repositories) and automates updates to the configuration when new code is deployed.
This section shows how to add Keptn pre- and post-deployment tasks to an existing Flux use case that runs pre and post-deployment jobs with Flux. Adding Keptn makes it simpler and more straight-forward to run the Flux pre and post-deployment jobs and provides added observability out of the box.
High-level structure of the Git repository
Flux uses a GitOps approach for continuous delivery. The Git repository structure for our use case looks like the following:
├── apps
│ └── dev
│ ├── podtato-head.yaml
│ └── kustomize.yaml
└── clusters
└── dev
├── flux-system
│ ├── gotk-components.yaml
│ ├── gotk-sync.yaml
│ └── kustomize.yaml
├── podtato-head-source.yaml
└── podtato-head-kustomization.yaml
The apps
directory contains application manifests, that will be deployed.
The clusters
directory contains Flux configuration manifests and custom
resources, that are needed for the delivery.
The apps
and clusters
directories can live in two separate repositories,
but for simplicity of this excercise, we will keep them in a single one.
You see that the Keptn runs pre/post-deployment tasks
rather than using the Flux pre-deploy
and post-deploy
directories in the Git repository.
The Keptn process is easier to implement
and contains more information than the Flux jobs do.
Set up your environment
Before we start, you need to install Flux CLI on your local machine and Keptn on your cluster. You can find the installation instructions for Keptn here and for Flux here.
After successfully installing Flux CLI and Keptn, you need to
retrieve your Git repository credentials.
You can use any available Git providers, but be sure to store your token
for later usage.
For simplicity, we will use GitHub.
You then need to
bootstrap the Git repository,
supplying the token
you saved,
to install Flux in your cluster.
This sets up all necessary Flux structures in the repository.
Use the following command to do this:
GITHUB_USER=<user-name> GITHUB_TOKEN=<token> \
flux bootstrap github \
--owner=$GITHUB_USER \
--repository=podtato-head \
--branch=main \
--path=./clusters/dev \
--personal
The bootstrap command above does the following:
- Creates a Git repository
podtato-head
on your GitHub account. - Adds Flux component manifests to the repository and
creates
./clusters/dev/flux-system/*
structure. - Deploys Flux components to your Kubernetes Cluster.
- Configures Flux components to track the path
./clusters/dev/
in the repository.
Creating the application
Now it's time to add the Keptn application that defines the Keptn pre- and post-deployment checks to the repository.
First, clone the podtato-head
repository to your local machine.
Add the following manifests that represent the application into the podtato-head.yaml
file
and store it in the ./apps/dev/
directory of your repository:
apiVersion: v1
kind: Namespace
metadata:
name: podtato-kubectl
annotations:
keptn.sh/lifecycle-toolkit: "enabled"
---
apiVersion: lifecycle.keptn.sh/v1
kind: KeptnAppContext
metadata:
name: podtato-head
spec:
preDeploymentTasks:
- hello-task
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: podtato-head-entry
labels:
app: podtato-head
spec:
selector:
matchLabels:
component: podtato-head-entry
template:
metadata:
labels:
component: podtato-head-entry
annotations:
keptn.sh/app: podtato-head
keptn.sh/workload: podtato-head-entry
keptn.sh/version: 0.1.0
keptn.sh/pre-deployment-tasks: hello-task
keptn.sh/post-deployment-tasks: hello-task
spec:
terminationGracePeriodSeconds: 5
containers:
- name: server
image: ghcr.io/podtato-head/entry:latest
imagePullPolicy: Always
ports:
- containerPort: 9000
env:
- name: PODTATO_PORT
value: "9000"
---
apiVersion: lifecycle.keptn.sh/v1
kind: KeptnTaskDefinition
metadata:
name: hello-task
spec:
deno:
inline:
code: |
console.log('hello');
retries: 3
See the Keptn
CRD reference
documentation for more information about the Keptn resources that are used.
See
Basic annotations
for a description of the labels and annotations that Keptn uses.
Additionally, create a kustomize.yaml
file right next to it:
You can commit and push these manifests to the Git repository.
The application has Keptn pre- and post-deployment tasks defined in the manifests. This enhances the Flux pre and post-deployment jobs setup with added observability out of the box.
Set up continuous delivery for the application
First, we need to create a Flux
GitRepository
resource
pointing to a repository where the application manifests are present.
In this case, it will be our podtato-head
repository.
To create this resource, we use Flux CLI:
flux create source git podtato-head \
--url=<git-repo-url> \
--branch=main \
--interval=1m \
--export > ./clusters/dev/podtato-head-source.yaml
This results in output similar to:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: app
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
url: <git-repo-url>
In the last step, create a Flux
Kustomization
resource to deploy the podtato-head
application to the cluster.
You can create it using the Flux CLI:
flux create kustomization podtato-head \
--target-namespace=podtato-kubectl \
--source=podtato-head \
--path="./apps/dev" \
--prune=true \
--wait=true \
--interval=30m \
--retry-interval=2m \
--health-check-timeout=3m \
--export > ./clusters/dev/podtato-head-kustomization.yaml
which results in output similar to:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: app
namespace: flux-system
spec:
interval: 30m0s
path: ./apps/dev
prune: true
retryInterval: 2m0s
sourceRef:
kind: GitRepository
name: app
namespace: flux-system
targetNamespace: podtato-kubectl
timeout: 3m0s
wait: true
Now, commit and push the resources you created in the previous steps. After pushing them, Flux picks up the configuration and deploys your application into the cluster.
Watch Flux sync of the application
You can watch the synchronization of the application using the Flux CLI:
$ flux get kustomizations --watch
NAME REVISION SUSPENDED READY MESSAGE
flux-system main@sha1:4e9c917f False True Applied revision: main@sha1:4e9c917f
podtato-head main@sha1:44154333 False True Applied revision: main@sha1:44154333
or using kubectl
:
$ kubectl get keptnappversion -n podtato-head
NAME APPNAME VERSION PHASE
podtato-head-v0.1.0-6b86b273 podtato-head v0.1.0 Completed
Each time you update the application, the changes are synced to the cluster.
Possible follow-ups
You can also set up multi-stage delivery with Flux,
following the steps described for ArgoCD
in the
ArgoCD multi-stage delivery with Keptn
user guide.