Dynamic DNS Resolution with HAProxy and Docker - docker

I'm trying to setup HAProxy inside a Docker host.
Using HAProxy 1.7 and Docker 1.12
My haproxy.cfg looks like:
# Simple configuration for an HTTP proxy listening on port 81 on all
# interfaces and forwarding requests to a single backend "servers" with a
# single server "server1" listening on 127.0.0.1:8000
global
daemon
maxconn 256
resolvers docker
# nameserver dnsmasq 127.0.0.1:53
nameserver dns 127.0.0.1:53
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
default-server init-addr none
frontend http-in
bind *:80
default_backend www_somedomain1_com
# Define hosts
acl host_www_somedomain1_com hdr(host) -i somedomain1.com
acl host_www_somedomain1_com hdr(host) -i www.somedomain1.com
acl host_www_somedomain2_com hdr(host) -i www.somedomain2.com
## figure out which one to use
use_backend www_somedomain1_com if host_www_somedomain1_com
use_backend www_somedomain2_com if host_www_somedomain2_com
backend www_somedomain1_com
# Utilizing the Docker DNS to resolve below host
# server server1 www-somedomain1-com maxconn 32 check port 80
server server1 www-somedomain1-com resolvers docker check maxconn 32
backend www_somedomain2_com
# Utilizing the Docker DNS to resolve below host
# server server1 www-somedomain2-com maxconn 32 check resolvers docker resolve-prefer ipv4
server server1 www-somedomain2-com maxconn 32 check port 80
I want to use Docker's embedded DNS system - which, in my understanding, is only enabled when using a user defined network.
So I create a network (using the default bridge driver)
docker network create mynetwork
When I run my two named docker containers, (my-haproxy and www-somedomain1-com) I add them to that network with the --net flag.
Docker run commands:
docker run --name myhaproxy --net mynetwork -p 80:80 -d haproxy
docker run --name www-somedomain1-com --net mynetwork -d nginx
I know the Docker dns is functional because I can resolve from one container to the other when I hop on them in a bash shell. I can't get the right combo/config in HAProxy to enable the dynamic DNS resolution.
HAProxy stats page always shows the downstream backends as brown/resolution issue....
Some things that have helped:
- the "default-server init-addr none" helps pass the haproxy config check on startup.
Any guidance is greatly appreciated!

I think your issue is that you are using 127.0.0.1:53 for your resolver dns, when it needs to be 127.0.0.11:53 for the docker bridge network.
Here is my haproxy setup for dev docker stuff:
global
quiet
defaults
log global
mode http
option forwardfor
timeout connect 60s
timeout client 60s
timeout server 60s
default-server init-addr none
resolvers docker_resolver
nameserver dns 127.0.0.11:53
frontend https-proxy
bind 0.0.0.0:80
bind 0.0.0.0:443 ssl crt /usr/local/etc/haproxy/dev_server.pem
redirect scheme https if !{ ssl_fc }
acl is_api_server hdr(host) -i mywebsite
use_backend api_server if is_api_server
backend api_server
server haproxyapi api-server-dev:80 check inter 10s resolvers docker_resolver resolve-prefer ipv4

Related

HAProxy config for TCP load balancing in docker container

I'm trying to put a HAProxy loadbalancer in front of my RabbitMQ cluster(which is setup with nodes in separate docker containers). I cannot find many examples for haproxy config for the above setup,
global
debug
defaults
log global
mode tcp
timeout connect 5000
timeout client 50000
timeout server 50000
frontend main
bind *:8089
default_backend app
backend app
balance roundrobin
mode http
server rabbit-1 172.18.0.2:8084
server rabbit-2 172.18.0.3:8085
server rabbit-3 172.18.0.4:8086
In this example, what should I give in the place of the ip addresses for docker containers?

Connection refused: when uwsgi and nginx in different containers

