Swarm operational

This commit is contained in:
lif
2025-10-12 12:30:50 +01:00
parent 6368588bce
commit 0a562d8d01
9 changed files with 233 additions and 63 deletions

View File

@@ -7,8 +7,15 @@ destroy:
ansible-setup:
ansible-galaxy install -r ansible/ansible-requirements.yml
ansible-master:
cd ansible && ansible-playbook -i ../vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory master.yml
cd ansible && ansible-playbook -i ../vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory swarm-master.yml
ansible-workers:
cd ansible && ansible-playbook -i ../vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory swarm-node.yml
ansible-stack:
cd ansible && ansible-playbook -i ../vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory swarm-stack.yml
ansible-full:
make ansible-master && make ansible-workers && make ansible-full
setup-keys:
mkdir -p ./keys
@@ -19,4 +26,9 @@ ansible-watch:
full-reset:
make destroy
make up && make ansible-master
make up && make ansible-full
swarm-check:
cd vagrant && vagrant ssh swarm-master -c "docker info"|grep -e "Managers" -e "Nodes"
service-ls:
cd vagrant && vagrant ssh swarm-master -c "docker service ls"

View File

@@ -2,3 +2,5 @@
host_key_checking=False
# stdout_callback = minimal
color = true
interpreter_python = /usr/bin/python3.9
deprecation_warnings=False

View File

@@ -0,0 +1,30 @@
version: '3.8'
services:
portainer:
image: portainer/portainer-ce:latest
command: -H unix:///var/run/docker.sock
ports:
- "9000:9000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
networks:
- portainer_net
deploy:
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
replicas: 1
volumes:
portainer_data:
external: true
networks:
portainer_net:
driver: overlay
attachable: true

View File

@@ -1,52 +0,0 @@
---
- hosts: swarm_master
become: true
vars_files:
- group_vars/all.yml
vars:
swap_file_state: present
swap_file_existing_size_mb: 0
roles:
- role: geerlingguy.swap
- role: geerlingguy.docker
- role: common
tasks:
- name: Check memory and swap usage
command: free -m
register: memory_info
changed_when: false
- name: Ensure Python pip is installed
package:
name: python3-pip
state: present
- name: Ensure Docker SDK for Python is installed
pip:
name: docker>=5.0.0
executable: pip3
- name: Init a new swarm with default parameters
community.docker.docker_swarm:
state: present
- name: Debug all variables
debug:
msg: "swap_file_size_mb: {{ swap_file_size_mb }}, swap_file_state: {{ swap_file_state }}"
- name: Debug Docker variables
debug:
msg: "docker_edition: {{ docker_edition }}, docker_packages: {{ docker_packages }}"
# - name: Debug all host variables
# debug:
# var: hostvars[inventory_hostname]
# - name: Initialize the cluster
# shell: docker swarm init --advertise-addr 192.168.56.10 >> cluster_initialized.txt
# args:
# chdir: $HOME
# creates: cluster_initialized.txt

View File

@@ -2,6 +2,36 @@
command: free -m
register: memory_info
changed_when: false
- name: Run the equivalent of "apt-get update" as a separate step
- name: apt update
ansible.builtin.apt:
update_cache: yes
- name: Ensure Python pip is installed
package:
name: python3-pip
state: present
- name: Ensure Docker SDK for Python is installed
pip:
name: docker>=5.0.0
executable: pip3
- name: Ensure Docker Compose is installed
pip:
name: docker-compose>=1.29.0
executable: pip3
- name: Install 'jsondiff' Python module
pip:
name: jsondiff
executable: pip3
- name: wait for docker service
service:
name: docker
state: started
register: docker_service
until: docker_service.status.ActiveState == "active"
retries: 10
delay: 20

78
ansible/swarm-master.yml Normal file
View File

@@ -0,0 +1,78 @@
---
- hosts: swarm_master
become: true
roles:
- role: geerlingguy.swap
- role: geerlingguy.docker
- role: common
tasks:
- name: Debug all relevant variables
debug:
msg: |
=== SWARM JOIN DEBUG INFO ===
Current host: {{ inventory_hostname }}
Current host IP: {{ ansible_host }}
Master group hosts: {{ groups['swarm_master'] }}
First master: {{ groups['swarm_master'][0] }}
Master hostvars:
- ansible_host: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] }}
- inventory_hostname: {{ hostvars[groups['swarm_master'][0]]['inventory_hostname'] }}
Remote address calculation:
- Raw master ansible_host: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] }}
- Fallback to hostname: {{ groups['swarm_master'][0] }}
- Final address: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] | default(groups['swarm_master'][0]) }}
- With port: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] | default(groups['swarm_master'][0]) }}:2377
- name: Init a new swarm with default parameters
community.docker.docker_swarm:
state: present
advertise_addr: "{{ ansible_eth1.ipv4.address }}"
listen_addr: "{{ ansible_eth1.ipv4.address }}"
- name: print listen addr
debug:
msg: "{{ ansible_eth1.ipv4.address }}"
- name: Get Docker Swarm information
community.docker.docker_swarm_info:
register: swarm_info
- name: Save worker join token to file
copy:
content: "{{ swarm_info.swarm_facts.JoinTokens.Worker }}"
dest: /tmp/swarm_worker_token
mode: '0600'
- name: Save manager join token to file
copy:
content: "{{ swarm_info.swarm_facts.JoinTokens.Manager }}"
dest: /tmp/swarm_manager_token
mode: '0600'
# Copy tokens to host filesystem
# - name: Fetch worker join token to host
# fetch:
# src: /tmp/swarm_worker_token
# dest: ./tokens/swarm_worker_token
# flat: yes
# - name: Fetch manager join token to host
# fetch:
# src: /tmp/swarm_manager_token
# dest: ./tokens/swarm_manager_token
# flat: yes
# - name: Create Portainer data volume
# community.docker.docker_volume:
# name: portainer_data
# state: present
# - name: Deploy Portainer stack from compose file
# community.docker.docker_stack:
# name: portainer
# state: present
# compose:
# - "{{ lookup('file', 'files/docker-base-stack.yml') | from_yaml }}"

