Working setup
This commit is contained in:
2
Makefile
2
Makefile
@@ -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
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Vagrant Swarm
|
||||||
|
|
||||||
|
Create a cluster of nodes with vagrant and set up docker swarm with ansible.
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
@@ -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 }}"
|
|
||||||
@@ -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] }}"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
# Basic‑auth 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
|
||||||
|
|||||||
@@ -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
33
vagrant/Vagrantfile
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user