Working setup

This commit is contained in:
lif
2025-10-17 14:11:52 +01:00
parent 5b3cd2b8b6
commit 492318c2e1
9 changed files with 49 additions and 173 deletions

View File

@@ -2,6 +2,8 @@ list:
vagrant status vagrant status
up: up:
cd vagrant && vagrant up cd vagrant && vagrant up
halt:
cd vagrant && vagrant halt
destroy: destroy:
cd vagrant && vagrant destroy -f cd vagrant && vagrant destroy -f

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
# Vagrant Swarm
Create a cluster of nodes with vagrant and set up docker swarm with ansible.

View File

@@ -55,37 +55,10 @@
retries: 10 retries: 10
delay: 20 delay: 20
# - name: Create Docker config directory for vagrant user
# file:
# path: /home/vagrant/.docker
# state: directory
# mode: '0700'
# owner: vagrant
# group: vagrant
- name: Login to Docker Hub as vagrant user - name: Login to Docker Hub as vagrant user
community.docker.docker_login: community.docker.docker_login:
username: "{{ docker_hub_username }}" username: "{{ docker_hub_username }}"
password: "{{ docker_hub_password }}" password: "{{ docker_hub_password }}"
# config_path: "/home/vagrant/.docker"
reauth: true reauth: true
become_user: vagrant
when: docker_hub_username is defined and docker_hub_password is defined when: docker_hub_username is defined and docker_hub_password is defined
register: docker_login_result register: docker_login_result
- name: Debug Docker Hub credentials
debug:
msg: |
Username: {{ docker_hub_username }}
Password: {{ docker_hub_password }}
- name: Debug Docker login result
debug:
msg: |
=== DOCKER LOGIN RESULT ===
Changed: {{ docker_login_result.changed }}
Failed: {{ docker_login_result.failed | default(false) }}
Message: {{ docker_login_result.msg | default('No message') }}
Login successful: {{ docker_login_result.login_successful | default('Unknown') }}
Full result: {{ docker_login_result }}
# when: docker_hub_username is defined and docker_hub_password is defined

View File

@@ -8,42 +8,10 @@
- role: common - role: common
tasks: 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: Debug master hostvars
debug:
msg: |
advertise_addr: {{ ansible_eth1.ipv4.address }}
ansible_eth0: {{ ansible_eth0.ipv4.address }}
- name: Init a new swarm with default parameters - name: Init a new swarm with default parameters
community.docker.docker_swarm: community.docker.docker_swarm:
state: present state: present
advertise_addr: "{{ ansible_eth1.ipv4.address }}" advertise_addr: "{{ ansible_eth1.ipv4.address }}"
# listen_addr: "{{ ansible_eth1.ipv4.address }}"
# data_path_addr: "{{ ansible_eth1.ipv4.address }}"
- name: print listen addr
debug:
msg: "{{ ansible_eth1.ipv4.address }}"
- name: Get Docker Swarm information - name: Get Docker Swarm information
community.docker.docker_swarm_info: community.docker.docker_swarm_info:
@@ -60,27 +28,3 @@
content: "{{ swarm_info.swarm_facts.JoinTokens.Manager }}" content: "{{ swarm_info.swarm_facts.JoinTokens.Manager }}"
dest: /tmp/swarm_manager_token dest: /tmp/swarm_manager_token
mode: '0600' 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

@@ -20,64 +20,16 @@
set_fact: set_fact:
worker_token: "{{ worker_token_file.content | b64decode | trim }}" 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 }}
# ansible_eth1={{ ansible_eth1.ipv4.address }}
# 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: Debug IPs
debug:
msg: |
Current hostname: {{ inventory_hostname }}
ansible_eth1 full: {{ ansible_eth1 }}
ansible_eth1 ipv4: {{ ansible_eth1.ipv4 }}
ansible_eth1 ipv4 address: {{ ansible_eth1.ipv4.address }}
advertise_addr: {{ ansible_eth1.ipv4.address }}
ansible_eth0: {{ ansible_eth0.ipv4.address }}
- name: Gather master facts - name: Gather master facts
ansible.builtin.setup: ansible.builtin.setup:
delegate_to: "{{ groups['swarm_master'][0] }}" delegate_to: "{{ groups['swarm_master'][0] }}"
run_once: true run_once: true
register: master_facts register: master_facts
# Needed as gathering master facts will overwrite
- name: Regather node facts - name: Regather node facts
ansible.builtin.setup: ansible.builtin.setup:
# - 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 }}
# remote_addrs: {{ master_facts.ansible_facts ['ansible_eth1']['ipv4']['address'] }}
# advertise_addr: {{ ansible_eth1.ipv4.address }}
- name: Debug IPs
debug:
msg: |
remote_addrs: {{ master_facts.ansible_facts['ansible_eth1']['ipv4']['address'] }}:2377
advertise_addr: {{ ansible_eth1.ipv4.address }}
ansible_eth0: {{ ansible_eth0.ipv4.address }}
- name: Add nodes - name: Add nodes
community.docker.docker_swarm: community.docker.docker_swarm:
state: join state: join
@@ -85,6 +37,10 @@
remote_addrs: remote_addrs:
- "{{ master_facts.ansible_facts['ansible_eth1']['ipv4']['address'] }}:2377" - "{{ master_facts.ansible_facts['ansible_eth1']['ipv4']['address'] }}:2377"
advertise_addr: "{{ ansible_eth1.ipv4.address }}" advertise_addr: "{{ ansible_eth1.ipv4.address }}"
# listen_addr: "{{ ansible_eth1.ipv4.address }}" # You already added this
# data_path_addr: "{{ ansible_eth1.ipv4.address }}" - name: Replace node labels with new labels
community.docker.docker_node:
hostname: "{{ inventory_hostname }}"
labels: "{{ dict(group_names | zip(['true'] * group_names | length)) }}"
labels_state: replace
delegate_to: "{{ groups['swarm_master'][0] }}"

