132 lines
3.4 KiB
Markdown
132 lines
3.4 KiB
Markdown
# Topology
|
|
|
|
Every VM is a Docker host. Proxmox and Cloud-Init only create the machine and
|
|
bootstrap Ansible; service placement is controlled by inventory.
|
|
|
|
## Edge VM
|
|
|
|
The edge VM runs:
|
|
|
|
- Docker
|
|
- Traefik
|
|
- authentik IAM
|
|
|
|
It publishes Traefik entrypoints on host ports `80` and `443`. authentik can run
|
|
behind the same local Traefik instance by setting:
|
|
|
|
```yaml
|
|
nbops_service_routing_mode: traefik
|
|
authentik_domain: auth.example.invalid
|
|
```
|
|
|
|
## Downstream VMs
|
|
|
|
Downstream VMs also run Docker and normally run an internal Traefik instance.
|
|
Application containers route through that local Traefik using Docker labels and
|
|
the shared Docker proxy network.
|
|
|
|
```yaml
|
|
nbops_roles:
|
|
- base
|
|
- ssh
|
|
- ufw
|
|
- updates
|
|
- docker
|
|
- traefik
|
|
- gitea
|
|
- immich
|
|
|
|
nbops_service_routing_mode: traefik
|
|
nbops_traefik_entrypoint: web
|
|
nbops_traefik_tls: false
|
|
```
|
|
|
|
In this mode application roles do not publish their HTTP ports. They render
|
|
Traefik labels and join `nbops_proxy_network`, which defaults to `proxy`.
|
|
|
|
Only Traefik entrypoints should be exposed on the downstream host firewall. Use
|
|
`traefik_bind_address` to bind those entrypoints to the VM's internal address.
|
|
|
|
For central edge routing, the edge Traefik uses the file provider to route
|
|
machine-to-machine traffic to each downstream VM's internal Traefik entrypoint.
|
|
The internal Traefik then routes to applications using Docker labels. This keeps
|
|
container discovery local to the VM and gives the edge-to-internal leg a stable
|
|
place for future mTLS.
|
|
|
|
Edge VM:
|
|
|
|
```yaml
|
|
nbops_roles:
|
|
- base
|
|
- ssh
|
|
- ufw
|
|
- updates
|
|
- docker
|
|
- traefik
|
|
|
|
traefik_docker_provider_enabled: false
|
|
traefik_file_provider_enabled: true
|
|
traefik_dynamic_inventory_group: nbops
|
|
```
|
|
|
|
Downstream VM:
|
|
|
|
```yaml
|
|
nbops_service_routing_mode: traefik
|
|
nbops_traefik_entrypoint: web
|
|
nbops_traefik_tls: false
|
|
|
|
traefik_bind_address: "10.0.10.25"
|
|
traefik_publish_entrypoints: true
|
|
|
|
nbops_traefik_file_routes:
|
|
- name: jellyfin
|
|
domain: jellyfin.example.invalid
|
|
scheme: http
|
|
port: 80
|
|
- name: gitea
|
|
domain: git.example.invalid
|
|
scheme: http
|
|
port: 80
|
|
```
|
|
|
|
When the play runs against the edge VM, Traefik renders
|
|
`dynamic/http-services.yml` from `nbops_traefik_file_routes` declared across the
|
|
inventory group. Each route targets `ansible_host` for that inventory host by
|
|
default. Set `target_host` for a different VM address, or set `url` to provide
|
|
the complete upstream URL.
|
|
|
|
For future mTLS between edge Traefik and internal Traefik, routes can reference a
|
|
Traefik `serversTransport`:
|
|
|
|
```yaml
|
|
nbops_traefik_file_routes:
|
|
- name: jellyfin
|
|
domain: jellyfin.example.invalid
|
|
scheme: https
|
|
port: 443
|
|
servers_transport: internal-mtls
|
|
|
|
traefik_dynamic_servers_transports:
|
|
- name: internal-mtls
|
|
server_name: apps-01.example.internal
|
|
root_cas:
|
|
- /etc/pki/internal/certs/ca.crt
|
|
certificates:
|
|
- cert_file: /etc/pki/internal/certs/edge.crt
|
|
key_file: /etc/pki/internal/private/edge.key
|
|
```
|
|
|
|
## Routing Modes
|
|
|
|
Application roles support:
|
|
|
|
- `host`: publish application ports directly and open those ports in UFW.
|
|
- `traefik`: do not publish HTTP ports; attach to Traefik and render labels.
|
|
- `traefik_file`: publish a service port without labels. This is available for
|
|
exceptional direct edge-to-app routes, but the preferred multi-VM topology is
|
|
edge Traefik -> internal Traefik -> application.
|
|
|
|
Gitea is special: HTTP can be routed through Traefik while SSH remains published
|
|
with `gitea_publish_ssh: true`.
|