feat: add worker nodes to docker swarm setup
This commit is contained in:
parent
22d7e4a318
commit
d318880600
10 changed files with 252 additions and 112 deletions
|
|
@ -1,5 +1,12 @@
|
|||
[homelab]
|
||||
[homelab:children]
|
||||
docker
|
||||
|
||||
[docker:children]
|
||||
docker_managers
|
||||
docker_workers
|
||||
|
||||
[docker_managers]
|
||||
10.0.10.50
|
||||
|
||||
[docker]
|
||||
10.0.10.50 docker_swarm_manager=true
|
||||
[docker_workers]
|
||||
10.0.10.[51:52]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/playbook.json
|
||||
|
||||
# > /COPILOT_GENERATE I'm writing an ansible playbook to setup a new alpine server, I want you to help me to generate some tasks
|
||||
|
||||
---
|
||||
- name: Setup an alpine machine
|
||||
hosts: homelab
|
||||
user: root
|
||||
|
|
@ -41,24 +41,12 @@
|
|||
line: 'permit persist :wheel'
|
||||
state: present
|
||||
|
||||
- name: Install Docker
|
||||
ansible.builtin.package:
|
||||
state: present
|
||||
name:
|
||||
- docker
|
||||
- docker-cli-compose
|
||||
- py3-yaml
|
||||
- py3-pip
|
||||
- py3-docker-py
|
||||
|
||||
- name: Common setup
|
||||
hosts: homelab
|
||||
user: root
|
||||
roles:
|
||||
- role: common
|
||||
vars:
|
||||
extra_groups:
|
||||
- docker
|
||||
robo_allowed_commands:
|
||||
- "docker system dial-stdio"
|
||||
|
||||
|
|
@ -67,3 +55,27 @@
|
|||
user: root
|
||||
roles:
|
||||
- docker
|
||||
vars:
|
||||
users:
|
||||
- aleidk
|
||||
- robo
|
||||
|
||||
- name: Setup docker swarm manager
|
||||
hosts: docker_managers
|
||||
user: root
|
||||
tasks:
|
||||
- name: Setup swarm manager
|
||||
include_role:
|
||||
name: docker
|
||||
tasks_from: swarm_manager.yaml
|
||||
|
||||
- name: Setup docker swarm workers
|
||||
hosts: docker_workers
|
||||
user: root
|
||||
tasks:
|
||||
- name: "Setup swarm workers"
|
||||
include_role:
|
||||
name: docker
|
||||
tasks_from: swarm_worker.yaml
|
||||
vars:
|
||||
managers_group: docker_managers
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ argument_specs:
|
|||
type: "list"
|
||||
elements: "str"
|
||||
required: false
|
||||
default: []
|
||||
description:
|
||||
- "Additional groups that will be added to each user"
|
||||
robo_allowed_commands:
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/tasks.json
|
||||
|
||||
- name: Create a user group named docker
|
||||
loop: "{{ extra_groups }}"
|
||||
ansible.builtin.group:
|
||||
name: "{{ item }}"
|
||||
|
||||
- name: Setup users
|
||||
loop: "{{ users }}"
|
||||
ansible.builtin.user:
|
||||
|
|
@ -14,7 +9,7 @@
|
|||
shell: "{{ item.shell }}"
|
||||
create_home: true
|
||||
password: "{{ (item.password != '!' or item.password != '*') | ternary(item.password | password_hash('sha512'), item.password) }}"
|
||||
groups: "{{ item.groups + extra_groups }}"
|
||||
groups: "{{ item.groups + (extra_groups | default([])) }}"
|
||||
|
||||
- name: Add SSH public key to users
|
||||
loop: "{{ users }}"
|
||||
|
|
|
|||
61
roles/docker/files/openrc.sh
Executable file
61
roles/docker/files/openrc.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
#!/sbin/openrc-run
|
||||
supervisor=supervise-daemon
|
||||
|
||||
name="Docker Daemon"
|
||||
description="Persistent process that manages docker containers"
|
||||
description_reload="Reload configuration without exiting"
|
||||
|
||||
command="${DOCKERD_BINARY:-/usr/bin/dockerd}"
|
||||
command_args="${DOCKER_OPTS}"
|
||||
|
||||
DOCKER_LOGFILE="${DOCKER_LOGFILE:-/var/log/${RC_SVCNAME}.log}"
|
||||
DOCKER_ERRFILE="${DOCKER_ERRFILE:-${DOCKER_LOGFILE}}"
|
||||
DOCKER_OUTFILE="${DOCKER_OUTFILE:-${DOCKER_LOGFILE}}"
|
||||
if [ "$DOCKER_ERRFILE" = "$DOCKER_OUTFILE" ]; then
|
||||
LOGPROXY_OPTS="$LOGPROXY_OPTS -m"
|
||||
fi
|
||||
export \
|
||||
LOGPROXY_CHMOD="${LOGPROXY_CHMOD:-0644}" \
|
||||
LOGPROXY_LOG_DIRECTORY="${LOGPROXY_LOG_DIRECTORY:-/var/log}" \
|
||||
LOGPROXY_ROTATION_SIZE="${LOGPROXY_ROTATION_SIZE:-104857600}" \
|
||||
LOGPROXY_ROTATION_TIME="${LOGPROXY_ROTATION_TIME:-86400}" \
|
||||
LOGPROXY_ROTATION_SUFFIX="${LOGPROXY_ROTATION_SUFFIX:-.%Y%m%d%H%M%S}" \
|
||||
LOGPROXY_ROTATED_FILES="${LOGPROXY_ROTATE_FILES:-5}"
|
||||
|
||||
output_logger="log_proxy $LOGPROXY_OPTS $DOCKER_OUTFILE"
|
||||
error_logger="log_proxy $LOGPROXY_OPTS $DOCKER_ERRFILE"
|
||||
|
||||
extra_started_commands="reload"
|
||||
|
||||
rc_ulimit=""
|
||||
RC_ULIMIT=""
|
||||
if [ "$1" = "start" ]; then
|
||||
if [ $BASH ]; then
|
||||
rc_ulimit="${DOCKER_ULIMIT:--c unlimited -n 1048576 -u unlimited}"
|
||||
else
|
||||
ulimit -c unlimited
|
||||
ulimit -n 1048576
|
||||
ulimit -p unlimited
|
||||
fi
|
||||
fi
|
||||
|
||||
retry="${DOCKER_RETRY:-TERM/60/KILL/10}"
|
||||
|
||||
if [ -e /etc/profile.d/proxy.sh ]; then
|
||||
. /etc/profile.d/proxy.sh
|
||||
fi
|
||||
|
||||
depend() {
|
||||
need sysfs cgroups net
|
||||
after firewall
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
checkpath -f -m 0644 -o root:docker "$DOCKER_ERRFILE" "$DOCKER_OUTFILE"
|
||||
}
|
||||
|
||||
reload() {
|
||||
ebegin "Reloading configuration"
|
||||
$supervisor $RC_SVCNAME --signal HUP
|
||||
eend $?
|
||||
}
|
||||
25
roles/docker/meta/argument_specs.yml
Normal file
25
roles/docker/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
argument_specs:
|
||||
main:
|
||||
short_description: Main entrypoint
|
||||
author:
|
||||
- aleidk
|
||||
options:
|
||||
users:
|
||||
type: "list"
|
||||
elements: "str"
|
||||
default: []
|
||||
description:
|
||||
- "list of users to add to the docker group"
|
||||
|
||||
swarm_workers:
|
||||
short_description: Docker swarm workers setup
|
||||
author:
|
||||
- aleidk
|
||||
options:
|
||||
managers_group:
|
||||
type: "str"
|
||||
required: true
|
||||
description:
|
||||
- "The host group of the managers"
|
||||
- "Used to obtain the advertised address and join tokens"
|
||||
20
roles/docker/tasks/docker_alpine.yaml
Normal file
20
roles/docker/tasks/docker_alpine.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/tasks.json
|
||||
---
|
||||
- name: Install Docker
|
||||
ansible.builtin.package:
|
||||
state: present
|
||||
name:
|
||||
- docker
|
||||
- docker-cli-compose
|
||||
- py3-yaml
|
||||
- py3-pip
|
||||
- py3-docker-py
|
||||
|
||||
- name: Copy openrc.sh to /etc/init.d/docker
|
||||
copy:
|
||||
src: files/openrc.sh
|
||||
dest: /etc/init.d/docker
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
|
|
@ -1,94 +1,23 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/tasks.json
|
||||
---
|
||||
- name: Create a user group named docker
|
||||
ansible.builtin.group:
|
||||
name: "docker"
|
||||
|
||||
- name: Add users to docker group
|
||||
loop: "{{ users }}"
|
||||
ansible.builtin.user:
|
||||
state: present
|
||||
append: true
|
||||
name: "{{ item }}"
|
||||
groups: "docker"
|
||||
|
||||
- name: Install docker in Alpine
|
||||
import_tasks: docker_alpine.yaml
|
||||
when: ansible_facts['os_family']|lower == 'alpine'
|
||||
|
||||
- name: Start docker service
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Setup Docker Swarm
|
||||
when: docker_swarm_manager | bool
|
||||
block:
|
||||
- name: Enable Docker Swarm mode
|
||||
community.docker.docker_swarm:
|
||||
state: present
|
||||
|
||||
- name: Create Traefik network
|
||||
community.docker.docker_network:
|
||||
name: reverse-proxy
|
||||
driver: overlay
|
||||
attachable: true
|
||||
|
||||
- name: Deploy Traefik service
|
||||
community.docker.docker_compose_v2:
|
||||
remove_orphans: true
|
||||
project_name: reverse-proxy
|
||||
definition:
|
||||
networks:
|
||||
reverse-proxy:
|
||||
external: true
|
||||
services:
|
||||
traefik:
|
||||
container_name: traefix-proxy
|
||||
image: 'traefik:latest'
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- reverse-proxy
|
||||
ports:
|
||||
# listen on host ports without ingress network
|
||||
- target: 80
|
||||
published: 80
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 443
|
||||
published: 443
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 8080
|
||||
published: 8080
|
||||
protocol: tcp
|
||||
mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
healthcheck:
|
||||
test: 'wget -qO- http://localhost:80/ping || exit 1'
|
||||
interval: 4s
|
||||
timeout: 2s
|
||||
retries: 5
|
||||
command:
|
||||
- '--ping=true'
|
||||
- '--ping.entrypoint=http'
|
||||
- '--api.dashboard=true'
|
||||
- '--api.insecure=true'
|
||||
- '--entrypoints.http.address=:80'
|
||||
- '--entryPoints.http.forwardedHeaders.trustedIPs=10.0.10.0/24'
|
||||
- '--entrypoints.http.http.encodequerysemicolons=true'
|
||||
- '--entryPoints.http.http2.maxConcurrentStreams=50'
|
||||
# - "--providers.swarm.endpoint=tcp://{{ ansible_default_ipv4.address }}:2375"
|
||||
- --providers.swarm.exposedByDefault=false
|
||||
- --providers.swarm.network=reverse-proxy
|
||||
deploy:
|
||||
mode: global
|
||||
placement:
|
||||
constraints:
|
||||
- node.role==manager
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.traefik.entrypoints=http
|
||||
- traefik.http.routers.traefik.service=api@internal
|
||||
- traefik.http.services.traefik.loadbalancer.server.port=8080
|
||||
|
||||
- name: Check if Docker context exists
|
||||
local_action: ansible.builtin.command docker context inspect {{ ansible_hostname }}
|
||||
register: context_exists
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create Docker context for each Swarm manager machine
|
||||
local_action: >
|
||||
ansible.builtin.command docker context create {{ ansible_hostname }} --docker "host=ssh://{{ ansible_default_ipv4.address }}"
|
||||
when: context_exists.stderr != ''
|
||||
|
||||
- name: Join Docker Swarm as a worker
|
||||
community.docker.docker_swarm:
|
||||
state: join
|
||||
join_token: "{{ hostvars['manager']['docker_swarm_worker_token'] }}"
|
||||
remote_addrs: ["{{ hostvars['manager']['ansible_default_ipv4']['address'] }}"]
|
||||
when: not docker_swarm_manager | bool
|
||||
|
|
|
|||
81
roles/docker/tasks/swarm_manager.yaml
Normal file
81
roles/docker/tasks/swarm_manager.yaml
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/tasks.json
|
||||
---
|
||||
- name: Enable Docker Swarm mode
|
||||
register: swarm_info
|
||||
community.docker.docker_swarm:
|
||||
state: present
|
||||
|
||||
- name: Create Traefik network
|
||||
community.docker.docker_network:
|
||||
name: reverse-proxy
|
||||
driver: overlay
|
||||
attachable: true
|
||||
|
||||
- name: Check if Docker context exists
|
||||
local_action: ansible.builtin.command docker context inspect {{ ansible_hostname }}
|
||||
register: context_exists
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create Docker context for each Swarm manager machine
|
||||
local_action: >
|
||||
ansible.builtin.command docker context create {{ ansible_hostname }} --docker "host=ssh://{{ ansible_default_ipv4.address }}"
|
||||
when: context_exists.stderr != ''
|
||||
|
||||
- name: Deploy Traefik service
|
||||
community.docker.docker_compose_v2:
|
||||
remove_orphans: true
|
||||
project_name: reverse-proxy
|
||||
definition:
|
||||
networks:
|
||||
reverse-proxy:
|
||||
external: true
|
||||
services:
|
||||
traefik:
|
||||
container_name: traefix-proxy
|
||||
image: 'traefik:latest'
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- reverse-proxy
|
||||
ports:
|
||||
# listen on host ports without ingress network
|
||||
- target: 80
|
||||
published: 80
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 443
|
||||
published: 443
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 8080
|
||||
published: 8080
|
||||
protocol: tcp
|
||||
mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
healthcheck:
|
||||
test: 'wget -qO- http://localhost:80/ping || exit 1'
|
||||
interval: 4s
|
||||
timeout: 2s
|
||||
retries: 5
|
||||
command:
|
||||
- '--ping=true'
|
||||
- '--ping.entrypoint=http'
|
||||
- '--api.dashboard=true'
|
||||
- '--api.insecure=true'
|
||||
- '--entrypoints.http.address=:80'
|
||||
- '--entryPoints.http.forwardedHeaders.trustedIPs=10.0.10.0/24'
|
||||
- '--entrypoints.http.http.encodequerysemicolons=true'
|
||||
- '--entryPoints.http.http2.maxConcurrentStreams=50'
|
||||
# - "--providers.swarm.endpoint=tcp://{{ ansible_default_ipv4.address }}:2375"
|
||||
- --providers.swarm.exposedByDefault=false
|
||||
- --providers.swarm.network=reverse-proxy
|
||||
deploy:
|
||||
mode: global
|
||||
placement:
|
||||
constraints:
|
||||
- node.role==manager
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.traefik.entrypoints=http
|
||||
- traefik.http.routers.traefik.service=api@internal
|
||||
- traefik.http.services.traefik.loadbalancer.server.port=8080
|
||||
9
roles/docker/tasks/swarm_worker.yaml
Normal file
9
roles/docker/tasks/swarm_worker.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/refs/heads/main/src/ansiblelint/schemas/tasks.json
|
||||
---
|
||||
- name: Join Docker Swarm as a worker
|
||||
vars:
|
||||
key: "{{ groups[managers_group] | map('extract', hostvars, ['swarm_info', 'swarm_facts', 'JoinTokens', 'Worker']) | list | first }}"
|
||||
community.docker.docker_swarm:
|
||||
state: join
|
||||
join_token: "{{ key }}"
|
||||
remote_addrs: "{{ groups[managers_group] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) }}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue