The GitOps Toolkit Kustomize reconciler
Go to file
Stefan Prodan 37d84d749e
Merge pull request #47 from fluxcd/requeue-dependency
Configurable dependency requeuing
2020-06-22 17:20:28 +03:00
.github Update source-controller to v0.0.1-alpha.6 2020-05-06 11:45:43 +03:00
api/v1alpha1 Generate API documentation 2020-06-19 17:00:10 +02:00
config Update source-controller to v0.0.1-beta.2 2020-06-10 11:29:08 +03:00
controllers Configurable dependency requeuing 2020-06-20 10:30:37 +03:00
docs Generate API documentation 2020-06-19 17:00:10 +02:00
hack Generate API documentation 2020-06-19 17:00:10 +02:00
internal Add Go license to forked package 2020-06-10 13:06:51 +03:00
.gitignore Init controller with kubebuilder 2020-04-15 09:58:33 +03:00
CHANGELOG.md Release v0.0.1-beta.2 2020-06-10 11:02:04 +03:00
CODE_OF_CONDUCT.md Release v0.0.1-alpha.1 2020-04-20 15:11:11 +03:00
CONTRIBUTING.md Release v0.0.1-alpha.1 2020-04-20 15:11:11 +03:00
DCO Release v0.0.1-alpha.1 2020-04-20 15:11:11 +03:00
Dockerfile Update Alpine to 3.12 2020-06-10 11:01:53 +03:00
LICENSE Initial commit 2020-04-15 08:57:39 +03:00
MAINTAINERS Add Hidde to MAINTAINERS 2020-06-19 17:02:01 +02:00
Makefile Generate API documentation 2020-06-19 17:00:10 +02:00
PROJECT Introduce profiles 2020-04-21 14:01:51 +03:00
README.md Update install instructions 2020-05-09 12:17:14 +03:00
go.mod Update source-controller to v0.0.1-beta.2 2020-06-10 11:29:08 +03:00
go.sum Update source-controller to v0.0.1-beta.2 2020-06-10 11:29:08 +03:00
main.go Configurable dependency requeuing 2020-06-20 10:30:37 +03:00

README.md

kustomize-controller

e2e report license release

The kustomize-controller is a Kubernetes operator, specialized in running continuous delivery pipelines for infrastructure and workloads defined with Kubernetes manifests and assembled with Kustomize.

overview

Features:

  • watches for Kustomization objects
  • fetches artifacts produced by source-controller from Source objects
  • watches Source objects for revision changes
  • generates the kustomization.yaml file if needed
  • generates Kubernetes manifests with kustomize build
  • validates the build output with client-side or APIServer dry-run
  • applies the generated manifests on the cluster
  • prunes the Kubernetes objects removed from source
  • checks the health of the deployed workloads
  • runs Kustomizations in a specific order, taking into account the depends-on relationship
  • reports on Slack or Discord whenever a Kustomization status changes

Specifications:

Usage

The kustomize-controller is part of a composable GitOps toolkit and depends on source-controller to acquire the Kubernetes manifests from Git repositories.

Install the controllers

Install the source and kustomize controllers in the kustomize-system namespace:

kustomize build https://github.com/fluxcd/kustomize-controller//config/default?ref=master \
kubectl apply -f-

Define a Git repository source

Create a source object that points to a Git repository containing Kubernetes and Kustomize manifests:

apiVersion: source.fluxcd.io/v1alpha1
kind: GitRepository
metadata:
  name: podinfo
  namespace: kustomize-system
spec:
  interval: 1m
  url: https://github.com/stefanprodan/podinfo
  ref:
    branch: master

For private repositories, SSH or token based authentication can be configured with Kubernetes secrets.

Save the above file and apply it on the cluster. You can wait for the source controller to assemble an artifact from the head of the repo master branch with:

kubectl wait gitrepository/podinfo --for=condition=ready

The source controller will check for new commits in the master branch every minute. You can force a git sync with:

kubectl annotate --overwrite gitrepository/podinfo source.fluxcd.io/syncAt="$(date +%s)"

Define a kustomization

Create a kustomization object that uses the git repository defined above:

apiVersion: kustomize.fluxcd.io/v1alpha1
kind: Kustomization
metadata:
  name: podinfo-dev
  namespace: kustomize-system
spec:
  interval: 5m
  path: "./deploy/overlays/dev/"
  prune: true
  sourceRef:
    kind: GitRepository
    name: podinfo
  validation: client
  healthChecks:
    - kind: Deployment
      name: frontend
      namespace: dev
    - kind: Deployment
      name: backend
      namespace: dev
  timeout: 80s

Note that if your repository contains only plain Kubernetes manifests, the controller will automatically generate a kustomization.yaml file inside the specified path.

A detailed explanation of the Kustomization object and its fields can be found in the specification doc.

