incus-contrib/notes/mermaid-test.md

7.4 KiB

Mermaid Diagram Rendering Test

Style reference for all mermaid diagrams in this repository. See individual guide files for the actual diagrams in use.


Style Guidelines

All diagrams in this project follow a consistent style based on semantic color-coding by element role, color-blind-safe colors (Okabe-Ito derived), and minimal text per node.

Color palette (5 semantic colors + 1 neutral):

Role Color Hex Node shape
Cluster node / VM Teal #009E73 Rectangle ["..."]
Instance / container Sky blue #56B4E9 Rectangle ["..."]
Network infrastructure Blue #0072B2 Rounded ("...")
Load balancer / proxy Amber #E69F00 Rectangle ["..."]
Management / control Mauve #CC79A7 Rectangle ["..."]
External / entry point Light gray #f5f5f5 Stadium (["..."])

Subgraph fills: light tint of the dominant role color, darker stroke.

Rules:

  • Max 2 lines of text per node (name + one detail). Move specs to tables.
  • Top-down (TD) for hierarchies; left-right (LR) for lateral/peer relationships.
  • Solid arrows (-->) for data/traffic; dashed (-.->) for control/management.
  • Use classDef for styling, never per-node style statements.
  • No emojis or unicode symbols in labels (renderer compatibility).
  • Edge labels: 1-3 words max, only when relationship isn't obvious.
  • Use <br/> for line breaks in node labels (not \n — Gitea renders that literally).

Test 1: HAProxy Architecture

Original: notes/haproxy-guide.md

flowchart TD
    client(["Client / LAN"])
    vip["VIP 192.168.103.200"]
    ovnlb("OVN Load Balancer")
    ha1["HAProxy 01<br/>10.10.10.50"]
    ha2["HAProxy 02<br/>10.10.10.51"]
    ng1["nginx-01 · .60"]
    ng2["nginx-02 · .61"]
    ng3["nginx-03 · .62"]

    client --> vip
    vip --> ovnlb
    ovnlb --> ha1 & ha2
    ha1 & ha2 --> ng1 & ng2 & ng3

    classDef external fill:#f5f5f5,color:#333,stroke:#999
    classDef network fill:#0072B2,color:#fff,stroke:#005a8e
    classDef lb fill:#E69F00,color:#fff,stroke:#b87d00
    classDef instance fill:#56B4E9,color:#fff,stroke:#3a8fbf

    class client external
    class vip,ovnlb network
    class ha1,ha2 lb
    class ng1,ng2,ng3 instance

Test 2: Bridge Topology

Original: notes/networking-guide.md

flowchart TD
    subgraph node1["Node 1 · net-node-01"]
        c1["c1 · .202"] & c2["c2 · .40"] --- br1("incusbr0<br/>10.0.0.1/24")
        br1 --> nat1["NAT · 192.168.1.209"]
    end

    subgraph node2["Node 2 · net-node-02"]
        c3["c3 · .52"] --- br2("incusbr0<br/>10.0.0.1/24")
        br2 --> nat2["NAT · 192.168.1.150"]
    end

    nat1 & nat2 --- lan(("LAN<br/>192.168.1.0/24"))

    classDef instance fill:#56B4E9,color:#fff,stroke:#3a8fbf
    classDef network fill:#0072B2,color:#fff,stroke:#005a8e
    classDef node fill:#009E73,color:#fff,stroke:#007a5e

    class c1,c2,c3 instance
    class br1,br2,lan network
    class nat1,nat2 node

    style node1 fill:#e6f5f0,stroke:#009E73
    style node2 fill:#e6f5f0,stroke:#009E73

Each node has its own bridge with the same subnet (10.0.0.1/24). The bridges are not connected to each other — cross-node traffic fails.


Test 3: OVN Topology

Original: notes/networking-guide.md

