routing working
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ charts/
|
||||
# Keys
|
||||
keys/
|
||||
old/
|
||||
.env.yml
|
||||
4
Makefile
4
Makefile
@@ -15,7 +15,7 @@ ansible-workers:
|
||||
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
|
||||
make ansible-master && make ansible-workers && make ansible-stack
|
||||
|
||||
setup-keys:
|
||||
mkdir -p ./keys
|
||||
@@ -32,3 +32,5 @@ 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"
|
||||
service-portainer-restart:
|
||||
cd vagrant && vagrant ssh swarm-master -c "docker service rm portainer_portainer"
|
||||
|
||||
@@ -19,7 +19,22 @@ services:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
replicas: 1
|
||||
|
||||
# db:
|
||||
# image: postgres
|
||||
# restart: always
|
||||
# environment:
|
||||
# POSTGRES_PASSWORD: example
|
||||
# volumes:
|
||||
# - pgdata:/var/lib/postgresql/data
|
||||
# networks:
|
||||
# - portainer_net
|
||||
# deploy:
|
||||
# placement:
|
||||
# constraints:
|
||||
# - node.role == manager
|
||||
# restart_policy:
|
||||
# condition: on-failure
|
||||
# replicas: 1
|
||||
volumes:
|
||||
portainer_data:
|
||||
external: true
|
||||
|
||||
@@ -12,3 +12,5 @@ docker_packages_state: present
|
||||
docker_users:
|
||||
- vagrant
|
||||
|
||||
# docker_hub_username: "{{ lookup('env_file', '.env', 'DOCKER_HUB_USERNAME') }}"
|
||||
# docker_hub_password: "{{ lookup('env_file', '.env', 'DOCKER_HUB_PASSWORD') }}"
|
||||
@@ -1,3 +1,14 @@
|
||||
|
||||
- name: Load environment variables from .env file
|
||||
include_vars:
|
||||
file: .env.yml
|
||||
name: env_vars
|
||||
|
||||
- name: Set Docker Hub credentials from env vars
|
||||
set_fact:
|
||||
docker_hub_username: "{{ env_vars.DOCKER_HUB_USERNAME }}"
|
||||
docker_hub_password: "{{ env_vars.DOCKER_HUB_PASSWORD }}"
|
||||
|
||||
- name: Check memory and swap usage
|
||||
command: free -m
|
||||
register: memory_info
|
||||
@@ -7,6 +18,14 @@
|
||||
ansible.builtin.apt:
|
||||
update_cache: yes
|
||||
|
||||
- name: install packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- jq
|
||||
- vim
|
||||
- curl
|
||||
state: present
|
||||
|
||||
- name: Ensure Python pip is installed
|
||||
package:
|
||||
name: python3-pip
|
||||
@@ -35,3 +54,38 @@
|
||||
until: docker_service.status.ActiveState == "active"
|
||||
retries: 10
|
||||
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
|
||||
community.docker.docker_login:
|
||||
username: "{{ docker_hub_username }}"
|
||||
password: "{{ docker_hub_password }}"
|
||||
# config_path: "/home/vagrant/.docker"
|
||||
reauth: true
|
||||
become_user: vagrant
|
||||
when: docker_hub_username is defined and docker_hub_password is defined
|
||||
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
|
||||
@@ -33,6 +33,7 @@
|
||||
state: present
|
||||
advertise_addr: "{{ ansible_eth1.ipv4.address }}"
|
||||
listen_addr: "{{ ansible_eth1.ipv4.address }}"
|
||||
|
||||
- name: print listen addr
|
||||
debug:
|
||||
msg: "{{ ansible_eth1.ipv4.address }}"
|
||||
|
||||
@@ -20,27 +20,28 @@
|
||||
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 }}
|
||||
# - 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 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'] }}
|
||||
# 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
|
||||
# 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] }}...
|
||||
# Join token (first 10 chars): {{ worker_token[:10] }}...
|
||||
|
||||
- name: Gather master facts
|
||||
ansible.builtin.setup:
|
||||
@@ -48,21 +49,23 @@
|
||||
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: 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: Add nodes
|
||||
community.docker.docker_swarm:
|
||||
state: join
|
||||
join_token: "{{ worker_token }}"
|
||||
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 }}"
|
||||
listen_addr: "{{ ansible_eth1.ipv4.address }}:2377"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
- name: Deploy Portainer stack from compose file
|
||||
community.docker.docker_stack:
|
||||
name: portainer
|
||||
name: mgmt
|
||||
state: present
|
||||
compose:
|
||||
- "{{ lookup('file', 'files/docker-base-stack.yml') | from_yaml }}"
|
||||
5
test-usage/Makefile
Normal file
5
test-usage/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
deploy:
|
||||
ansible-playbook -i ../vagrant/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml
|
||||
|
||||
watch:
|
||||
find . -type f | entr -p make deploy
|
||||
6
test-usage/ansible.cfg
Normal file
6
test-usage/ansible.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
[defaults]
|
||||
host_key_checking=False
|
||||
# stdout_callback = minimal
|
||||
color = true
|
||||
interpreter_python = /usr/bin/python3.9
|
||||
deprecation_warnings=False
|
||||
129
test-usage/files/docker-compose.yml
Normal file
129
test-usage/files/docker-compose.yml
Normal file
@@ -0,0 +1,129 @@
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.4
|
||||
|
||||
networks:
|
||||
# Connect to the 'traefik_proxy' overlay network for inter-container communication across nodes
|
||||
- traefik_proxy
|
||||
|
||||
ports:
|
||||
# Expose Traefik's entry points to the Swarm
|
||||
# Swarm requires the long syntax for ports.
|
||||
- target: 80 # Container port (Traefik web entry point)
|
||||
published: 80 # Host port exposed on the nodes
|
||||
protocol: tcp
|
||||
# 'host' mode binds directly to the node's IP where the task runs.
|
||||
# 'ingress' mode uses Swarm's Routing Mesh (load balances across nodes).
|
||||
# Choose based on your load balancing strategy. 'host' is often simpler if using an external LB.
|
||||
mode: host
|
||||
- target: 443 # Container port ( Traefik websecure entry point)
|
||||
published: 443 # Host port
|
||||
protocol: tcp
|
||||
mode: host
|
||||
- target: 8080 # Container port (Traefik web entry point)
|
||||
published: 8080 # Host port exposed on the nodes
|
||||
protocol: tcp
|
||||
mode: host
|
||||
|
||||
volumes:
|
||||
# Mount the Docker socket for the Swarm provider
|
||||
# This MUST be run from a manager node to access the Swarm API via the socket.
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro # Swarm API socket
|
||||
# - ./certs:/certs:ro
|
||||
# - ./dynamic:/dynamic:ro
|
||||
|
||||
# Traefik Static configuration via command-line arguments
|
||||
command:
|
||||
# HTTP EntryPoint
|
||||
- "--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
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
- "--entrypoints.websecure.http.tls=true"
|
||||
|
||||
# Attach dynamic TLS file
|
||||
# - "--providers.file.filename=/dynamic/tls.yaml"
|
||||
|
||||
# Providers
|
||||
|
||||
# Enable the Docker Swarm provider (instead of Docker provider)
|
||||
- "--providers.swarm.endpoint=unix:///var/run/docker.sock"
|
||||
|
||||
# Watch for Swarm service changes (requires socket access)
|
||||
- "--providers.swarm.watch=true"
|
||||
|
||||
# Recommended: Don't expose services by default; require explicit labels
|
||||
- "--providers.swarm.exposedbydefault=false"
|
||||
|
||||
# Specify the default network for Traefik to connect to services
|
||||
- "--providers.swarm.network=myappstack_traefik_proxy"
|
||||
|
||||
# API & Dashboard
|
||||
- "--api.dashboard=true" # Enable the dashboard
|
||||
- "--api.insecure=true" # Explicitly disable insecure API mod
|
||||
|
||||
# Observability
|
||||
- "--log.level=INFO" # Set the Log Level e.g INFO, DEBUG
|
||||
- "--accesslog=true" # Enable Access Logs
|
||||
- "--metrics.prometheus=true" # Enable Prometheus
|
||||
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
|
||||
# Placement constraints restrict where Traefik tasks can run.
|
||||
# Running on manager nodes is common for accessing the Swarm API via the socket.
|
||||
constraints:
|
||||
- node.role == manager
|
||||
|
||||
# Traefik Dynamic configuration via labels
|
||||
# In Swarm, labels on the service definition configure Traefik routing for that service.
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
||||
# Dashboard router
|
||||
- "traefik.http.routers.dashboard.rule=PathPrefix(`/d2`)"
|
||||
- "traefik.http.routers.dashboard.entrypoints=web"
|
||||
- "traefik.http.middlewares.dashboard-stripprefix.stripprefix.prefixes=/d2"
|
||||
- "traefik.http.routers.dashboard.middlewares=dashboard-stripprefix"
|
||||
- "traefik.http.routers.dashboard.service=api@internal"
|
||||
- "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
|
||||
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
|
||||
|
||||
# Deploy the Whoami application
|
||||
whoami:
|
||||
image: traefik/whoami
|
||||
ports:
|
||||
- "8081:80"
|
||||
networks:
|
||||
- traefik_proxy
|
||||
deploy:
|
||||
labels:
|
||||
# Enable Service discovery for Traefik
|
||||
- "traefik.enable=true"
|
||||
# Define the Whoami router rule - match root path
|
||||
- "traefik.http.routers.whoami.rule=PathPrefix(`/whoami`)"
|
||||
# Expose Whoami on the HTTP entrypoint
|
||||
- "traefik.http.routers.whoami.entrypoints=web"
|
||||
- "traefik.http.middlewares.whoami-stripprefix.stripprefix.prefixes=/whoami"
|
||||
- "traefik.http.routers.whoami.middlewares=whoami-stripprefix"
|
||||
# Expose the whoami port number to Traefik
|
||||
- "traefik.http.services.whoami.loadbalancer.server.port=80"
|
||||
|
||||
# Define the overlay network for Swarm
|
||||
networks:
|
||||
traefik_proxy:
|
||||
driver: overlay
|
||||
# attachable: true
|
||||
14
test-usage/playbook.yml
Normal file
14
test-usage/playbook.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- hosts: swarm_master
|
||||
become: true
|
||||
|
||||
roles:
|
||||
|
||||
tasks:
|
||||
- name: Deploy myappstack stack from compose file
|
||||
community.docker.docker_stack:
|
||||
name: myappstack
|
||||
state: present
|
||||
prune: true
|
||||
compose:
|
||||
- "{{ lookup('file', 'files/docker-compose.yml') | from_yaml }}"
|
||||
13
vagrant/Vagrantfile
vendored
13
vagrant/Vagrantfile
vendored
@@ -1,7 +1,13 @@
|
||||
num_workers = 7
|
||||
num_workers = 1
|
||||
|
||||
nodes = [
|
||||
{ hostname: 'swarm-master', ip: '192.168.56.10', ram: 256, cpus: 1, groups: ['swarm_master'] }
|
||||
{
|
||||
hostname: 'swarm-master',
|
||||
ip: '192.168.56.10',
|
||||
ram: 256,
|
||||
cpus: 1,
|
||||
groups: ['swarm_master'],
|
||||
},
|
||||
]
|
||||
|
||||
(1..num_workers).each do |i|
|
||||
@@ -15,6 +21,8 @@ nodes = [
|
||||
end
|
||||
|
||||
Vagrant.configure('2') do |config|
|
||||
# config.vbguest.auto_update = true
|
||||
|
||||
groups = {}
|
||||
nodes.each do |node|
|
||||
node[:groups].each do |group|
|
||||
@@ -25,6 +33,7 @@ Vagrant.configure('2') do |config|
|
||||
|
||||
config.vm.provision 'ansible' do |ansible|
|
||||
ansible.playbook = 'setup.yml'
|
||||
ansible.config_file = 'ansible.cfg'
|
||||
ansible.groups = groups
|
||||
|
||||
# ansible.verbose = true
|
||||
|
||||
6
vagrant/ansible.cfg
Normal file
6
vagrant/ansible.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
[defaults]
|
||||
host_key_checking=False
|
||||
# stdout_callback = minimal
|
||||
color = true
|
||||
interpreter_python = /usr/bin/python3.9
|
||||
deprecation_warnings=False
|
||||
Reference in New Issue
Block a user