APISIX Ingress Controller, a Kubernetes operator that programs an API gateway
APISIX Ingress Controller for Kubernetes
At a glance
- What is it?
- The APISIX Ingress Controller lets you run the APISIX Gateway as a Kubernetes Ingress, and it dynamically configures and manages that gateway from Gateway API resources. It is a Go controller built on controller-runtime, it ships a distroless container image, it produces a single install.yaml for distribution, and it has a substantial end-to-end test harness built on kind and terratest.
- Who is it for?
- Adopt the APISIX Ingress Controller if you run Kubernetes and want the gateway's routing configuration to be derived from Gateway API resources rather than maintained by hand, and skip it if you are on the official kubernetes ingress-nginx, since this is a controller for a specific gateway.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the controller actually does
The description in the project documentation is precise: the APISIX Ingress Controller allows you to run the APISIX Gateway as a Kubernetes Ingress to handle inbound traffic for a Kubernetes cluster, and it dynamically configures and manages the APISIX Gateway using Gateway API resources. The mechanism is the standard Kubernetes operator pattern, and the choice of Gateway API as the input rather than the older Ingress API is the interesting part. Gateway API is a role-oriented model where a Gateway, a Route and a listener carry the meaning, and it is a better fit for an API gateway than a path-and-service rule set. The repository structure reflects the same shape, with an api/ directory for the custom resource definitions, an internal/ directory for the controller logic, a cmd/ directory for the binary, a config/ directory, a pkg/ directory, a Dockerfile at the root and a test/ directory holding the end-to-end suite.
The APISIX Ingress Controller allows you to run the APISIX Gateway as a
Kubernetes Ingress to handle inbound traffic for a Kubernetes cluster. It
dynamically configures and manages the APISIX Gateway using Gateway API
resources.The deploy path is four make targets
The getting started section gives a sequence that reads like a contract between the operator and the cluster. You build and push your image to the location specified by the IMG variable with make build-image, and the note says this image ought to be published in the personal registry you specified and that it is required to have access to pull the image from the working environment, with a reminder to check registry permissions if the command does not work. You install the custom resource definitions and the Gateway API into the cluster with make install. You deploy the manager to the cluster with the image specified by IMG using make deploy, which takes the image reference as an argument, as in the example with a development tag. And the reverse is also documented, with make uninstall to delete the custom resource definitions and make undeploy to remove the controller. The RBAC warning sits next to the deploy step: if you encounter RBAC errors, you may need to grant yourself cluster-admin privileges or be logged in as admin.
make build-image
make install
make deploy #IMG=apache/apisix-ingress-controller:devOne YAML file for distribution, built with Kustomize
The project distribution section is a separate workflow from the developer one, and it is the part a platform team would actually use. You build the installer for the image you have published with make build-installer, passing the same IMG argument, and the note explains what comes out: the target generates an install.yaml file in the dist directory, containing all the resources built with Kustomize, which are necessary to install this project without its dependencies. Users then just run kubectl apply with the YAML bundle. That is a deliberate design choice. Rather than asking every user to run a helm chart, a kustomize overlay and a set of prerequisites, the project produces one self-contained file, and the separate install step for the CRDs and Gateway API is what the word without its dependencies refers to.
make build-installer # IMG=apache/apisix-ingress-controller:dev
kubectl apply -f dist/install.yamlA distroless image and an architecture-specific binary
The Dockerfile is short and follows the pattern you would expect from a Kubernetes operator. The base is a distroless cc-debian12 image, with the tag taken from a build argument so a nonroot variant can be selected. The build context is not the source tree but a prepared binary, since the image copies an architecture-specific executable named for the target architecture into the working directory, and the entrypoint runs that binary with a configuration file path as the default command. The distroless choice is a security decision rather than a size one: there is no shell and no package manager in the image, so a compromised process has nothing to escalate with, and the runtime user is baked into the base image. The Go module records a much newer Go version than the getting started guide mentions, and the Kubernetes client libraries and controller-runtime are pinned to matching versions, which is the sort of alignment that stops a dependency upgrade from breaking the build.
ARG BASE_IMAGE_TAG=nonroot
FROM gcr.io/distroless/cc-debian12:${BASE_IMAGE_TAG}
ARG TARGETARCH
WORKDIR /app
COPY ./bin/apisix-ingress-controller_${TARGETARCH} ./apisix-ingress-controller
ENTRYPOINT ["/app/apisix-ingress-controller"]
CMD ["-c", "/app/conf/config.yaml"]The test harness is the interesting part of the repository
The Makefile reveals how seriously the end-to-end story is taken, and the numbers are specific. The end-to-end suite runs under a kind cluster named apisix-ingress-cluster with four nodes, using a cloud provider kind binary at version 0.6.0, with the provider's pid file written to a temporary path. The test timeout is 80 minutes, which tells you how long a real end-to-end run takes. The suite uses terratest at version 0.50.0, which is a framework for testing infrastructure as code against real cloud providers, and ginkgo with gomega for the test structure, along with httpexpect for HTTP assertions and a websocket client. There is also envtest, with a pinned Kubernetes version for the kubebuilder assets, and a separate adc version. The unit test path uses ginkgo as well, and a Makefile variable selects the test directory. A project that runs a real cluster with four nodes in its end-to-end tests is making a different claim from one that mocks the API server.
ENVTEST_K8S_VERSION = 1.30.0
KIND_NAME ?= apisix-ingress-cluster
TEST_TIMEOUT ?= 80m
E2E_NODES ?= 4The dependencies, and what they tell you about the design
The module file is a good map of the architecture. The Kubernetes side is a set of matching libraries at 0.36.1, covering the api, apiextensions-apiserver for the custom resource definitions, apimachinery, apiserver, client-go, kubectl and streaming, with controller-runtime at 0.24.1 as the controller framework. The Gateway API libraries are at 1.6.0, including the conformance suite, which is a detail worth noting, because it means the project runs the upstream Gateway API conformance tests rather than only its own. Prometheus client_golang is there for metrics, zap with zapr for logging, cobra for the command line, and mergo and sprig for configuration merging and templating. Two entries reveal functional areas that the summary does not mention: the eclipse paho mqtt golang client, and hashicorp go-memdb, an in-memory database, alongside gopkg from api7, the APISIX organisation's own packaging library. The presence of a gateway configuration layer beyond the Kubernetes libraries is what makes this a controller for APISIX rather than a generic ingress controller.
sigs.k8s.io/controller-runtime v0.24.1
sigs.k8s.io/gateway-api v1.6.0
sigs.k8s.io/gateway-api/conformance v1.6.0
k8s.io/api v0.36.1Where it fits, and what to check before you deploy it
The controller is a well-built piece of infrastructure with a clear scope, and the honest caveats are about versions and permissions rather than about design. The first check is your cluster version. The getting started guide lists Kubernetes 1.31 or newer as the prerequisite, while the end-to-end harness is pinned to an envtest Kubernetes version of 1.30.0, so the tested surface and the documented surface are not quite the same, and a reader on 1.30 should find out what the project supports there before assuming. The second is the image architecture, since the container copies a binary named for the target architecture and the build argument has to match your nodes. The third is the RBAC story, because the documentation's own advice for permission errors is to grant cluster-admin, which is a sign that the default service account permissions are the thing to review carefully. The release history shows active work, with 2.2.0 in August 2026, 2.1.0 in June and 2.0.1 in January, and the last push on 2026-10-13.
Editorial conclusion
Adopt the APISIX Ingress Controller if you run Kubernetes and want the gateway's routing configuration to be derived from Gateway API resources rather than maintained by hand, and skip it if you are on the official kubernetes ingress-nginx, since this is a controller for a specific gateway. Verify three things before you deploy it: that your cluster version is within the supported range, since the getting started guide asks for Kubernetes 1.31 or newer while the test harness runs against an older version; that the image you deploy matches the architecture your nodes run, since the Dockerfile copies an architecture-specific binary; and that you read the RBAC note, because the documentation warns that permission errors during install may require cluster-admin privileges.
Frequently asked questions
What does the APISIX Ingress Controller do?
It allows you to run the APISIX Gateway as a Kubernetes Ingress to handle inbound traffic for a cluster, dynamically configuring and managing that gateway using Gateway API resources.
How do I deploy the APISIX Ingress Controller?
Build and push your image with `make build-image`, install the custom resource definitions and the Gateway API with `make install`, then deploy the manager with `make deploy` and an IMG argument pointing at your image. The reverse is `make undeploy` and `make uninstall`.
How is the APISIX Ingress Controller distributed to users?
The makefile target build-installer generates an install.yaml file in the dist directory, containing all the resources built with Kustomize that are needed to install the project without its dependencies. Users then run `kubectl apply -f dist/install.yaml`.
What container image does the APISIX Ingress Controller use?
A distroless cc-debian12 base image, with the tag selected by a build argument so a nonroot variant can be used. The image copies an architecture-specific controller binary into the working directory and runs it with a config.yaml path, so there is no shell or package manager in the runtime image.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/apache-apisix-ingress-controller)Was this useful?