docker-archive / dockercloud-haproxy

HAproxy image that autoreconfigures itself when used in Docker Cloud
https://cloud.docker.com/
651 stars 187 forks source link

Proxy for TCP services in swarm mode (docker 1.13) #179

Closed shuston closed 7 years ago

shuston commented 7 years ago

I'm having trouble getting this to work - it may be my understanding of how to set it up.

What I want to have is:

The behavior I see is that the TCP connection into port 16000 is accepted, then the remote client sends the first protocol bytes and the connection is reset/closed. Nothing ever happens on port 8000.

I set this up in a docker stack compose and have tweaked the service settings since, but what I have is:

services:
  my-lb:
    image: dockercloud/haproxy:latest
    ports:
      - 16000:16000
    networks:
      - my-net
    deploy:
      placement:
        constraints: [node.role == manager]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  # (There are 4 of these, only one shown)
  my-service1:
    image: repo:5000/my-service1:1.0-1
    networks:
      - my-other-other-net
      - my-other-net
      - my-net
    deploy:
      placement:
        constraints: [node.role == worker]
    environment:
      - SERVICE_PORTS="8000"
      - TCP_PORTS="8000"
tifayuki commented 7 years ago

@shuston

When you specify TCP_PORTS="8000", haproxy actually listens to port 8000, not 16000. As a result, in my-lib you need publish port 8000 to 16000

Change ports in my-lb to 16000:8000 and try if it works

shuston commented 7 years ago

Thanks for your quick reply; however, that doesn't work either. When I try to access port 16000 the connection is reset as soon as the client sends data to my-service1.

I can access port 8000 directly, bypassing haproxy, but I'd like haproxy to handle it if possible. I'd also like to not have to expose port 8000 to the host level.

tifayuki commented 7 years ago

I use dockercloud/hello-world image that exposes port 80 for testing, didn't see any error. See the logs:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

$ docker service ls
ID  NAME  MODE  REPLICAS  IMAGE

$ cat docker-compose.yml
version: "3.0"
services:
        my-lb:
            image: dockercloud/haproxy:latest
            ports:
                - 16000:80
            networks:
                - app1
            deploy:
                placement:
                    constraints: [node.role == manager]
            volumes:
                - /var/run/docker.sock:/var/run/docker.sock

        my-service1:
            image: dockercloud/hello-world
            networks:
                - app1
            environment:
                - SERVICE_PORTS="80"
                - TCP_PORTS="80"
networks:
        app1:
              external: true

$ docker stack deploy --compose-file docker-compose.yml haproxy
Creating service haproxy_my-lb
Creating service haproxy_my-service1

$ curl localhost:16000
<html>
<head>
    <title>Hello world!</title>
    <link href='//fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
    <style>
    body {
        background-color: white;
        text-align: center;
        padding: 50px;
        font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
    }

    #logo {
        margin-bottom: 40px;
    }
    </style>
</head>
<body>
    <img id="logo" src="logo.png" />
    <h1>Hello world!</h1>
    <h3>My hostname is d95e5960b6d6</h3>    </body>
</html>

$ docker service ls
ID            NAME                 MODE        REPLICAS  IMAGE
de2oju6239xq  haproxy_my-lb        replicated  1/1       dockercloud/haproxy:latest
zm33sc12va99  haproxy_my-service1  replicated  1/1       dockercloud/hello-world:latest
shuston commented 7 years ago

Thank you! I tore down my whole environment and built it back again with what I learned here. It is working now - I must have got something tangled up in my experimentation. All is well now. Thank you for your help!