Kubernetes for https://github.com/fluxcd/flux2-kustomize-helm-example/
Motivation: The Foundation
This repository aims to provide a robust, scalable, and efficient way to manage multi-cluster Kubernetes deployments using Flux and Kustomize. The core goal is to leverage these tools to automate the deployment, testing, and upgrades of applications across different environments, while minimizing redundancy and maximizing consistency.
Workflows:
- The
test
workflow within the GitHub CI ensures the validity of Kubernetes manifests and Kustomize overlays through kubeconform. - The
e2e
workflow sets up a Kubernetes cluster using Kind and tests the staging setup by running Flux within the CI environment.
Cluster Management:
Adding a New Cluster:
- Clone the Repository:
git clone https://github.com/${GITHUB_USER}/${GITHUB_REPO}.git && cd ${GITHUB_REPO}
- Create a Cluster Directory:
mkdir -p clusters/dev
- Copy Staging Manifests:
cp clusters/staging/infrastructure.yaml clusters/dev
- Copy Staging Manifests:
cp clusters/staging/apps.yaml clusters/dev
- Create a Custom Overlay: Create a ‘dev’ overlay within the
apps
directory and adjust thespec.path
inclusters/dev/apps.yaml
to point to the overlay, e.g.,path: ./apps/dev
. - Push Changes:
git add -A && git commit -m "add dev cluster" && git push
- Set Kubectl Context: Configure your kubectl context for the dev cluster.
- Bootstrap Flux:
flux bootstrap github --context=dev
- Clone the Repository:
Production Deployment:
- Configure Let’s Encrypt: Within the
clusters/production/infrastructure.yaml
file, update the Let’s Encrypt server value to point to the production API, e.g.:
apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-configs namespace: flux-system spec: # ...omitted for brevity dependsOn: - name: infra-controllers patches: - patch: | - op: replace path: /spec/acme/server value: https://acme-v02.api.letsencrypt.org/directory target: kind: ClusterIssuer name: letsencrypt
- Dependency Management: The
dependsOn
property ininfrastructure.yaml
ensures that Flux installs or upgrades the controllers before the configs. This ensures CRDs are registered on the cluster before Flux applies any custom resources.
- Configure Let’s Encrypt: Within the
Prerequisites:
- Kubernetes Cluster: Requires a Kubernetes cluster version 1.28 or newer. You can use Kubernetes Kind for local testing.
- GitHub Account: A GitHub account is required for managing the Git repository.
- GitHub Personal Access Token: Requires a personal access token with
repo
permissions for creating repositories. - Flux CLI: Install the Flux CLI using Homebrew on macOS or Linux:
brew install fluxcd/tap/flux
or by downloading precompiled binaries:curl -s https://fluxcd.io/install.sh | sudo bash
Repository Structure:
├── apps
│ ├── base
│ ├── production
│ └── staging
├── infrastructure
│ ├── configs
│ └── controllers
└── clusters
├── production
└── staging
- apps: Contains Helm releases with cluster-specific configurations.
- infrastructure: Contains common infrastructure tools like ingress-nginx and cert-manager.
- clusters: Contains the Flux configuration for each cluster.
Application Management:
Helm Repository: Defines the Helm repository for cert-manager in
infrastructure/controllers/cert-manager.yaml
:apiVersion: source.toolkit.fluxcd.io/v1 kind: HelmRepository metadata: name: cert-manager namespace: cert-manager spec: interval: 12h url: https://charts.jetstack.io
interval: 12h
: Flux pulls the Helm repository index every 12 hours to check for updates.version: "1.x"
: Defines the semver range for the Helm chart.
Let’s Encrypt Issuer: Creates a Let’s Encrypt issuer within the
infrastructure/configs/
directory:apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt spec: acme: # Replace the email address with your own contact email email: server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-nginx solvers: - http01: ingress: class: nginx
Helm Release: Defines the Helm release for cert-manager in
infrastructure/controllers/cert-manager.yaml
:apiVersion: helm.toolkit.fluxcd.io/v2 kind: HelmRelease metadata: name: cert-manager namespace: cert-manager spec: interval: 30m chart: spec: chart: cert-manager version: "1.x" sourceRef: kind: HelmRepository name: cert-manager
interval: 30m
: Flux checks the Helm chart for updates every 30 minutes.
Podinfo Demo App: The demo app utilizes a Helm release for deployment. You can verify its deployment and access it using the following steps:
- Helm Release Definition: The
apps/base/podinfo/release.yaml
file contains the Helm release configuration for Podinfo. - Verification: Check the release status using the
flux get helmreleases
command. - Access via Ingress: Use
kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8080:80 &
and access the app athttp://localhost:8080
.
- Helm Release Definition: The
Cluster Synchronization:
Deploying to a New Cluster:
- Bootstrap:
flux bootstrap github --context=production-clone --owner=${GITHUB_USER} --repository=${GITHUB_REPO} --branch=main --personal --path=clusters/production-clone
- Pull Changes:
git pull origin main
- Create Kustomization:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - flux-system - ../production/infrastructure.yaml - ../production/apps.yaml
- Reconcile:
flux reconcile kustomization flux-system --context=production-clone --with-source
- Bootstrap:
Production Cluster:
- Bootstrap:
flux bootstrap github --context=production --owner=${GITHUB_USER} --repository=${GITHUB_REPO} --branch=main --personal --path=clusters/production
- Watch Reconciliation:
flux get kustomizations --watch
- Bootstrap:
Infrastructure Organization:
- infrastructure/controllers: Contains namespaces and Helm release definitions for Kubernetes controllers.
- infrastructure/configs: Contains Kubernetes custom resources, such as cert issuers and network policies.
- HelmRelease Definitions:
infrastructure/controllers/cert-manager.yaml
andinfrastructure/controllers/ingress-nginx.yaml
contain the Helm release definitions for various controllers.
Configuration:
flux-system Kustomization: The
clusters/production/flux-system/kustomization.yaml
andclusters/staging/flux-system/kustomization.yaml
files define the kustomization for theflux-system
namespace. These files include various patches for customizing the Flux components.Infrastructure Kustomizations:
- infrastructure/configs/kustomization.yaml: Defines the kustomization for the infrastructure configurations.
- infrastructure/controllers/kustomization.yaml: Defines the kustomization for the infrastructure controllers.
App Kustomizations:
- apps/staging/kustomization.yaml: Defines the kustomization for the staging environment.
- apps/production/kustomization.yaml: Defines the kustomization for the production environment.
- apps/base/podinfo/kustomization.yaml: Defines the kustomization for the Podinfo application.
Ingress-nginx Definition: The
infrastructure/controllers/ingress-nginx.yaml
file defines the deployment of ingress-nginx using a Helm release.Cluster-Specific Kustomizations: The
clusters/production/apps.yaml
andclusters/staging/apps.yaml
files define the kustomizations for theapps
namespace in each cluster. These files include dependencies on the infrastructure components.Production Infrastructure: The
clusters/production/infrastructure.yaml
file defines the kustomization for the infrastructure configurations. This file includes the Let’s Encrypt configuration.Staging Infrastructure: The
clusters/staging/infrastructure.yaml
file defines the kustomization for the infrastructure configurations. This file includes the staging Let’s Encrypt configuration.Podinfo Values: The
apps/staging/podinfo-values.yaml
andapps/production/podinfo-values.yaml
files define the values for the Podinfo Helm release in the respective environments.
Key Concepts:
- GitOps: This repository implements GitOps principles, where the infrastructure and application configurations are stored in Git and changes are propagated to the cluster through reconciliation.
- Flux: Flux is a GitOps operator that automatically deploys, updates, and manages Kubernetes applications based on the configurations in Git.
- Kustomize: Kustomize provides a mechanism to customize and apply configurations to multiple environments, reducing redundancy and promoting consistency.
- Helm: Helm is a package manager for Kubernetes, used to manage the deployment of applications in a structured and reproducible manner.
- Let’s Encrypt: Let’s Encrypt is used for obtaining and managing TLS certificates for the applications.
Top-Level Directory Explanations
apps/ - This directory contains the application definitions and configurations. It includes base, production, staging directories.
apps/base/ - This directory contains the base application configurations. It includes podinfo directory.
apps/production/ - This directory contains the production application configurations.
apps/staging/ - This directory contains the staging application configurations.
clusters/ - This directory contains the Kubernetes cluster configurations. It includes production and staging directories.
clusters/production/ - This directory contains the production Kubernetes cluster configurations. It includes flux-system directory.
clusters/staging/ - This directory contains the staging Kubernetes cluster configurations. It includes flux-system directory.
infrastructure/ - This directory contains the infrastructure configurations and scripts.
infrastructure/configs/ - This directory contains the configuration files for the infrastructure.
infrastructure/controllers/ - This directory contains the Kubernetes controllers for managing the infrastructure.
scripts/ - This directory contains the scripts used for automating tasks.