ansible-role-docker-swarm/README.md

114 lines
4.8 KiB
Markdown

Role Name
=========
A role that configures a docker swarm cluster, adding Portainer CE and HAPROXY
Role Variables
--------------
The most important variables are listed below:
``` yaml
docker_swarm_cluster_haproxy_install: true
# mesh, keepalive, global
docker_swarm_haproxy_installation_type: 'keepalive'
docker_swarm_haproxy_networks:
- '{{ docker_swarm_portainer_network }}'
#
docker_swarm_expose_api_via_haproxy: false
docker_swarm_expose_api_hostname: 'swarm.example.com'
# Portainer
docker_swarm_cluster_portainer_install: true
docker_swarm_portainer_hostname: 'portainer-swarm.example.com'
docker_swarm_portainer_additional_constraints: []
# - 'node.hostname != docker01'
docker_swarm_portainer_nfs_volume: false
docker_swarm_portainer_nfs_type: 'nfs4'
docker_swarm_portainer_nfs_o: 'nfsvers=4,addr=127.0.0.1,rw,nolock,soft'
docker_swarm_portainer_nfs_device: ':/tmp'
docker_swarm_portainer_network: 'agent_network'
docker_swarm_portainer_http_port: '9000'
docker_swarm_portainer_service_port: '8000'
docker_swarm_haproxy_additional_services: []
# - { acl_name: 'service', acl_rule: 'hdr_dom(host) -i service.example.com', service_name: 'service-', service_replica_num: '1', service_port: '9999', service_overlay_network: 'service-network', http_redirect_to_https: True }
```
HAPROXY configuration
------------
`docker_swarm_haproxy_plain_http_global_acl_rules` allows the definition of arbitrary acl with the corresponding http-request rules, for the *plain http* listener
`docker_swarm_haproxy_global_acl_rules` allows the definition of arbitrary acl with the corresponding http-request rules, for the *https* listener
`haproxy_docker_swarm_additional_services` is the dictionary that contains the backends definitions and their acls
A plain http listener can be defined, using the following variables. The syntax of `haproxy_docker_swarm_plain_http_services` is identical to the `haproxy_docker_swarm_additional_services` one.
```yaml
haproxy_docker_swarm_plain_http_listener: true
haproxy_docker_swarm_plain_http_port: 8080
haproxy_docker_swarm_plain_http_services: []
```
Optional HAProxy features
-------------------------
The generated `haproxy.cfg` can serve `robots.txt`, deny blacklisted user agents,
apply a per-source flood control with a browser-validation challenge, handle CORS
and enforce OIDC/JWT authentication. Everything is off by default; see
`defaults/main.yml` for the variables and the per-service opt-in fields.
**These features need files, and on Swarm HAProxy runs in a container.** The role
only writes the configuration: getting the files in place is a deployment
decision, and there are three ways to do it.
1. **Through the directory that is already mounted.** With
`haproxy_docker_mount_conf_file: true` the `haproxy` role bind-mounts
`/etc/haproxy` on the manager node to `/usr/local/etc/haproxy` inside the
container. Anything rendered under `/etc/haproxy/static/` and
`/etc/haproxy/lua/` is therefore visible to HAProxy with no additional volume,
and an in-place reload picks it up without recreating the service. The path
defaults in this role assume exactly this layout. It covers `robots.txt`, the
user-agent blacklists and `cors.lua`.
2. **Docker configs / secrets.** Cleaner distribution (the manager pushes them,
nothing to manage per node) but config objects are immutable: changing one
means creating a new object and updating the service, i.e. a rolling restart
instead of a reload. Reasonable for files that never change, awkward for
blacklists. Use a secret for the stats password if the config file is moved to
a config object, since config objects are not secret; HAProxy expands
`${VARIABLE}` from its environment, so a small entrypoint wrapper that exports
the secret file's content is enough.
3. **A custom image.** Required — not merely convenient — for the OIDC scripts:
they `require` cjson, socket, ssl and ltn12, and the stock
`haproxytech/haproxy-debian` image ships HAProxy built with Lua support but not
a single Lua module, which cannot be installed at run time. The build itself is
trivial, since that image is Debian based and the Debian/Ubuntu module packages
(`lua-cjson`, `lua-socket`, `lua-sec`) install for every Lua ABI from 5.1 to
5.4, so they cover whatever the image links. What it costs is owning an image
build and publish pipeline tied to HAProxy version bumps. `cors.lua` needs no
modules and works in the stock image.
Recommended split: option 1 for the static files and CORS, and either a custom
image or a separate `oauth2-proxy` service for OIDC. `oauth2-proxy` avoids the
image pipeline altogether and does not depend on the Lua code path, which has
never run in production.
Dependencies
------------
* docker
* keepalived, when haproxy is installed in HA host mode
License
-------
EUPL-1.2
Author Information
------------------
Andrea Dell'Amico, <andrea.dellamico@isti.cnr.it>