View File

@@ -1,16 +1,68 @@
---
- hosts: swarm_workers
become: true
gather_facts: yes
vars:
roles:
- role: geerlingguy.swap
swap_file_size_mb: 1024
- role: geerlingguy.docker
- role: common
tasks:
- name: Check memory and swap usage
command: free -m
register: memory_info
changed_when: false
- name: Get worker join token from master
slurp:
src: /tmp/swarm_worker_token
register: worker_token_file
delegate_to: "{{ groups['swarm_master'][0] }}"
- name: Decode worker join token
set_fact:
worker_token: "{{ worker_token_file.content | b64decode | trim }}"
- name: Debug all relevant variables
debug:
msg: |
=== SWARM JOIN DEBUG INFO ===
Current host: {{ inventory_hostname }}
Current host IP: {{ ansible_host }}
Master group hosts: {{ groups['swarm_master'] }}
First master: {{ groups['swarm_master'][0] }}
Master hostvars:
- ansible_host: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] }}
- inventory_hostname: {{ hostvars[groups['swarm_master'][0]]['inventory_hostname'] }}
Remote address calculation:
- Raw master ansible_host: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] }}
- Fallback to hostname: {{ groups['swarm_master'][0] }}
- Final address: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] | default(groups['swarm_master'][0]) }}
- With port: {{ hostvars[groups['swarm_master'][0]]['ansible_host'] | default(groups['swarm_master'][0]) }}:2377
Join token (first 10 chars): {{ worker_token[:10] }}...
- name: Gather master facts
ansible.builtin.setup:
delegate_to: "{{ groups['swarm_master'][0] }}"
run_once: true
register: master_facts
- name: Debug master hostvars
debug:
msg: |
Master hostvars keys: {{ hostvars[groups['swarm_master'][0]].keys() | list }}
Master ansible_eth1: {{ hostvars[groups['swarm_master'][0]].ansible_eth1 | default('Not available') }}
Master node: {{ groups['swarm_master'][0] }}
Master ansible_default_ipv4: {{ hostvars[groups['swarm_master'][0]] }}
Master ansible_default_ipv4: {{ master_facts.ansible_facts }}
FINAL IP: {{ master_facts.ansible_facts ['ansible_eth1']['ipv4']['address'] }}
- name: Add nodes
community.docker.docker_swarm:
state: join
join_token: "{{ worker_token }}"
remote_addrs:
- "{{ master_facts.ansible_facts ['ansible_eth1']['ipv4']['address'] }}:2377"
advertise_addr: "{{ ansible_eth1.ipv4.address }}"

18
ansible/swarm-stack.yml Normal file
View File

@@ -0,0 +1,18 @@
---
- hosts: swarm_master
become: true
roles:
tasks:
- name: Create Portainer data volume
community.docker.docker_volume:
name: portainer_data
state: present
- name: Deploy Portainer stack from compose file
community.docker.docker_stack:
name: portainer
state: present
compose:
- "{{ lookup('file', 'files/docker-base-stack.yml') | from_yaml }}"

6
vagrant/Vagrantfile vendored
View File

@@ -1,4 +1,4 @@
num_workers = 1
num_workers = 7
nodes = [
{ hostname: 'swarm-master', ip: '192.168.56.10', ram: 256, cpus: 1, groups: ['swarm_master'] }
@@ -31,7 +31,7 @@ Vagrant.configure('2') do |config|
# ansible.limit = "all"
# ansible.raw_arguments = ["--timeout=60"]
end
nodes.each do |node|
puts "Provisioning node: #{node[:hostname]}"
config.vm.define node[:hostname] do |node_config|
@@ -40,7 +40,7 @@ Vagrant.configure('2') do |config|
# node_config.vm.box = 'generic/archlinux64'
# node_config.vm.box_version = "20250415.336224"
# node_config.vm.network "private_network", ip: node[:ip]
node_config.vm.network "private_network", ip: node[:ip]
node_config.vm.provider "virtualbox" do |vb|
vb.name = node[:hostname]
vb.memory = node[:ram]