Skip to content

Isolate container services into dedicated bridge networks - #26

Open
pablomh wants to merge 6 commits into
masterfrom
foremanctl_networks_rebase
Open

Isolate container services into dedicated bridge networks#26
pablomh wants to merge 6 commits into
masterfrom
foremanctl_networks_rebase

Conversation

@pablomh

@pablomh pablomh commented Apr 23, 2026

Copy link
Copy Markdown
Owner

Rebased version of #24 with clean commit history.

Changes

  • Add reusable deploy_network role for Podman network management
  • Isolate containers into dedicated bridge networks (foreman-db, foreman-cache, foreman-app, foreman-proxy)
  • Mount /etc/hosts read-only into foreman-proxy container for managed host resolution
  • Rename foreman-proxy-net to foreman-proxy for naming consistency
  • Issue dedicated TLS certificate for Candlepin container hostname
  • Use host networking in development environment
  • Document container networking architecture
  • Add /etc/hosts resolution test for the proxy container

pablomh and others added 5 commits April 24, 2026 00:50
Introduces the deploy_network role, which wraps
containers.podman.podman_network to create a named bridge network with
configurable properties: internal (no external routing), isolate (no
cross-network packet forwarding), IPv6, subnet, gateway, and DNS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace host networking with four named Podman bridge networks:

- foreman-db (internal, isolated): PostgreSQL and its clients
- foreman-cache (internal, isolated): Redis and its clients
- foreman-app: application layer — Foreman, Candlepin, Pulp, httpd
- foreman-proxy-net: Foreman and the smart proxy

Services reach each other by container DNS name instead of localhost.
Per-service notes:

- postgresql: also accessible via a Unix socket bind-mounted at
  /var/run/postgresql, used by Ansible's community.postgresql modules
  during deployment so no TCP port needs to be published to the host.
- redis: publishes no ports; clients reach it by DNS name on
  foreman-cache.
- candlepin: Tomcat binds to 0.0.0.0 so that other containers on the
  bridge network can reach it via its DNS name.
- migration containers (foreman db:migrate, pulp migrations): attached
  to foreman-db when the database is internal; switched to foreman-app
  when the database is external, because foreman-db uses internal: true
  which removes the default gateway, making it impossible for containers
  on that network to reach an external database host.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The development setup runs the Foreman Rails process directly on the
host rather than in a container, so it cannot resolve container bridge
DNS names such as postgresql or candlepin. Keeping host networking for
all services in the devel environment means every service remains
reachable on localhost as before, without requiring per-service URL
overrides for the Rails process.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
foreman-certs generates certificates only for localhost and the server
FQDN. Now that Foreman connects to Candlepin via the bridge DNS name
"candlepin", TLS hostname validation fails against those certificates.
A dedicated certificate with SAN=candlepin, signed by the installer
CA, is generated using the openssl CLI (consistent with the rest of
the codebase).

The certificate validity is set to 7300 days (20 years), matching the
default used by puppet-certs (theforeman/puppet-certs manifests/init.pp
$expiration parameter). The signing step runs on every deployment to
ensure the certificate is always freshly dated, consistent with how
foreman-certs handles the other installer certificates.

The localhost certificate previously used by Candlepin's Tomcat is now
unused and removed:

- "localhost" dropped from certificates_hostnames — the certificates
  role no longer generates the cert.
- localhost_key / localhost_certificate removed from
  default_certificates.yml and installer_certificates.yml.

The healthcheck is updated to validate the new certificate instead of
skipping verification with --insecure. --resolve candlepin:23443:127.0.0.1
forces the connection to the loopback so it works in both bridge
networking (where other containers reach Candlepin by DNS name) and
host networking (where "candlepin" would not resolve via container DNS).

Tests are updated to route connectivity checks through the foreman
container (which shares the same bridge network as candlepin), to verify
against the new certificate, and to check candlepin_certificate expiry
instead of the now-removed localhost_certificate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds docs/deployment.md with a description of the four bridge
networks introduced by this series, their properties (internal,
isolate), which containers are attached to each, and the rationale
for the port publishing decisions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@pablomh
pablomh force-pushed the foremanctl_networks_rebase branch 2 times, most recently from 8a11368 to 40812f3 Compare April 26, 2026 17:05
- Rename foreman-proxy-net to foreman-proxy for naming consistency
  with foreman-app, foreman-db, foreman-cache
- Mount /etc/hosts read-only into the proxy container so managed hosts
  defined only in /etc/hosts are resolvable (aardvark-dns does not
  read the host's /etc/hosts file)
- Add test verifying both DNS and /etc/hosts resolution from inside
  the proxy container
- Update documentation with /etc/hosts rationale and network rename

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pablomh
pablomh force-pushed the foremanctl_networks_rebase branch from 40812f3 to 39ff569 Compare April 26, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant