Enabling PROXY Protocol between Vultr Load Balancer and NGINX Ingress Controller to preserve client connection information
PROXY Protocol preserves a client’s connection information (such as IP address) when traffic passes through a PROXY. When a Vultr Load Balancer sits in front of an NGINX Ingress Controller, enabling PROXY protocol ensures the controller sees the client’s original IP and protocol, which is necessary for accurate logging, rate-limiting, and any IP-dependent application logic.
To enable the PROXY protocol in Vultr Kubernetes Engine, follow these steps:
Identify the ConfigMap used by your NGINX Ingress Controller. If deployed via Helm, you can list ConfigMaps in all namespaces to locate it:
$ kubectl get configmaps -A | grep ingress-nginx
Edit the ConfigMap to enable PROXY protocol and forwarded headers:
$ kubectl edit configmap -n <namespace> <configmap-name>
Update the Ingress Controller’s ConfigMap to include use-PROXY-protocol: 'true', use-forwarded-headers: 'true', and compute-full-forwarded-for: 'true' under the data section so that NGINX correctly interprets the PROXY protocol headers.
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/component: controller
name: <configmap-name>
namespace: <namespace>
data:
use-PROXY-protocol: 'true'
use-forwarded-headers: 'true'
compute-full-forwarded-for: 'true'
ssl-redirect: 'false'
Next, edit the Service of type LoadBalancer that exposes the NGINX Ingress Controller. Use the namespace and service-name where your controller is deployed:
$ kubectl edit service -n <namespace> <service-name>
In the Service manifest, add the annotation service.beta.kubernetes.io/vultr-loadbalancer-PROXY-protocol: 'true' and set externalTrafficPolicy: Local to ensure the client IP is preserved.
apiVersion: v1
kind: Service
metadata:
name: <service-name>
namespace: <namespace>
annotations:
service.beta.kubernetes.io/vultr-loadbalancer-PROXY-protocol: 'true'
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- name: http
protocol: TCP
appProtocol: http
port: 80
targetPort: 80
- name: https
protocol: TCP
appProtocol: https
port: 443
targetPort: 443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
If you are editing live resources with kubectl edit, changes take effect immediately. If you are modifying local manifest files, apply them with:
$ kubectl apply -f <manifest.yaml>
After applying, the Ingress Controller will see the original client IP and protocol, allowing applications to handle traffic based on the real client connection.
DNS01 challenge to avoid conflicts with PROXY protocol handling.