I am trying to setup two docker containers(yes separate without docker-compose): one with nginx and one with uwsgi with basic flask app.
I run containers in same network within docker
My nginx config for site added/linked to sites-enabled(everything else is default):
server {
listen 80;
server_name 127.0.0.1;
location / {
include uwsgi_params;
uwsgi_pass 0.0.0.0:8080;
}
}
My uwsgi.ini
[uwsgi]
module = app:app
master = true
processes = 2
socket = 0.0.0.0:8080
uwsgi entry point in docker looks like
.local/bin/uwsgi --ini uwsgi.ini
Containers run fine on their own - uwsgi receives request on 8080 and nginx receives expected requests. How ever when I try to access 127.0.0.1 i get 502 status code and nginx logs error:
1 connect() failed (111: Connection refused) while connecting to
upstream, client: 192.168.4.1, server: 127.0.0.1, request: "GET /
HTTP/1.1", upstream: "uwsgi://0.0.0.0:8080", host: "127.0.0.1"
By googling i find solution that rather use one container and some_socket.sock as file or use docker compose. Apparently problem with permissions, but I do not know how to solve them or diagnose.
I launch containers with these commands:
docker run --network app_network --name nginx --rm -p 80:80 my_nginx
docker run --network app_network --name flaskapp --rm -p 8080:8080 my_uwsgi
EDIT
You can simply use the hostname of the docker container in the uwsgi_pass directive as both docker containers are on the same subnet.
location / {
include uwsgi_params;
uwsgi_pass flaskapp:8080;
}
0.0.0.0 isn't the IP address of the server, it essentially tells the server to be hosted on every IP that the device has allocated.
To connect to it from nginx, you will need to use the IP address of the container instead.
You can find the IP address of the container running uWsgi with the following command:
docker inspect CONTAINER_ID
Where CONTAINER_ID is the ID of the container you started uwsgi in.
From here you can update the nginx config as follows:
uwsgi_pass IP_ADDRESS:8080;
Where IP_ADDRESS is the one you found from the command above
You can also set the ip address of the container when you start it with the following option
--ip <ip>
Be careful, however, to ensure that the IP address you set is in the same subnet as the standard IP's assigned.

How Install SSL Certificate on ha proxy dockerfile using letsencrypt

I am using haproxy to route the domains and subdomains and it is deployed on port 80. I want that all the domains should be https or using SSL certificate.
global
log xx.xx.90.28 local0
log xx.xx.90.28 local1 notice
maxconn 2048
defaults
log global
mode http
option httplog
option dontlognull
option redispatch
option forwardfor
option http-server-close
retries 3
timeout connect 5000
timeout client 10000
timeout server 10000
frontend balancer
bind *:80
mode http
stats enable
stats uri /stats
stats refresh 15s
stats show-node
stats auth admin:admin
acl domain hdr_dom(host) -i www.example.com
acl subdomain hdr_dom(host) -i app.example.com
acl subdomain1 hdr_dom(host) -i examplecom
use_backend go_app_1 if domain
use_backend go_app_2 if subdomain
use_backend go_app_3 if subdomain1
backend go_app_1
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8081 check
backend go_app_2
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8082 check
backend go_app_3
balance roundrobin
mode http
option forwardfor
server go xx.xx.90.28:8081 check
And here is the DockerFile
FROM haproxy:2.1
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
Now I want to use letsencrypt to secure these URL please guide me how I can do this?
I think we need to setup letsencrypt locally first.
And inject the result setting to the container via volume mount.
Example command from Docker Hub:
docker run -d --name my-running-haproxy -v /path/to/etc/haproxy:/usr/local/etc/haproxy:ro haproxy:1.7
Something like below:
-v /my/letsencrypt/setting/:/etc/ssl/

Docker Nginx-Proxy Container used for Port 80 Forwarding to other container based on Domain