Based on the above definition, the kustomize-controller fetches the Git repository content from source-controller, generates Kubernetes manifests by running kustomize build inside ./deploy/overlays/dev/, and validates them with a dry-run apply. If the manifests pass validation, the controller will apply them on the cluster and starts the health assessment of the deployed workload. If the health checks are passing, the Kustomization object status transitions to a ready state.

workflow

You can wait for the kustomize controller to complete the deployment with:

kubectl -n kustomize-system wait kustomization/podinfo-dev --for=condition=ready

When the controller finishes the reconciliation, it will log the applied objects:

kubectl -n kustomize-system logs deploy/kustomize-controller | jq .
{
  "level": "info",
  "ts": 1587195448.071468,
  "logger": "controllers.Kustomization",
  "msg": "Kustomization applied in 1.436096591s",
  "kustomization": "kustomize-system/podinfo-dev",
  "output": {
    "namespace/dev": "created",
    "service/frontend": "created",
    "deployment.apps/frontend": "created",
    "horizontalpodautoscaler.autoscaling/frontend": "created",
    "service/backend": "created",
    "deployment.apps/backend": "created",
    "horizontalpodautoscaler.autoscaling/backend": "created"
  }
}

You can trigger a kustomize build and apply any time with:

kubectl -n kustomize-system annotate --overwrite kustomization/podinfo-dev \
kustomize.fluxcd.io/syncAt="$(date +%s)"

When the source controller pulls a new Git revision, the kustomize controller will detect that the source revision changed, and will apply those changes right away.

If the kustomization build or apply fails, the controller sets the ready condition to false and logs the error:

status:
  conditions:
  - lastTransitionTime: "2020-04-16T07:27:58Z"
    message: 'apply failed'
    reason: ApplyFailed
    status: "False"
    type: Ready
{
  "kustomization": "kustomize-system/podinfo-dev",
  "error": "Error from server (NotFound): error when creating podinfo-dev.yaml: namespaces dev not found"
}

Control the execution order

When running a kustomization, you may need to make sure other kustomizations have been successfully applied beforehand. A kustomization can specify a list of dependencies with spec.dependsOn. When combined with health assessment, a kustomization will run after all its dependencies health checks are passing.

For example, a service mesh proxy injector should be running before deploying applications inside the mesh:

apiVersion: kustomize.fluxcd.io/v1alpha1
kind: Kustomization
metadata:
  name: istio
  namespace: kustomize-system
spec:
  interval: 10m
  path: "./istio/system/"
  sourceRef:
    kind: GitRepository
    name: istio
  healthChecks:
    - kind: Deployment
      name: istiod
      namespace: istio-system
  timeout: 2m
---
apiVersion: kustomize.fluxcd.io/v1alpha1
kind: Kustomization
metadata:
  name: podinfo-dev
  namespace: kustomize-system
spec:
  dependsOn:
    - istio
  interval: 5m
  path: "./overlays/dev/"
  prune: true
  sourceRef:
    kind: GitRepository
    name: podinfo

Deploy releases to production

For production deployments, instead of synchronizing with a branch you can use a semver range to target stable releases:

apiVersion: source.fluxcd.io/v1alpha1
kind: GitRepository
metadata:
  name: podinfo-releases
  namespace: kustomize-system
spec:
  interval: 5m
  url: https://github.com/stefanprodan/podinfo
  ref:
    semver: ">=3.2.3 <4.0.0"

With ref.semver we configure source controller to pull the Git tags and create an artifact from the most recent tag that matches the semver range.

Create a production kustomization and reference the git source that follows the latest semver release:

apiVersion: kustomize.fluxcd.io/v1alpha1
kind: Kustomization
metadata:
  name: podinfo-production
  namespace: kustomize-system
spec:
  interval: 10m
  path: "./deploy/overlays/production/"
  sourceRef:
    kind: GitRepository
    name: podinfo-releases

Based on the above definition, the kustomize controller will apply the kustomization that matches the semver range set in the Git repository.

Configure alerting

The kustomize controller can post message to Slack or Discord whenever a kustomization status changes.

Alerting can be configured by creating a profile that targets a list of kustomizations:

apiVersion: kustomize.fluxcd.io/v1alpha1
kind: Profile
metadata:
  name: default
  namespace: kustomize-system
spec:
  alert:
    type: slack
    verbosity: info
    address: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
    username: kustomize-controller
    channel: general
  kustomizations:
    - '*'

The alert provider type can be: slack or discord and the verbosity can be set to info or error.

The * wildcard tells the controller to use this profile for all kustomizations that are present in the same namespace as the profile. Multiple profiles can be used to send alerts to different channels or Slack organizations.

When the verbosity is set to error, the controller will alert on any error encountered during the reconciliation process. This includes kustomize build and validation errors, apply errors and health check failures.

error alert

When the verbosity is set to info, the controller will alert if:

  • a Kubernetes object was created, updated or deleted
  • heath checks are passing
  • a dependency is delaying the execution
  • an error occurs

info alert