Ha Proxy Simple Forwarding with Docker

HA Proxy simple forwarding with Docker

I went down the route of adding it to its own docker network as per Miq suggestion. However this was not enough on its own so I also simplified the ha config.

Below is what it looks like now

global
quiet

defaults
mode http
maxconn 5000

timeout connect 5s
timeout client 20s
timeout server 20s

frontend public
bind *:81
default_backend apps

backend apps
server myapp-backend myapp-backend:80 check

bash

docker network create elk || true
docker run --name myapp-backend -p 8088:80 -d --net=elk nginx:1.15.0-alpine
docker run --name rob-haproxy -p 81:81 --net=dev-d rob-haproxy-image

HaProxy forward proxy works on HTTP but gives 503 on HTTPS

After a full day of debugging, it looks like simply specifying port 80 did the trick, although I would have expected the default port to be 80 perhaps it carries through a default port of 443? I could also get rid of the port 80 after check after this change which was the original trigger hint that something might be off there.

backend certbot
option httpchk GET /
default-server init-addr libc,none
server certbot_server certbot:80 check

backend client
option httpchk HEAD /
server client_server client:80 check

backend api
option httpchk OPTIONS /api/healthcheck
server api_server api:80 check

How to properly configure HAProxy in Docker Swarm to automatically route traffic to replicated services (via SSL)?

Well, first of all and regarding SSL (since it's the first thing that you mention) you need to configure it using the certificate and listen on the port 443, not port 80.

With that modification, your Proxy configuration would already change to:

global
daemon
maxconn 256

defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

frontend http-in
bind *:80
default_backend servers

frontend https-in
bind *:443 ssl crt /etc/ssl/certs/hackaton2021.pem
default_backend servers

That would be a really simplified configuration for allowing SSL connection.


Now, let's go for the access to the different services.

First of all, you cannot access to the service on localhost, actually you shouldn't even expose the ports of the services you have to the host. The reason? That you already have those applications in the same network than the haproxy, so the ideal would be to take advantage of the Docker DNS to access directly to them

In order to do this, first we need to be able to resolve the service names. For that you need to add the following section to your configuration:

resolvers docker
nameserver dns1 127.0.0.11:53
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 10s
hold refused 10s
hold nx 10s
hold timeout 10s
hold valid 10s
hold obsolete 10s

The Docker Swarm DNS service is always available at 127.0.0.11.

Now to your previous existent configuration, we would have to add the server but using the service-name discovery:

backend servers
balance roundrobin
server-template node- 2 node-server:8080 check resolvers docker init-addr libc,none

If you check what we are doing, we are creating a server for each one of the discovered containers in the Swarm within the node-server service (so the replicas) and we will create those adding the prefix node- to each one of them.

Basically, that would be the equivalent to get the actual IPs of each of the replicas and add them stacked as a basic server configuration.


For deployment, you also have some errors, since we aren't interested into actually expose the node-server ports to the host, but to create the two replicas and use HAProxy for the networking.

For that, we should use the following Docker Compose:

version: '3.9'

services:
proxy:
image: haproxy
ports:
- 80:80
- 443:443
volumes:
- hackaton2021.pem:/etc/ssl/certs/hackaton2021.pem
- haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
deploy:
placement:
constraints: [node.role == manager]

node-server:
image: glusk/hackathon-2021:latest
command: npm run server
deploy:
mode: replicated
replicas: 2

Remember to copy your haproxy.cfg and the self-signed (or real) certificate for your application to the instance before deploying the Stack.

Also, when you create that stack it will automatically create a network with the name <STACK_NAME>-default, so you don't need to define a network just for connecting both services.

Configuring haproxy load balancer in front of ha artifactory cluster

The reqirep keyword was spitted in several http-request directives.

You will need to use http-request replace-path.

My suggestion, untested

# reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker-virtual/v22
http-request replace-path /v2(.*$) /artifactory/api/docker/docker-virtual/v22\1

The appsession isn't anymore part of haproxy as the ALERT message shows.

My suggestion for the cookie sticky, untested.

backend normal
mode http
balance roundrobin
# this makes no sense option httpchk OPTIONS /
option httpchk GET /api/system/ping HTTP/1.1\r\nHost:haproxy\r\n
option forwardfor
option http-server-close

stick-table type string len 52 size 2m expire 3h

#appsession JSESSIONID len 52 timeout 3h
stick on cookie(JSESSIONID)

server platform-artifactory-ha-01 172.17.1.71:80 check fall 3 inter 3s rise 2
server platform-artifactory-ha-02 172.17.1.122:80 check fall 3 inter 3s rise 2


Related Topics



Leave a reply



Submit