Merge pull request #46 from byjg/4.3.1
Issue #36 - Fix Swarm Connection
This commit is contained in:
commit
7c5912f120
10 changed files with 198 additions and 44 deletions
|
|
@ -4,8 +4,12 @@
|
|||
|
||||
This method will use a docker standalone installation to discover the containers and configure the HAProxy.
|
||||
|
||||
The only requirement is that containers and EasyHAProxy must be in the same docker network.
|
||||
If not, EasyHAProxy will connect the container with the EasyHAProxy network.
|
||||
You cannot mix docker containers with swarm containers.
|
||||
|
||||
The only request is that containers and EasyHAProxy must be in the same docker network.
|
||||
If you don't add to your services the same network EasyHAProxy is connected to, EasyHAProxy will attach it network to your container.
|
||||
|
||||
Also, it is highly recommended you create a network external to EasyHAProxy.
|
||||
|
||||
e.g.:
|
||||
|
||||
|
|
@ -53,7 +57,6 @@ Please follow the [docker label configuration](container-labels.md) to see other
|
|||
|
||||
You can configure the behavior of the EasyHAProxy by setup specific environment variables. To get a list of the variables, please follow the [docker container environment](docker-environment.md)
|
||||
|
||||
|
||||
## Setup certificates with Letsencrypt
|
||||
|
||||
Follow [this link](letsencrypt.md)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ Once the container is running, EasyHAProxy will detect automatically and start t
|
|||
|
||||
You don't need to expose any port in your container.
|
||||
|
||||
Caveats:
|
||||
Notes:
|
||||
|
||||
- At this point, the implementation doesn't support all ingress properties or wildcard domains.
|
||||
- The ingress will publish the ports 80 and 443, plus 1936 if stats are enabled.
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@
|
|||
This method will use a docker swarm installation to discover the containers and configure the HAProxy.
|
||||
The advantage of this method is that you can discover containers in other nodes from the cluster.
|
||||
|
||||
The only requirement is that containers and EasyHAProxy must be in the same docker swarm network.
|
||||
If not, EasyHAProxy will connect the service with the EasyHAProxy service network.
|
||||
You cannot mix docker containers with swarm containers.
|
||||
|
||||
The only request is that containers and EasyHAProxy must be in the same docker swarm network.
|
||||
If you don't add to your services the same network EasyHAProxy is connected to, EasyHAProxy will attach it network to your container.
|
||||
|
||||
Also, it is highly recommended you create a network external to EasyHAProxy.
|
||||
|
||||
e.g.:
|
||||
|
||||
```bash
|
||||
docker network create -d overlay easyhaproxy
|
||||
docker network create -d overlay --attachable easyhaproxy
|
||||
```
|
||||
|
||||
And then deploy the EasyHAProxy stack:
|
||||
|
|
@ -79,8 +83,6 @@ networks:
|
|||
external: true
|
||||
```
|
||||
|
||||
Note: The services to be discovered **don't need** to be in the same network as EasyHAProxy is.
|
||||
|
||||
Once the container is running, EasyHAProxy will detect automatically and start to redirect all traffic from `example.org:80` to your container.
|
||||
|
||||
You don't need to expose any port in your container.
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
You can map the following volumes:
|
||||
|
||||
| Volume | Description |
|
||||
|------|------|
|
||||
|-----------------------------|----------------------------------------------------------------------------------------|
|
||||
| /etc/haproxy/static/ | The folder that will contain the [config.yml](static.md) file for static configuration |
|
||||
| /certs/haproxy/ | The folder that will contain the certificates (`PEM`) for the [SSL](ssl.md) |
|
||||
| /certs/letsencrypt/ | The folder that will contain the certificates (`PEM`) for the SSL. Use this volume to cache the [letsencrypt](letsencrypt.md) certificate and avoid re-issue certificates between restarts. |
|
||||
| /etc/haproxy/conf.d/ | The folder that will contain the [custom configuration](other.md) files. |
|
||||
| /etc/haproxy/errors-custom/ | The folder that will contain the [custom error](other.md) files. |
|
||||
| /etc/haproxy/errors-custom/ | The folder that will contain the [custom error](other.md) html files. |
|
||||
|
||||
----
|
||||
[Open source ByJG](http://opensource.byjg.com)
|
||||
82
examples/swarm/certs/host1.local.pem
Normal file
82
examples/swarm/certs/host1.local.pem
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIFDTCCAvWgAwIBAgIURi+w1ZVgeedTlNIAwqQBMJv6dXswDQYJKoZIhvcNAQEL
|
||||
BQAwFjEUMBIGA1UEAwwLaG9zdDEubG9jYWwwHhcNMjEwODEwMTg0OTA2WhcNMzEw
|
||||
ODA4MTg0OTA2WjAWMRQwEgYDVQQDDAtob3N0MS5sb2NhbDCCAiIwDQYJKoZIhvcN
|
||||
AQEBBQADggIPADCCAgoCggIBAMBDAhLAygJuaW6w6ffigzTAAGXpmEz0tIxn1k4Z
|
||||
x5wN5rpv/qu0QMYz+Av2u1eOKEKZeaFRVpT0r93dX7IvbEZHt25GPiBvlLGqhjKR
|
||||
PnSk/7U8XmsnttUAV7rVEK1UrdFw8/IwriQC+dhr0mnYfSDMkvBoMFpdhVNTrbAZ
|
||||
1TB6rQjE7Ar0Mt8my96XJmwrcjK2Tj+E2rgPIUz1e5cekFYIDSBatmw+3+vr+T5x
|
||||
FNFkJ2o30W5o8ZflCJJzrVaihqQics6ZKDgpf7iqXMFiwWIlhdQpGvx5Gf/KFTK9
|
||||
UaOnRZz/X+2CebAFaTHR3k/PYppWTgBBBuRvlpCw+wdnkmteC0SQRF91QWVr7ejo
|
||||
7KaOlGI5VtvMUsWvTeAZmpaymIaATETuOJaY0JU11OmLeD9DOj5E2SQ7qIX/pFcp
|
||||
xpzG5j4c+MlgvxP2VAkNTeAXCaYiPBQH5ZZg0HE2WnB1KhLRFlHd4iHQD2GJ5yN/
|
||||
6fCFBfZfKSeK8JauwxgWkra53OcDq/mKd+DA/dK+/ruG7tqwVgIa04HOplzM7LYR
|
||||
GB0Irs9+lr5/PJbQZmU073Mdn6cXAg3p+6wvwFlDkS5v13gBDYNHtF62bc551edF
|
||||
Z6kGzJ7wmGRo84aBP7MuRZeReLOrSS67a1wLdzZsMnP1TJ7x9Lfr9MKl2uDnQdnY
|
||||
ex8DAgMBAAGjUzBRMB0GA1UdDgQWBBSQ/mtZd6h8en9YQVH6HO1PlWWiqzAfBgNV
|
||||
HSMEGDAWgBSQ/mtZd6h8en9YQVH6HO1PlWWiqzAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||
CSqGSIb3DQEBCwUAA4ICAQChQYNuah3+mTpIBDYxGrjTJNuOTIMaWzMyi1tkf+L0
|
||||
sEGwpbmAO2mWWQYF7WVLsi98PULh3adjt2jiud9VlaaC6gnwn5Zo1+Pilo9sNLLW
|
||||
6ij0+rN4kwIm/pNqi+jDuu2cvAuHIwZWeh8bEe/5UCxo4ihmWFQN8eJ6TUKCphRC
|
||||
6Eor/SSZZBQHgPl0BchzHOkwu7R3LCndRqxjhAoVb9yQOV+ZsmTeJXulwNzJ1uLt
|
||||
T8OIgIiDpmBo7HSN2H0k3chx00AsjUyJ9mmAWPejFe/KXLRPcVZR17jhzgfIBEzs
|
||||
M5WtWFm1aHDjVv6M6iteVm61E9T+k/M11ru1e2YwsxTDvb6x04mcrNu9soqddBbr
|
||||
VfpluuoQ/hEAbXtFNPoTySpz0cwOwcHCowVOLmdKgvImszZiMyHHG8VGGmPh88n7
|
||||
wVxb0gV0P4RMrcMLdeTdn55YQr1CqBr34eB6ol6AsbTm3VzBHRVmFNksl1o5JB5t
|
||||
tXLgF/G8/rzJ/4m1PaVuxrB7DxUmIk8EPbSIVkvZvd7LBzKwQ6IfVaucewHfEajQ
|
||||
VIiexSMiFc7lw3KnxjOHZjf6FM9VYg3No++GdC99s7LkIuJwAMLNqTQ7Hvhn7YvP
|
||||
4FlSIgc6xj0YkGZEQlb5o/5nauEqQU0ABgw6jtI4NxrNLT6cp7CO4M0xIDEg/3YD
|
||||
aA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
YkU14WzQKleFkiBJI9lVvnfgGnOlgg0=
|
||||
-----END PRIVATE KEY-----
|
||||
40
examples/swarm/easyhaproxy.yml
Normal file
40
examples/swarm/easyhaproxy.yml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# To Install
|
||||
# docker network create --driver overlay --attachable easyhaproxy
|
||||
# docker stack deploy -c easyhaproxy.yml easyhaproxy
|
||||
|
||||
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
haproxy:
|
||||
image: byjg/easy-haproxy:4.3.1-rc2
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./certs:/certs/haproxy
|
||||
- certs_letsencrypt:/certs/letsencrypt
|
||||
deploy:
|
||||
replicas: 1
|
||||
environment:
|
||||
EASYHAPROXY_DISCOVER: swarm
|
||||
EASYHAPROXY_SSL_MODE: "loose"
|
||||
EASYHAPROXY_LETSENCRYPT_EMAIL: changeme@example.org
|
||||
HAPROXY_CUSTOMERRORS: "true"
|
||||
HAPROXY_USERNAME: admin
|
||||
HAPROXY_PASSWORD: password
|
||||
HAPROXY_STATS_PORT: 1936
|
||||
ports:
|
||||
- "80:80/tcp"
|
||||
- "443:443/tcp"
|
||||
- "1936:1936/tcp"
|
||||
networks:
|
||||
- easyhaproxy
|
||||
|
||||
networks:
|
||||
easyhaproxy:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
certs_letsencrypt:
|
||||
# external: true
|
||||
# certs_haproxy:
|
||||
# external: true
|
||||
28
examples/swarm/portainer.yml
Normal file
28
examples/swarm/portainer.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# To install:
|
||||
# docker stack deploy -c portainer.yml portainer
|
||||
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
portainer:
|
||||
image: portainer/portainer-ce:latest
|
||||
volumes:
|
||||
- portainer_data:/data portainer
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
deploy:
|
||||
replicas: 1
|
||||
labels:
|
||||
# easyhaproxy.http.redirect_ssl: true
|
||||
# easyhaproxy.http.letsencrypt: true
|
||||
easyhaproxy.http.host: portainer.local
|
||||
easyhaproxy.http.port: 80
|
||||
easyhaproxy.http.localport: 9000
|
||||
|
||||
volumes:
|
||||
certs_letsencrypt:
|
||||
external: true
|
||||
# certs_haproxy:
|
||||
# external: true
|
||||
portainer_data:
|
||||
# external: true
|
||||
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
# To install:
|
||||
# docker stack deploy -c services.yml services
|
||||
#
|
||||
# To test:
|
||||
# curl -k -H "Host: host1.local" https://127.0.0.1/
|
||||
# curl -k -H "Host: host2.local" https://127.0.0.1/
|
||||
|
|
@ -18,25 +21,6 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
haproxy:
|
||||
image: byjg/easy-haproxy
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./host2.local.pem:/certs/haproxy/host2.local.pem
|
||||
deploy:
|
||||
replicas: 1
|
||||
environment:
|
||||
EASYHAPROXY_DISCOVER: swarm
|
||||
EASYHAPROXY_SSL_MODE: "loose"
|
||||
HAPROXY_CUSTOMERRORS: "true"
|
||||
HAPROXY_USERNAME: admin
|
||||
HAPROXY_PASSWORD: password
|
||||
HAPROXY_STATS_PORT: 1936
|
||||
ports:
|
||||
- "80:80/tcp"
|
||||
- "443:443/tcp"
|
||||
- "1936:1936/tcp"
|
||||
|
||||
container:
|
||||
image: byjg/static-httpserver
|
||||
deploy:
|
||||
|
|
@ -40,6 +40,7 @@ class ProcessorInterface:
|
|||
|
||||
def __init__(self, filename = None):
|
||||
self.filename = filename
|
||||
self.label = ContainerEnv.read()['lookup_label']
|
||||
self.refresh()
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -156,21 +157,35 @@ class Swarm(ProcessorInterface):
|
|||
|
||||
def inspect_network(self):
|
||||
ha_proxy_service_name = self.client.containers.get(socket.gethostname()).name.split('.')[0]
|
||||
ha_proxy_network_id = None
|
||||
swarm_ingress_id = None
|
||||
|
||||
# Get the HAProxy network and the ingress network
|
||||
for endpoint in self.client.services.get(ha_proxy_service_name).attrs['Endpoint']["VirtualIPs"]:
|
||||
network_name = self.client.networks.get(endpoint["NetworkID"]).name
|
||||
if swarm_ingress_id is None and network_name == 'ingress':
|
||||
swarm_ingress_id = endpoint["NetworkID"]
|
||||
if ha_proxy_network_id is None and network_name != 'ingress':
|
||||
ha_proxy_network_id = endpoint["NetworkID"]
|
||||
if self.client.networks.get(ha_proxy_network_id).name != 'ingress':
|
||||
if ha_proxy_network_id is not None and swarm_ingress_id is not None:
|
||||
break
|
||||
|
||||
# Check if the service is attached to the HAProxy network
|
||||
self.parsed_object = {}
|
||||
for service in self.client.services.list():
|
||||
if not any(self.label in key for key in service.attrs["Spec"]["Labels"]):
|
||||
continue
|
||||
|
||||
ip_address = None
|
||||
network_list = []
|
||||
for endpoint in service.attrs["Endpoint"]["VirtualIPs"]:
|
||||
if ha_proxy_network_id == endpoint["NetworkID"]:
|
||||
ip_address = endpoint["Addr"].split("/")[0]
|
||||
break
|
||||
elif swarm_ingress_id != endpoint["NetworkID"]:
|
||||
network_list.append(endpoint["NetworkID"])
|
||||
|
||||
# Attach the service to the HAProxy network
|
||||
if ip_address is None:
|
||||
network_list.append(ha_proxy_network_id)
|
||||
service.update(networks = network_list)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue