Manage with Flux
Flux is a GitOps toolkit composed of specialized Kubernetes controllers. Its source controllers retrieve versioned configuration and deployment artifacts, while other controllers reconcile those sources into the cluster. In this workflow, Flux Helm Controller manages APISIX or API7 Ingress Controller as a declarative Helm release defined in Git.
Flux Helm Controller performs Helm install and upgrade actions and stores the rendered release manifest. It can also remediate failed operations and correct configuration drift. Because it does not render the chart again for every comparison, the current webhook certificate-generation behavior is not expected to cause continuous drift. Keep the webhook enabled and verify a no-change reconciliation before using the workflow in production.
This guide creates the HelmRepository and HelmRelease, configures CRD lifecycle policies and remediation, and reconciles gateway and application resources. It also covers verification, upgrades, rollback, and troubleshooting.
Prerequisites
Before you begin, ensure that you have:
- The repository, resource ownership, CRD, and credential preparation described in Prepare for GitOps.
- A Flux installation and an authenticated
fluxCLI. - Flux access to the platform repository and permission to manage the destination namespace and required cluster-scoped resources.
The examples use aic as the destination namespace. If you use another namespace, replace aic throughout the manifests and commands.
The example values focus on GitOps ownership and reconciliation; they retain the chart defaults for replicas, resource requests, and pod scheduling. Before production, configure capacity for your workload, run multiple controller replicas, and spread them across failure domains. See AIC High Availability and test failover in the target cluster. The podDisruptionBudget.enabled option in the pinned charts does not render successfully; do not enable it without verifying that a later chart release contains the fix.
Create the Helm Source and Release
Create a HelmRepository and HelmRelease for the selected controller. The examples use the controller-owned CRD model.
Apply the CRD ownership decision from Prepare for GitOps when configuring the HelmRelease:
- If the HelmRelease owns the bundled CRDs, set
install.crdstoCreateandupgrade.crdstoCreateReplace. Helm leaves CRDs in the cluster when a release is uninstalled, but an upgrade can replace them. Review CRD changes separately before upgrading the release. - If the platform owns the CRDs, reconcile the required Gateway API and APISIX CRDs from a separate, pinned Flux Kustomization. Wait until they report an
Establishedcondition and set both HelmRelease CRD policies toSkip. If Flux also applies the HelmRelease through a Kustomization, configure that Kustomization to depend on the CRD Kustomization.
The manifests use the Flux v2 HelmRelease API and drift detection. Confirm that your Flux installation supports these fields before applying them.
On a shared or multi-tenant cluster, set spec.serviceAccountName on the HelmRelease to a platform-owned service account with only the required permissions. The service account must be able to manage the namespaced and cluster-scoped resources assigned to the release, including CRDs when the HelmRelease owns them. Flux otherwise performs Helm actions with the permissions granted to Helm Controller.
- APISIX
- API7
The APISIX Admin API Service and apisix-admin-key Secret must already exist in the destination namespace (aic in the example).
apiVersion: v1
kind: Namespace
metadata:
name: aic
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: apisix
namespace: aic
spec:
interval: 1h
url: https://apache.github.io/apisix-helm-chart
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: apisix-ingress-controller
namespace: aic
spec:
interval: 30m
releaseName: apisix-ingress-controller
chart:
spec:
chart: apisix-ingress-controller
version: "1.2.2"
sourceRef:
kind: HelmRepository
name: apisix
namespace: aic
interval: 12h
install:
crds: Create
remediation:
retries: 3
upgrade:
crds: CreateReplace
remediation:
retries: 3
driftDetection:
mode: enabled
values:
config:
provider:
type: apisix-standalone
gatewayProxy:
createDefault: true
provider:
type: ControlPlane
controlPlane:
service:
name: apisix-admin
port: 9180
auth:
type: AdminKey
adminKey:
valueFrom:
secretKeyRef:
name: apisix-admin-key
key: admin-key
Replace the controller name and leader-election ID with the values generated by API7 Dashboard when they differ.
apiVersion: v1
kind: Namespace
metadata:
name: aic
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: api7
namespace: aic
spec:
interval: 1h
url: https://charts.api7.ai
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: api7-ingress-controller
namespace: aic
spec:
interval: 30m
releaseName: api7-ingress-controller
chart:
spec:
chart: api7-ingress-controller
version: "0.1.25"
sourceRef:
kind: HelmRepository
name: api7
namespace: aic
interval: 12h
install:
crds: Create
remediation:
retries: 3
upgrade:
crds: CreateReplace
remediation:
retries: 3
driftDetection:
mode: enabled
values:
config:
controllerName: api7.ai/api7-ingress-controller
leaderElection:
id: api7-ingress-controller-leader
provider:
type: api7ee
For a Gateway API workflow, reconcile the non-sensitive GatewayProxy, GatewayClass, and Gateway generated by API7 Dashboard separately. Supply their credential Secret through your secret-management solution.
The examples retry a failed operation three times. Flux uninstalls a failed installation before retrying it and rolls back a failed upgrade before retrying it. Adjust the retry count to match your recovery policy, and keep it bounded so persistent configuration or permission errors require operator review.
Reconcile the Helm Release
Commit the manifest to the path reconciled by Flux, request reconciliation, and inspect the release:
flux reconcile source helm <repository-name> -n aic
flux reconcile helmrelease <release-name> -n aic --with-source
flux get helmreleases -n aic
The HelmRelease should report Ready=True. Run the reconciliation again without changing Git and confirm that the revision and webhook Secret remain unchanged.
Reconcile Gateway and Application Resources
The HelmRelease manages the controller release. Manage the shared Gateway resources and application routes with separate Flux Kustomization resources so that their ownership and lifecycles remain independent. Despite the resource name, each referenced directory can contain ordinary Kubernetes YAML without a kustomization.yaml file.
Store the product-specific GatewayProxy, GatewayClass, shared Gateway, application namespaces, and authorization labels in the platform-owned infrastructure/gateway-resources/ directory prepared earlier. For APISIX, omit the GatewayProxy from this directory when the controller chart creates the default object. For API7, use the non-sensitive resources generated by API7 Dashboard and retain their generated names and references.
Create a GitRepository for the platform repository and a Kustomization for the shared resources:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: platform-config
namespace: flux-system
spec:
interval: 1m
url: https://github.com/example/platform-config.git
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: platform-gateway-resources
namespace: flux-system
spec:
interval: 10m
path: ./clusters/production/infrastructure/gateway-resources
prune: true
wait: true
timeout: 3m
sourceRef:
kind: GitRepository
name: platform-config
Store each application's Deployment, Service, HTTPRoute, and policies with that application. You can use the manifests from Configuration Examples without creating overlays. Add another Kustomization for the application directory and make it depend on the shared resources:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: httpbin-production
namespace: flux-system
spec:
interval: 10m
path: ./clusters/production/applications/httpbin
prune: true
wait: true
timeout: 3m
targetNamespace: <application-namespace>
sourceRef:
kind: GitRepository
name: platform-config
dependsOn:
- name: platform-gateway-resources
Flux generates the build configuration when either directory contains plain manifests. Commit these resources to the Flux bootstrap path. The application namespace must be created by the platform Kustomization or another owner before the application Kustomization runs. On a shared or multi-tenant cluster, set spec.serviceAccountName on each Kustomization to an appropriately scoped service account.
The dependency waits for the platform Kustomization to report Ready=True, but GatewayProxy has no status in this version. Verify the actual gateway connection through the Gateway and HTTPRoute conditions and an end-to-end request.
Verify
Verify the controller deployment, CRDs, gateway connection, and end-to-end routing before promoting the release to another environment.
Confirm that the Deployment is available and the CRDs are established:
kubectl rollout status deployment \
-l app.kubernetes.io/instance=<release-name> \
-n aic \
--timeout=300s
kubectl get pods,services -n aic
kubectl get crd gatewayproxies.apisix.apache.org
kubectl wait --for=condition=Established \
crd/gatewayproxies.apisix.apache.org \
--timeout=60s
The controller pod should report both the controller and ADC containers as ready. Inspect the rendered controller configuration and expected GatewayProxy:
kubectl get configmap -n aic
kubectl get configmap <configmap-name> -n aic \
-o jsonpath='{.data.config\.yaml}{"\n"}'
kubectl get gatewayproxy -n aic
kubectl describe gatewayproxy <gatewayproxy-name> -n aic
GatewayProxy does not expose an acceptance status in this version. When the admission webhook is enabled, invalid objects can be rejected during creation. Verify runtime connectivity through the controller logs and the Accepted, Programmed, and ResolvedRefs conditions on related Gateway and HTTPRoute resources.
Complete Proxy Requests to a Service with the gateway and classes managed by Git. A successful request verifies the entire path from a Kubernetes route through the controller to the gateway.
Finally, reconcile once more and confirm that no resources change:
flux reconcile helmrelease <release-name> -n aic --with-source
flux get helmreleases -n aic
Upgrade and Roll Back
Manage upgrades and rollbacks through Git so that Flux remains the only reconciler for the Helm release.
To upgrade the controller:
- Review the controller and chart release notes, including CRD changes.
- Change the pinned chart version and required values in Git.
- Inspect the rendered diff before reconciliation.
- Reconcile one environment and repeat the deployment, route, and no-change verification.
- Promote the same Git change to the next environment.
Before rolling back, confirm that the installed CRDs are compatible with the older controller. Set upgrade.crds to Skip in the rollback change so Flux does not replace the installed schemas with the chart's older CRDs. If a separate, pinned platform Kustomization owns the CRDs, keep both install.crds and upgrade.crds set to Skip. Then revert the chart version and controller values in Git.
If upgrade.crds remains set to CreateReplace, reverting the chart can replace the installed CRDs with older schemas. Setting it to Skip as described above prevents Flux from processing the chart's CRDs during the rollback. Do not run helm rollback or helm upgrade against a Flux-managed release.
Troubleshoot
Use the following checks to diagnose common release and reconciliation failures:
| Symptom | Check | Resolution |
|---|---|---|
| HelmRelease reports a CRD ownership or upgrade failure | Inspect install.crds, upgrade.crds, and other controllers managing the same CRDs. | Select one CRD owner and use Skip everywhere else. |
| GatewayProxy creation is rejected or controller logs report connection errors | Confirm that its Secret, endpoint or Service, network access, and CRD exist before reconciliation. | Correct the Secret reference, connectivity, or dependency order, then reconcile again. |
| Controller resources return after manual deletion or editing | Check whether Flux drift detection is enabled. | Make the intended change in Git instead of editing the live object. |
| Release remediation repeatedly retries | Inspect the Helm Controller events and release history. | Correct the chart values or dependency, then reconcile the source and release again. |