Skip to content
This repository has been archived by the owner on Jan 23, 2020. It is now read-only.

Ability to obtain client IP address on container HTTP requests #7

Closed
rocketraman opened this issue Feb 2, 2017 · 4 comments
Closed

Comments

@rocketraman
Copy link

When deploying containers into Docker for Azure, it appears like there is no way to obtain the original client IP address for HTTP requests. The container sees only the internal Docker network address e.g. 10.0.x.x.

Normally, this would be handled via X-Forwarded-For headers, but by the time the request reaches an haproxy container, the source IP is already obscured.

Is there a solution?

@ddebroy
Copy link

ddebroy commented Feb 2, 2017

@rocketraman The behavior you are observing is due to moby/moby#25526

You can try the temporary workaround of specifying mode=host as mentioned in that issue and documented here: https://github.com/docker/docker.github.io/blob/2248f78dabc2b0e5092fd550ad0aa3c15d41e2b0/engine/swarm/services.md#publish-a-services-ports-directly-on-the-swarm-node

@ddebroy
Copy link

ddebroy commented Feb 2, 2017

Closing since this a duplicate of moby/moby#25526

@ddebroy ddebroy closed this as completed Feb 2, 2017
@rocketraman
Copy link
Author

rocketraman commented Feb 24, 2017

You can try the temporary workaround of specifying mode=host as mentioned in that issue and documented here:

@ddebroy I tried this workaround. It seems that publishing the port with mode=host does not integrate with the automatic updates to the Azure load balancer. So this is fairly unusable as things stand now.

In addition, the externalLoadBalancer backend pool only goes to the worker nodes, but if something like dockercloud/haproxy is published to the worker nodes, it doesn't have access to the manager nodes' docker.sock. One should be able to use DOCKER_HOST env with dockercloud/haproxy but I couldn't get that to work either: it just insists that the host is not resolved, or if using a manager IP directly, that access was denied.

@djeeg
Copy link

djeeg commented Dec 18, 2017

Thanks for the hints, I have managed to get this working (leaving my setup below to help someone else)

Im using Traefik for proxy/acme

  • You basically have two choices where to run traefik, either run it on manager nodes or run it on worker nodes
  • Running on managers is easier as there is direct access to the docker.sock, though there are questions around scalability
  • Running on workers is harder, as you need to proxy the docker.sock, or wait for the possible introspecition PR, however this setup will apparently scale better Docker swarm mode, Traefik on manager node only ? traefik/traefik#766
  • For the moment I have chosen to run it on the manager nodes only
  • Gets more complicated with Lets Encrypt in the mix https://docs.traefik.io/user-guide/cluster/

Then you need to configure the service to by-pass the ingress mesh, using host mode ports

  traefikedge:
    image: traefik:1.4.3-alpine
    ports:
      - target: 80
        published: 80 #for redirect to HTTPS
        protocol: tcp
        mode: host #to bypass ingress mesh, to preserve client ip
      - target: 443
        published: 443
        protocol: tcp
        mode: host  #to bypass ingress mesh, to preserve client ip
    networks:
      - netfront
    deploy:
      mode: global
      placement:
        constraints:
          - node.role == manager

Then I manually added port 80+443 to the azure load balancer that points at the manager nodes

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

No branches or pull requests

3 participants