We are going to deploy Keycloak using Docker Swarm.
We will install Docker Swarm on CentOS 7 and create a stack for Keycloak. Note that Keycloak realm configuration is not covered in this article.
Pre-requisites
- Three CentOS 7 VMs with root access.
- Private IP address for the master node (e.g. 10.11.1.80)
- MySQL database and user credentials to store Keycloak configuration.
Install Docker Engine
Run the following commands on all nodes.
Install packages:
# yum install -y yum-utils
Add Docker repository:
# yum-config-manager --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
Install Docker:
# yum install docker-ce docker-ce-cli containerd.io
Enable and start the service:
# systemctl enable docker && systemctl start docker
Configure Firewall
Open the following ports between all nodes:
- TCP port 2377 for cluster management communications.
- TCP and UDP port 7946 for communication among nodes.
- UDP port 4789 for overlay network traffic.
Iptables config snippet:
-A INPUT -s 10.11.1.0/24 -p tcp -m multiport --dports 2377,7946 -j ACCEPT -A INPUT -s 10.11.1.0/24 -p udp -m multiport --dports 4789,7946 -j ACCEPT
Create a Swarm
On the master node, initialise the swarm:
# docker swarm init --advertise-addr 10.11.1.80 Swarm initialized: current node (uglx1edsgztziitrlg2uwuls2) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN...juf 10.11.1.80:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Add Workers to Swarm
Add the other two servers as worker nodes:
# docker swarm join --token SWMTKN...juf 10.11.1.80:2377
Verify Swarm
# docker info # docker node ls
Deploy Portainer Agent (Optional)
This part is optional. I find Portainer somewhat useful.
Content of the file compose.yml
can be seen below.
services: agent: image: portainer/agent:latest ports: - "9001:9001/tcp" volumes: - /var/run/docker.sock:/var/run/docker.sock - /var/lib/docker/volumes:/var/lib/docker/volumes version: '3.8'
Deploy a new stack:
# docker stack deploy --compose-file compose.yml portainer
Deploy Keycloak
Note that creating a dedicated network is useful but not required. Create a new network:
# docker network create --attachable --driver overlay --gateway 10.55.254.1 --subnet 10.55.254.0/24 --scope swarm --label keycloak_net --internal keycloak_net
Content of the file kc-compose.yml
can be seen below.
version: '3.8' services: keycloak: image: jboss/keycloak:11.0.0 environment: KEYCLOAK_USER: admin KEYCLOAK_PASSWORD: changeme KEYCLOAK_HTTP_PORT: 8080 KEYCLOAK_HTTPS_PORT: 8443 KEYCLOAK_LOGLEVEL: INFO DB_VENDOR: mysql DB_ADDR: database.hl.local DB_PORT: 3306 DB_DATABASE: keycloak_swarm DB_USER: keycloak_swarm DB_PASSWORD: changeme networks: - keycloak_net ports: - "8080:8080/tcp" - "8443:8443/tcp" restart: unless-stopped volumes: - "/etc/hosts:/etc/hosts" ## poor man's DNS - "/opt/keycloak/certs/:/etc/x509/https" ## map certificates to container deploy: mode: replicated replicas: 1 placement: max_replicas_per_node: 1 constraints: - node.role==worker resources: limits: cpus: '1.50' memory: 1024M reservations: cpus: '0.05' memory: 128M networks: keycloak_net: external: true
Start with a single replica.
Keycloak image allows us to specify both a private key and a certificate for serving HTTPS. Directory /opt/keycloak/certs/
contains two files: tls.crt
and tls.key
. As per documentation, those files need to be mounted on /etc/x509/https
directory. If you don’t use/require HTTPS, comment the lines out.
Deploy a new stack:
# docker stack deploy --compose-file kc-compose.yml keycloak
Check service logs:
# docker service logs -f keycloak_keycloak
List services:
# docker service ls ID NAME MODE REPLICAS IMAGE PORTS pwu4krhlcqkq keycloak_keycloak replicated 1/1 (max 1 per node) jboss/keycloak:11.0.0 *:8080->8080/tcp, *:8443->8443/tcp qoywxieiy53h portainer_agent replicated 1/1 portainer/agent:latest *:9001->9001/tcp
References
https://docs-stage.docker.com/engine/swarm/stack-deploy
https://registry.hub.docker.com/r/jboss/keycloak