I am trying to set up a Docker Nginx Proxy server to forward incoming requests to their corresponding Docker Container on 192.168.1.120 or to the Router's Web-Admin at 192.168.1.1
So right now I am in a bit of a pickle, but I need to set this up regardless. I have this setup right now
Router 192.168.1.1 (Web Admin + Port Forwarding)
Server1 LAMP - (Router Forwards -> port 80 for LAMP Server)
Server2 Docker - (Router Forwards -> 20 SSH, 8080, 9000 Docker Admin)
So I have to configure the port forwarding through my Router's web interface, which is accessible on port 8080. But the issue is that right now I moved to Florida, and I had stupidly added a port-forwarding rule on 8080 to forward to Shipyard Docker Manager, which I eventually planned to install an Nginx-Proxy Forwarding Docker container. I never got the forwarding Docker container working, and I eventually switched to Portainer on port 9000 which I had to configure because it was the only other port I had already set forwarded before I lost access to my Router's web interface, and thus lost the ability to forward ports.
The downside is that I cannot access my Router's web interface. The upside is that - I still have to implement an Nginx-Proxy port forwarding Container anyways, to set up dynamic port 80 forwarding to different Docker containers based on the URL.
So I want to mvoe my LAMP server on as a new Docker Container, and then I will also have a few other Rails Docker containers - but I need to configure a Docker Container to forward the app to differnt servers based on the port. I assume I need to have 2 dockers running - one for port 80 forwarding, and then one for port 8080 forwarding - this is not a problem.
I have not been able to correctly configure my Nginx config to forwarding an incoming request from my domain-name that I have point to my server (my.domain.com below), needs to get forwarded to my router 192.168.1.1. Any help / suggestions on how to configure my Nginx-Proxy Docker Container to forward this correctly, or what I should setup here to forward incoming requests to a web-server dynamically based on the URL. I can install any Docker containers I need for this.
My current Config /etc/nginx/nginx.conf, running on a Nginx-Proxy Docker Container on port 8080 (Google to find the Docker Image for nginx-proxy)
# My Nginx Config to forward my.domain.com
http {
resolver 127.0.0.1;
access_log /var/logs/nginx/access.log;
server {
listen 8080;
server_name my.domain.com;
return 301 http://192.168.1.1:8080/$request_uri;
}
}
I get these errors:
[error] 55#55: *2274 datacenter.URL.com could not be resolved (110: Operation timed out), client: 166.172.189.185, server: datacenter.URL.com, request: "GET / HTTP/1.1", host: "datacenter.URL.com:8080"
[error] 55#55: recv() failed (111: Connection refused) while resolving, resolver: 192.168.1.1:8080
EDIT: I just noticed that I can only have one Docker Container running at-a-time for each port. So I need to figure out how to forward requests to different servers's + ports based on the Domain Name. So each URL forwarding rule entry needs to be able to go to different servers all running on all different ports.

Port exposed by Docker not reachable

I ran a docker container that exposes port 443. docker ps confirms that it is exposed.
~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
42b17c2a4b75 tmp/tmp "/usr/bin/tini -- /bi" 57 seconds ago Up 55 seconds 443/tcp adoring_austin
However, netstat doesn't show this port. I cannot reach it from a browser either.
~ netstat -lt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:ssh *:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
The command that I used the run the container is just JupyterHub.
[I 2016-11-22 03:12:11.494 JupyterHub app:643] Writing cookie_secret to /jupyterhub_cookie_secret
[W 2016-11-22 03:12:12.562 JupyterHub app:304]
Generating CONFIGPROXY_AUTH_TOKEN. Restarting the Hub will require restarting the proxy.
Set CONFIGPROXY_AUTH_TOKEN env or JupyterHub.proxy_auth_token config to avoid this message.
[W 2016-11-22 03:12:12.655 JupyterHub app:757] No admin users, admin interface will be unavailable.
[W 2016-11-22 03:12:12.655 JupyterHub app:758] Add any administrative users to `c.Authenticator.admin_users` in config.
[I 2016-11-22 03:12:12.655 JupyterHub app:785] Not using whitelist. Any authenticated user will be allowed.
[I 2016-11-22 03:12:12.671 JupyterHub app:1231] Hub API listening on http://172.17.0.3:8081/hub/
[I 2016-11-22 03:12:12.676 JupyterHub app:968] Starting proxy # http://*:443/
03:12:12.861 - info: [ConfigProxy] Proxying https://*:443 to http://172.17.0.3:8081
03:12:12.864 - info: [ConfigProxy] Proxy API at http://127.0.0.1:444/api/routes
[I 2016-11-22 03:12:12.883 JupyterHub app:1254] JupyterHub is now running at http://127.0.0.1:443/
What am I doing wrong here?
By default, this Jupyterhub Docker image just exposes the port 8000. You can read here. To use SSL (port 443), you might do some extra steps.
You can check it on port 8000.
Stop and remove your containers
docker stop jupyterhub
docker rm jupyterhub
Start the jupyterhub with the mapped ports:
docker run -d --name jupyterhub -p 443:443 -p 8000:8000 jupyterhub/jupyterhub jupyterhub
Check it at http://YOUR_DOCKER_IP:8000/, port 443 is not available.
docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
0a123216ee9f jupyterhub/jupyterhub "jupyterhub" 26 seconds ago
Up 3 seconds 0.0.0.0:443->443/tcp, 0.0.0.0:8000->8000/tcp jupyterhub

Resources