From c197f28013211e9ff770d50ef2cb12b559a04682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20D=C3=A9siles?= <1536672+cdesiles@users.noreply.github.com> Date: Sun, 21 Dec 2025 22:25:11 +0100 Subject: [PATCH] fix: using a bridge to link podman pods to host s services --- inventory/host_vars/example.yml | 16 ++++-- roles/net-config/tasks/main.yml | 56 +++++++++---------- roles/net-config/templates/systemd.netdev.j2 | 6 ++ roles/net-config/templates/systemd.network.j2 | 5 ++ roles/net-persist/tasks/main.yml | 55 ++++++++++-------- roles/networking/tasks/main.yml | 5 ++ roles/postgres/README.md | 15 +++-- roles/valkey/README.md | 11 +++- 8 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 roles/net-config/templates/systemd.netdev.j2 diff --git a/inventory/host_vars/example.yml b/inventory/host_vars/example.yml index 59418be..fcb70d5 100644 --- a/inventory/host_vars/example.yml +++ b/inventory/host_vars/example.yml @@ -14,6 +14,10 @@ network_interfaces: - name: lan1 type: ethernet mac_address: 0a:3f:5b:1c:d2:e4 + - name: podman-gw + type: bridge + ipv4: + address: "{{ podman_gw_gateway }}/10" # NTP servers configuration # ------------------------- @@ -115,24 +119,24 @@ nfs_bind_addresses: # Podman configuration # -------------------- -podman_external_networks: - - name: immich - subnet: 172.20.0.0/16 - gateway: 172.20.0.1 +podman_gw_gateway: 100.64.0.1 +podman_gw_subnet: 100.64.0.0/10 # PostgreSQL configuration # ------------------------ postgres_admin_password: "{{ vault_postgres_admin_password }}" -postgres_bind: "127.0.0.1" +postgres_bind: "127.0.0.1,{{ podman_gw_gateway }}" # Comma-separated for PostgreSQL postgres_firewall_allowed_sources: - 127.0.0.0/8 + - "{{ podman_gw_subnet }}" # Valkey configuration # -------------------- valkey_admin_password: "{{ vault_valkey_admin_password }}" -valkey_bind: "127.0.0.1" +valkey_bind: "127.0.0.1 {{ podman_gw_gateway }}" # Space-separated for Valkey valkey_firewall_allowed_sources: - 127.0.0.0/8 + - "{{ podman_gw_subnet }}" # Valkey ACL users valkey_acl_users: diff --git a/roles/net-config/tasks/main.yml b/roles/net-config/tasks/main.yml index b97d481..3e52d99 100644 --- a/roles/net-config/tasks/main.yml +++ b/roles/net-config/tasks/main.yml @@ -1,36 +1,34 @@ --- - name: Check if the interface ipv4 address is defined + ansible.builtin.debug: + msg: "Warning: iface {{ interface.name }} has no defined ipv4 address, skipping configuration" when: interface.ipv4.address is not defined +- name: Process interface configuration + when: interface.ipv4.address is defined block: - - ansible.builtin.debug: - msg: "Warning: iface {{ interface.name }} has no defined ipv4 address, skipping configuration" - - name: Skip net-config role for {{ interface.name }} - ansible.builtin.meta: end_play -- name: Check if the interface is already configured - ansible.builtin.stat: - path: /etc/systemd/network/20-{{ interface.name }}.network - register: network_file + - name: Create systemd-netdev file for virtual interface + when: + - interface.type is defined + - interface.type != 'ethernet' + ansible.builtin.template: + src: systemd.netdev.j2 + dest: /etc/systemd/network/10-{{ interface.name }}.netdev + owner: root + group: root + mode: "0644" + register: netdev_result -- name: What patch is needed - ansible.builtin.debug: - msg: >- - {%- if network_file.stat.exists == true -%} - iface {{ interface.name }} is already configured, no action needed. - {%- else -%} - iface {{ interface.name }} will be configured. - {%- endif -%} + - name: Create systemd-network configuration file + ansible.builtin.template: + src: systemd.network.j2 + dest: /etc/systemd/network/20-{{ interface.name }}.network + owner: root + group: root + mode: "0644" + register: network_result -- name: Create systemd-network link file - when: network_file.stat.exists != true - ansible.builtin.template: - src: systemd.network.j2 - dest: /etc/systemd/network/20-{{ interface.name }}.network - owner: root - group: root - mode: "0644" - -- name: Notify a reload is required - ansible.builtin.set_fact: - network_reload_required: true - when: network_file.stat.exists != true + - name: Notify a reload is required + ansible.builtin.set_fact: + network_reload_required: true + when: netdev_result is changed or network_result is changed diff --git a/roles/net-config/templates/systemd.netdev.j2 b/roles/net-config/templates/systemd.netdev.j2 new file mode 100644 index 0000000..e8e616d --- /dev/null +++ b/roles/net-config/templates/systemd.netdev.j2 @@ -0,0 +1,6 @@ +# {{ ansible_managed }} +# systemd.netdev(5) + +[NetDev] +Name={{ interface.name }} +Kind={{ interface.type }} diff --git a/roles/net-config/templates/systemd.network.j2 b/roles/net-config/templates/systemd.network.j2 index 1a26fc2..cdd9764 100644 --- a/roles/net-config/templates/systemd.network.j2 +++ b/roles/net-config/templates/systemd.network.j2 @@ -11,9 +11,14 @@ RouteMetric={{ interface.ipv4.metric }} {% endif %} [Network] +{% if interface.type is defined and interface.type == 'bridge' %} +ConfigureWithoutCarrier=yes +{% endif %} +{% if interface.ipv4.nameservers is defined %} {% for dns in interface.ipv4.nameservers %} DNS={{ dns }} {% endfor %} +{% endif %} {% if interface.ipv4.gateway is defined %} [Route] diff --git a/roles/net-persist/tasks/main.yml b/roles/net-persist/tasks/main.yml index 2437991..1a1d0a5 100644 --- a/roles/net-persist/tasks/main.yml +++ b/roles/net-persist/tasks/main.yml @@ -1,28 +1,35 @@ --- -- name: "Check {{ interface.name }} ({{ interface.mac_address }}) rule" - ansible.builtin.set_fact: - interface_original_name: "{{ ansible_facts.interfaces | select('in', ansible_facts) | map('extract', ansible_facts) | selectattr('pciid', 'defined') | selectattr('macaddress', - 'equalto', interface.mac_address) | map(attribute='device') | first }}" - -- name: What patch is needed +- name: Skip net-persist for non-ethernet interfaces ansible.builtin.debug: - msg: >- - {%- if interface_original_name != interface.name -%} - iface {{ interface_original_name }} ({{ interface.mac_address }}) will be patched to {{ interface.name }}. - {%- else -%} - iface {{ interface.name }} is already set, no action needed. - {%- endif -%} + msg: "Skipping net-persist for {{ interface.name }} (type: {{ interface.type }})" + when: interface.type is defined and interface.type != 'ethernet' -- name: Create persistent-net link file - when: interface_original_name != interface.name - ansible.builtin.template: - src: persistent-net.link.j2 - dest: /etc/systemd/network/10-persistent-net-{{ interface.name }}.link - owner: root - group: root - mode: "0644" +- name: Process ethernet interface persistence + when: interface.type is not defined or interface.type == 'ethernet' + block: + - name: "Check {{ interface.name }} ({{ interface.mac_address }}) rule" + ansible.builtin.set_fact: + interface_original_name: "{{ ansible_facts.interfaces | select('in', ansible_facts) | map('extract', ansible_facts) | selectattr('pciid', 'defined') | selectattr('macaddress', 'equalto', interface.mac_address) | map(attribute='device') | first }}" -- name: Notify a reboot is required - ansible.builtin.set_fact: - reboot_required: true - when: interface_original_name != interface.name + - name: What patch is needed + ansible.builtin.debug: + msg: >- + {%- if interface_original_name != interface.name -%} + iface {{ interface_original_name }} ({{ interface.mac_address }}) will be patched to {{ interface.name }}. + {%- else -%} + iface {{ interface.name }} is already set, no action needed. + {%- endif -%} + + - name: Create persistent-net link file + when: interface_original_name != interface.name + ansible.builtin.template: + src: persistent-net.link.j2 + dest: /etc/systemd/network/10-persistent-net-{{ interface.name }}.link + owner: root + group: root + mode: "0644" + + - name: Notify a reboot is required + ansible.builtin.set_fact: + reboot_required: true + when: interface_original_name != interface.name diff --git a/roles/networking/tasks/main.yml b/roles/networking/tasks/main.yml index d0bfa66..f425964 100644 --- a/roles/networking/tasks/main.yml +++ b/roles/networking/tasks/main.yml @@ -1,4 +1,9 @@ --- +- name: Initialize network management variables + ansible.builtin.set_fact: + reboot_required: false + network_reload_required: false + - name: Setup persistent network interface(s) ansible.builtin.include_role: name: net-persist diff --git a/roles/postgres/README.md b/roles/postgres/README.md index 3312eb6..79676ba 100644 --- a/roles/postgres/README.md +++ b/roles/postgres/README.md @@ -22,16 +22,19 @@ See `CLAUDE.md` for detailed architecture documentation. ## Container Access -For containers to reach PostgreSQL, configure in inventory: +For containers to reach PostgreSQL: +PostgreSQL binds to `127.0.0.1` by default (secure, localhost-only). + +Containers can reach PostgreSQL via Pasta's `--map-host-loopback` feature, which routes container's `127.0.0.1` to the host's `127.0.0.1`. + +In docker-compose files, use: ```yaml -postgres_bind: "127.0.0.1,{{ podman_subnet_gateway }}" -postgres_firewall_allowed_sources: - - 127.0.0.0/8 - - "{{ podman_subnet }}" +extra_hosts: + - "postgres.local:127.0.0.1" ``` -Containers use `host.containers.internal` as hostname. +No additional bind addresses or firewall rules needed! ## Logging Backends diff --git a/roles/valkey/README.md b/roles/valkey/README.md index 18bb140..2e063f8 100644 --- a/roles/valkey/README.md +++ b/roles/valkey/README.md @@ -53,11 +53,18 @@ Service users must be registered via the `valkey_acl_users` list. See the ACL Co #### Container Access -For containers to access Valkey, set `valkey_bind` to include the Podman gateway: +Valkey binds to `127.0.0.1` by default (secure, localhost-only). + +Containers can reach Valkey via Pasta's `--map-host-loopback` feature, which routes container's `127.0.0.1` to the host's `127.0.0.1`. + +In docker-compose files, use: ```yaml -valkey_bind: "127.0.0.1 {{ podman_subnet_gateway }}" +extra_hosts: + - "host.containers.internal:127.0.0.1" ``` +No additional bind addresses needed! + **System Requirements:** This role automatically configures kernel parameters (`vm.overcommit_memory=1`) and transparent hugepage settings ## Dependencies