How to retrieve remote IP in EMK load-balancers
Estimated time to read: 3 minutes
In this tutorial you will learn how to set up a Nginx ingress controller to forward the remote address to a backend service
Preconditions:
- Fuga Cloud Account
- Kubectl installed on your machine
- Helm installed on your machine
- kubeconfig to access your EMK cluster
Here's a short explanation on what you are going to learn in this tutorial:
- Setup Nginx ingress controller
- Deploy backend service
- Test backend response
Step 1 Setup install Nginx ingress controller
Create a file named values.yaml
with the following contents:
---
controller:
config:
compute-full-forwarded-for: "true"
use-forwarded-headers: "true"
use-proxy-protocol: "true"
service:
annotations:
loadbalancer.openstack.org/proxy-protocol: "true"
This file will instruct Helm to set up the Nginx ingress controller to pass on the remote IP address as an HTTP header to backend services from the load-balancer using the Proxy Protocol.
Install the Nginx ingress controller using a Helm chart:
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--values values.yaml
This will create a new load-balancer with a Floating IP in your EMK cluster:
kubectl -n ingress-nginx get service ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 100.68.92.142 81.24.7.20 80:31841/TCP,443:30058/TCP 33m
In this example, any backend service will be available on external IP 81.24.7.20.
Step 2 Deploy backend service
To validate the availability of the remote IP address, deploy an echo server which can respond with a copy of the request including additional headers set by the Nginx ingress controller.
Create a file echoserver.yaml
with the following contents:
---
apiVersion: v1
kind: Namespace
metadata:
name: echoserver
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echoserver
namespace: echoserver
spec:
replicas: 2
selector:
matchLabels:
app: echoserver
template:
metadata:
labels:
app: echoserver
spec:
containers:
- image: ealen/echo-server:latest
imagePullPolicy: IfNotPresent
name: echoserver
ports:
- containerPort: 80
env:
- name: PORT
value: "80"
---
apiVersion: v1
kind: Service
metadata:
name: echoserver
namespace: echoserver
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
selector:
app: echoserver
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echoserver
namespace: echoserver
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: echoserver.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echoserver
port:
number: 80
Deploy the echo server backend containing a Deployment, Service and Ingress:
In a production setup you would create proper DNS records in order to resolve the backend service. Instead, instruct your HTTP client to resolve the hostname echoserver.local
to the external IP address of the previously created load-balancer.
Step 3 Test backend response
Query the echo server backend service using the HTTP client curl with additional resolving information:
curl -s --resolve echoserver.local:80:81.24.7.20 http://echoserver.local | python3 -m json.tool
{
"request": {
"headers": {
"host": "echoserver.local",
"x-real-ip": "x.x.x.x"
}
}
}
The returned JSON object should return the key x-real-ip
, equivalent of the HTTP header X-Real-Ip
, containing the remote address of the client.
With this setup, your web application should be able to retrieve the remote IP address by parsing the HTTP header X-Real-Ip
in the HTTP request.