flowchart TD
    subgraph cp["OVN Control Plane"]
        ovnc["ovn-central<br/>NB :6641 · SB :6642"]
    end

    subgraph n1["Node 1 · net-node-01"]
        ctrl1["ovn-controller"] ~~~ ls1
        c1["c1 · .2"] & c2["c2 · .3"] --- ls1("logical switch<br/>10.10.10.0/24")
    end

    subgraph n2["Node 2 · net-node-02"]
        ctrl2["ovn-controller"] ~~~ ls2
        c3["c3 · .4"] --- ls2("logical switch<br/>10.10.10.0/24")
    end

    subgraph n3["Node 3 · net-node-03"]
        ctrl3["ovn-controller"] ~~~ ls3
        c4["c4 · .5"] --- ls3("logical switch<br/>10.10.10.0/24")
    end

    ovnc -.-> ctrl1 & ctrl2 & ctrl3

    ls1 <-->|Geneve| ls2
    ls2 <-->|Geneve| ls3
    ls1 <-->|Geneve| ls3

    n1 & n2 & n3 --- lan(("LAN<br/>192.168.1.0/24"))

    classDef mgmt fill:#CC79A7,color:#fff,stroke:#a36088
    classDef instance fill:#56B4E9,color:#fff,stroke:#3a8fbf
    classDef network fill:#0072B2,color:#fff,stroke:#005a8e
    classDef node fill:#009E73,color:#fff,stroke:#007a5e

    class ovnc mgmt
    class ctrl1,ctrl2,ctrl3 node
    class c1,c2,c3,c4 instance
    class ls1,ls2,ls3,lan network

    style cp fill:#f5e6f0,stroke:#CC79A7
    style n1 fill:#e6f5f0,stroke:#009E73
    style n2 fill:#e6f5f0,stroke:#009E73
    style n3 fill:#e6f5f0,stroke:#009E73

All instances share a single logical switch connected via Geneve tunnels. The control plane (dashed lines) manages the data plane (solid lines).


Test 4: Geneve Tunnel Mesh

Original: notes/ovn-deep-dive.md

graph LR
    n1(("oc-node-01<br/>.140"))
    n2(("oc-node-02<br/>.141"))
    n3(("oc-node-03<br/>.142"))

    n1 <-->|"Geneve 6081"| n2
    n2 <-->|"Geneve 6081"| n3
    n1 <-->|"Geneve 6081"| n3

    classDef chassis fill:#009E73,color:#fff,stroke:#007a5e

    class n1,n2,n3 chassis

Full mesh — every pair has a Geneve tunnel (UDP 6081) with BFD health monitoring. Tunnel keys are set per-packet from the OVN datapath.


Test 5: OVS Bridge Architecture

Original: notes/ovn-deep-dive.md

flowchart LR
    subgraph provider["incusovn7 · provider bridge"]
        nic["physical NIC"]
        intport["internal port"]
        patch1["patch to br-int"]
    end

    subgraph integration["br-int · integration bridge"]
        veth["instance veth ports"]
        ovntun["Geneve tunnels"]
        patch2["patch to incusovn7"]
    end

    patch1 <-->|"patch port"| patch2

    classDef prov fill:#0072B2,color:#fff,stroke:#005a8e
    classDef integ fill:#009E73,color:#fff,stroke:#007a5e

    class nic,intport,patch1 prov
    class veth,ovntun,patch2 integ

    style provider fill:#e0eef8,stroke:#0072B2
    style integration fill:#e6f5f0,stroke:#009E73

Each IncusOS node runs two OVS bridges. The provider bridge is the on-ramp to the physical network; the integration bridge handles all OVN logical processing (ACLs, NAT, LB, routing).


Test 6: Operations Center Architecture

Original: notes/operations-center-guide.md

flowchart TD
    subgraph proxmox["Proxmox VE Host · i9-13900HK · 64 GiB"]
        subgraph cluster["Incus Cluster · net-prod 10.10.10.0/24"]
            n1["oc-node-01<br/>VMID 400 · .140"]
            n2["oc-node-02<br/>VMID 401 · .141"]
            n3["oc-node-03<br/>VMID 402 · .142"]
        end
        oc["Operations Center<br/>VMID 920 · .120"]
    end

    vmbr0(("VLAN 69<br/>192.168.100.0/22"))
    ext["OVN external IPs<br/>192.168.103.200-210"]

    proxmox --- vmbr0
    cluster -.->|"external gateway"| ext

    classDef node fill:#009E73,color:#fff,stroke:#007a5e
    classDef mgmt fill:#CC79A7,color:#fff,stroke:#a36088
    classDef network fill:#0072B2,color:#fff,stroke:#005a8e

    class n1,n2,n3 node
    class oc mgmt
    class vmbr0,ext network

    style proxmox fill:#f5f5f5,stroke:#999
    style cluster fill:#e6f5f0,stroke:#009E73
Component VMID IP Specs Role
oc-node-01 400 .140 4c/8G/64G Cluster init + OVN central
oc-node-02 401 .141 4c/8G/50G Cluster member
oc-node-03 402 .142 4c/8G/50G Cluster member
oc-server 920 .120 2c/4G/50G Operations Center