Kubernetes GitOps with FluxCD - Part 7 - Resource Optimization and Automated Version Management with Github Actions
Table of Contents
In our previous post, we set up push based reconciliation using webhooks. Building on what we’ve learned so far—basic FluxCD setup, SOPS-based secret management, image update automation, Helm chart automation, alerts and push based reconciliation — this article focuses on critical day-two operational concerns: optimizing FluxCD resource allocation and establishing automated version management through Github Actions.
1. Sizing FluxCD Containers
By default, FluxCD components are provisioned with the following resource configurations for CPU and memory:
kubectl -n flux-system get pods -o json | jq -r '["container", "cpu_requests", "cpu_limits", "memory_requests", "memory_limits"], (.items[].spec.containers[] | [.image, .resources.requests.cpu, .resources.limits.cpu, .resources.requests.memory, .resources.limits.memory]) | @csv' | column -t -s,
"container" "cpu_requests" "cpu_limits" "memory_requests" "memory_limits"
"ghcr.io/fluxcd/helm-controller:v1.2.0" "100m" "1" "64Mi" "1Gi"
"ghcr.io/fluxcd/image-automation-controller:v0.40.0" "100m" "1" "64Mi" "1Gi"
"ghcr.io/fluxcd/image-reflector-controller:v0.34.0" "100m" "1" "64Mi" "1Gi"
"ghcr.io/fluxcd/kustomize-controller:v1.5.0" "100m" "1" "64Mi" "1Gi"
"ghcr.io/fluxcd/notification-controller:v1.5.0" "100m" "1" "64Mi" "1Gi"
"ghcr.io/fluxcd/source-controller:v1.5.0" "50m" "1" "64Mi" "1Gi"
For our environment with a smaller cluster footprint, these default limits are unnecessarily generous and could lead to resource contention. We’ll refine these allocations by modifying cluster/default/flux-system/kustomization.yaml
to better align with our actual resource capacity and workload requirements:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
- webhook-receiver.yaml
- ingress.yaml
patches:
- patch: |-
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
decryption:
provider: sops
secretRef:
name: sops-gpg
+ - patch: |
+ - op: add
+ path: /spec/template/spec/nodeSelector
+ - op: replace
+ path: /spec/template/spec/containers/0/resources/limits/cpu
+ value: "100m"
+ - op: replace
+ path: /spec/template/spec/containers/0/resources/limits/memory
+ value: "128Mi"
+ target:
+ kind: Deployment
After committing these changes, we can verify the resource adjustments have been properly applied:
kubectl -n flux-system get pods -o json | jq -r '["container", "cpu_requests", "cpu_limits", "memory_requests", "memory_limits"], (.items[].spec.containers[] | [.image, .resources.requests.cpu, .resources.limits.cpu, .resources.requests.memory, .resources.limits.memory]) | @csv' | column -t -s,
"container" "cpu_requests" "cpu_limits" "memory_requests" "memory_limits"
"ghcr.io/fluxcd/helm-controller:v1.2.0" "100m" "100m" "64Mi" "128Mi"
"ghcr.io/fluxcd/image-automation-controller:v0.40.0" "100m" "100m" "64Mi" "128Mi"
"ghcr.io/fluxcd/image-reflector-controller:v0.34.0" "100m" "100m" "64Mi" "128Mi"
"ghcr.io/fluxcd/kustomize-controller:v1.5.0" "100m" "100m" "64Mi" "128Mi"
"ghcr.io/fluxcd/notification-controller:v1.5.0" "100m" "100m" "64Mi" "128Mi"
"ghcr.io/fluxcd/source-controller:v1.5.0" "50m" "100m" "64Mi" "128Mi"
The output confirms our resource constraints have been successfully applied to all FluxCD components, optimizing our cluster’s resource utilization while maintaining operational integrity.
2. Flux Version Updates with Github Actions
Maintaining current versions of infrastructure components is a critical operational responsibility. We can leverage Github Actions to automate the monitoring and updating of FluxCD components by implementing a workflow that periodically checks for new releases and creates pull requests when updates are available.
Let’s establish this automation by creating .github/workflows/update-flux.yaml
name: update-flux
on:
workflow_dispatch:
schedule:
- cron: "0 0 1 * *"
permissions:
contents: write
pull-requests: write
jobs:
components:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Setup Flux CLI
uses: fluxcd/flux2/action@main
- name: Check for updates
id: update
run: |
flux install \
--components="source-controller,kustomize-controller,helm-controller,notification-controller" \
--components-extra="image-reflector-controller,image-automation-controller" \
--export > ./cluster/default/flux-system/gotk-components.yaml
VERSION="$(flux -v)"
echo "flux_version=$VERSION" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
branch: update-flux
commit-message: Update to ${{ steps.update.outputs.flux_version }}
title: Update to ${{ steps.update.outputs.flux_version }}
body: |
${{ steps.update.outputs.flux_version }}
This workflow will execute either on-demand through manual triggering or automatically on the first day of each month. When new versions of FluxCD components are detected, it generates a pull request with the updated manifests, facilitating a controlled review and deployment process.
--components
and --components-extra
flags precisely match those used during your initial FluxCD installation as documented in Kubernetes GitOps with FluxCD - Part 1 - Initial Setup.
After pushing these changes to our repository, we can verify the workflow’s effectiveness by manually triggering it:
As demonstrated in the screenshot, the workflow has successfully detected and proposed an update to FluxCD version 2.5.1
, creating a pull request that can be reviewed and merged through our standard governance process.
References
- Official FluxCD Documentation - https://fluxcd.io/flux/flux-gh-action/
- Kubernetes Documentation - https://kubernetes.io/docs/