View File

@@ -37,18 +37,10 @@ services:
# HTTP EntryPoint # HTTP EntryPoint
- "--entrypoints.web.address=:80" - "--entrypoints.web.address=:80"
# Configure HTTP to HTTPS Redirection
# - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
# - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
# - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# HTTPS EntryPoint # HTTPS EntryPoint
- "--entrypoints.websecure.address=:443" - "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true" - "--entrypoints.websecure.http.tls=true"
# Attach dynamic TLS file
# - "--providers.file.filename=/dynamic/tls.yaml"
# Providers # Providers
# Enable the Docker Swarm provider (instead of Docker provider) # Enable the Docker Swarm provider (instead of Docker provider)
@@ -95,13 +87,10 @@ services:
- "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls=false" - "traefik.http.routers.dashboard.tls=false"
# Basicauth middleware
# - "traefik.http.middlewares.dashboard-auth.basicauth.users=<PASTE_HASH_HERE>"
# - "traefik.http.routers.dashboard.middlewares=dashboard-auth@swarm"
# Service hint # Service hint
- "traefik.http.services.traefik.loadbalancer.server.port=8080" - "traefik.http.services.traefik.loadbalancer.server.port=8080"
# Deploy the Whoami application # Deploy the Whoami application
whoami: whoami:
image: traefik/whoami image: traefik/whoami
@@ -128,4 +117,4 @@ services:
networks: networks:
traefik_proxy: traefik_proxy:
driver: overlay driver: overlay
# attachable: true # attachable: true

View File

@@ -5,10 +5,18 @@
roles: roles:
tasks: tasks:
- name: Upload Prometheus configuration
copy:
src: files/prometheus.yml
dest: ~/prometheus.yml
owner: root
group: root
mode: '0644'
- name: Deploy myappstack stack from compose file - name: Deploy myappstack stack from compose file
community.docker.docker_stack: community.docker.docker_stack:
name: myappstack name: myappstack
state: present state: present
prune: true prune: true
compose: compose:
- "{{ lookup('file', 'files/docker-compose.yml') | from_yaml }}" - "{{ lookup('file', 'files/docker-compose.yml') | from_yaml }}"

33
vagrant/Vagrantfile vendored
View File

@@ -1,19 +1,26 @@
num_workers = 1 num_workers = 3
nodes = [ nodes = [
{ {
hostname: 'swarm-master', hostname: 'swarm-master',
ip: '192.168.56.10', ip: '192.168.56.10',
ram: 256, ram: 1024,
cpus: 1, cpus: 1,
groups: ['swarm_master'], groups: ['swarm_master']
}, },
{
hostname: 'swarm-worker-storage',
ip: '192.168.56.11',
ram: 512,
cpus: 1,
groups: ['swarm_workers','storage']
}
] ]
(1..num_workers).each do |i| (1..num_workers).each do |i|
nodes << { nodes << {
hostname: "swarm-worker-#{i}", hostname: "swarm-worker-#{i}",
ip: "192.168.56.#{10 + i}", ip: "192.168.56.#{11 + i}",
ram: 256, ram: 256,
cpus: 1, cpus: 1,
groups: ['swarm_workers'] groups: ['swarm_workers']
@@ -49,11 +56,11 @@ Vagrant.configure('2') do |config|
# node_config.vm.box = 'generic/archlinux64' # node_config.vm.box = 'generic/archlinux64'
# node_config.vm.box_version = "20250415.336224" # 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| node_config.vm.provider 'virtualbox' do |vb|
vb.name = node[:hostname] vb.name = node[:hostname]
vb.memory = node[:ram] vb.memory = node[:ram]
vb.cpus = node[:cpus] vb.cpus = node[:cpus]
end end
end end
end end

View File

@@ -3,15 +3,7 @@
become: true become: true
tasks: tasks:
# write hello world to a file in the home directory - name: Placeholder
- name: write hello shell: echo 'We don\'t use the setup playbook as they run in sequence. Better to run on the whole inventory after.'
copy:
content: "hello ansible!"
dest: /home/vagrant/hello.txt
mode: 0644
become: true
- name: Echo hello
shell: echo 'hello ansible!'
args: args:
chdir: $HOME chdir: $HOME