Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support proxy protocol #73

Closed
thetechnick opened this issue Nov 17, 2016 · 2 comments
Closed

Support proxy protocol #73

thetechnick opened this issue Nov 17, 2016 · 2 comments
Milestone

Comments

@thetechnick
Copy link
Contributor

thetechnick commented Nov 17, 2016

If the nginx ingress controller is scheduled using mechanisms like nodePort, the client ip address is not preserved, because the kube-proxy is setting up NAT to connect the backend pods to the host network.

The client ip address is needed in several use cases:

  • Enforcing rate limits
  • Detecting the country of the user
  • ...

Until kubernetes/enhancements#27 is completed, there are only a few workarounds to preserve the client ip address.

  1. Directly binding to the host network
    Using hostNetwork: true in combination with a daemon-set nginx can bind directly to the host network, so there is no NAT.
    In this deployment scenario it is necessary to deploy a external TCP loadbalancer with a alive checking mechanism to enable high availability, if a host goes down unexpected.

  2. Enable proxy protocol so a external TCP LB can forward the requests without loosing the client ip.
    A major advantage of this approach is, that the nginx ingress deployment can be scaled independently of the host systems.

To enable the proxy protocol feature i would suggest to add a new entry in the nginx configmap:

data:
  proxy-protocol: 'True'

This entry will reconfigure the generated nginx configs like described in the official blog post:
https://www.nginx.com/resources/admin-guide/proxy-protocol/

I am not sure nginx is able to mix server entries with and without proxy-protocol in the listen directive. But because this is more of a global deployment choice, I do not see the need to support to annotations for the ingress object.

@pleshakov
Copy link
Contributor

@thetechnick

NGINX must know the address or CIDR of the proxy for the https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from directive. We can configure it via a separate config map entry:

data:
  proxy-protocol: 'True'
  proxy-protocol-from: '192.168.0.1/24'

In the NGINX configuration file, we must do the following:

listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
...
set_real_ip_from 192.168.0.1/24;
real_ip_header   proxy_protocol;
...

This way, the client IP address is accessible via $remote_addr variable.

I am not sure nginx is able to mix server entries with and without proxy-protocol in the listen directive. But because this is more of a global deployment choice, I do not see the need to support to annotations for the ingress object.

Agree, makes sense to make it global.

@thetechnick
Copy link
Contributor Author

@pleshakov
I think we should stick to the nginx directive names for the configmap option names:

data:
  proxy-protocol: 'True'
  set-real-ip-from: 192.168.0.1/24,192.168.12.1/24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants