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.

Important
Ensure that the --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