Mastering Multi‑Instance NGINX‑Ingress: Deployment, Configuration, and Best Practices
This guide explains how NGINX‑Ingress works, outlines key considerations for running multiple instances, and provides step‑by‑step instructions—including helm installation, custom controller parameters, admission webhook scoping, and verification screenshots—to reliably deploy and manage several NGINX‑Ingress controllers in a Kubernetes cluster.
1. How NGINX‑Ingress Works
In an NGINX‑Ingress pod there are two core components: the nginx‑ingress‑controller and NGINX itself. The controller watches the Kubernetes API server for changes to Ingress, Service, Endpoint, and ConfigMap resources, generates NGINX configuration, and reloads the NGINX process to provide external routing.
When the controller runs, it list‑watches the API server for relevant resources.
If a user creates an Ingress and the controller’s webhook is enabled, the API server calls the controller’s 8443 port to validate the Ingress before storing it in etcd.
The controller detects the new Ingress, fetches the associated Service, Endpoint, and ConfigMap (e.g., certificates), and rewrites nginx.conf.
When a request reaches NGINX on port 80 or 443, NGINX processes it; if the rule matches, a Lua script queries the API server to obtain the backend pod IP.
Key considerations for deploying multiple NGINX‑Ingress instances
How to uniquely identify each NGINX‑Ingress instance?
When several controllers watch Ingress resources, which one should handle a given Ingress?
If some instances have webhook enabled, which controller’s webhook will the API server invoke for validation?
2. Installation Tips for Multiple NGINX‑Ingress Controllers
2.1 Different --controller-class for each instance
Example startup parameters for two instances (nginx‑ingress‑a and nginx‑ingress‑b) are shown in the images below.
2.2 Specify the associated controller with spec.ingressClassName
For Kubernetes versions ≤1.23 the API version is networking.k8s.io/v1beta1:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-a
namespace: nginx-a
annotations:
kubernetes.io/ingress.class: custom-nginx-a
spec:
rules:
- http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITHSTARTS_WITHFor Kubernetes ≥1.23 the API version changes to networking.k8s.io/v1 and the class is set via ingressClassName:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-a
namespace: nginx-a
spec:
ingressClassName: custom-nginx-a
rules:
- http:
paths:
- backend:
service:
name: nginx
port:
number: 80
path: /
pathType: ImplementationSpecific
property:
ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH2.3 Scope admission webhooks to a single controller
By default, admission webhooks are global; with multiple controllers they can block all Ingress writes if one controller fails. Use namespaceSelector to limit each webhook to a specific namespace.
admissionwebhook:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values: ["${namespace}"]
rules:
- operations: ["CREATE","UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["ingresses"]
scope: "*"
objectSelector: {}For clusters ≥1.28 you can also use matchConditions to filter by ingressClassName.
3. Deploying Multiple NGINX‑Ingress Controllers
Download the Helm chart:
wget https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.3.0/ingress-nginx-4.3.0.tgzCreate a custom myvalue.yaml with unique fields for each controller (controller name, ingressClass, service annotations, resources, admission webhook settings, etc.). Example excerpt:
imagePullSecrets: {}
controller:
name: controller
image:
repository: swr.cn-north-4.myhuaweicloud.com/hwofficial/nginx-ingress
tag: "v1.2.1"
ingressClass: custom-nginx
ingressClassResource:
name: custom-nginx
controllerValue: k8s.io/custom-nginx
service:
annotations:
kubernetes.io/elb.id: 3660aa3c-xxxx-xxxx-xxxx-xxxxff97xxxx
resources:
requests:
cpu: 200m
memory: 200Mi
extraVolumeMounts:
- name: localtime
mountPath: /etc/localtime
readOnly: true
extraVolumes:
- name: localtime
hostPath:
path: /etc/localtime
admissionWebhooks:
enabled: true
failurePolicy: Fail
port: 8443
certificate: "/usr/local/certificates/cert"
key: "/usr/local/certificates/key"
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values: ["${namespace}"]
rules:
- operations: ["CREATE","UPDATE"]
apiGroups: ["*"]
apiVersions: ["*"]
resources: ["ingresses"]
scope: "*"
networkPolicyEnabled: false
service:
servicePort: 443
type: ClusterIP
createSecretJob:
resources:
limits:
cpu: 20m
memory: 40Mi
requests:
cpu: 10m
memory: 20Mi
patch:
enabled: true
image:
registry: registry.k8s.io
image: ingress-nginx/kube-webhook-certgen
tag: v1.1.1
pullPolicy: IfNotPresent
nodeSelector:
kubernetes.io/os: linux
securityContext:
runAsNonRoot: true
runAsUser: 2000
fsGroup: 2000
defaultBackend:
enabled: falseDeploy the controller to a specific namespace:
helm install ingress-nginx-controller -f myvalue.yaml ./ingress-nginx -a -n ${namespace}Repeat the above steps for each additional controller.
Result Showcase
Verify controller pods are running, view IngressClass resources, and check the ELB address. Then create test workloads, Services, and Ingress resources to confirm traffic routing.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
