mirror of
https://github.com/netbirdio/docs.git
synced 2026-09-09 00:21:26 +02:00
docs: add "Route to a Kubernetes service with HA" how-to (#810)
* docs: add Highly Available Routing Peers use-case page (Kubernetes operator) Add a standalone use-case page under a new Use Cases group in the Kubernetes nav, covering how to run the operator's routing peers in HA: NetworkRouter workloadOverride.replicas (default 3), the auto-created PodDisruptionBudget (maxUnavailable: 1), equal-metric automatic failover, and spreading replicas across failure domains via workloadOverride.podTemplate. Models least-privilege (named destination group + access policy) rather than the All group. * docs: add topology diagrams to HA routing peers page Two SVG topology diagrams: replicas on a single node (single point of failure) and replicas spread one-per-node via topologySpreadConstraints. Embedded in Step 1 and the failure-domains section. * docs: correct HA scheduling framing; drop single-node diagram kube-scheduler spreads a Deployment's replicas across nodes by default (best-effort, via built-in PodTopologySpread defaults). The earlier text/ diagram wrongly implied replicas co-locate by default. Reframe: multi-node spread is the default; topologySpreadConstraints turns it into a guarantee (or spans zones). Remove the single-node diagram (non-HA case, out of scope). * docs: add Friendly DNS names appendix to HA routing peers page Document exposing a service under a cleaner name via a CNAME in a custom zone pointing at the operator's <service>.<namespace>.<zone> record (verified end-to-end). Placed as an appendix for now; can move to a shared location later. * docs: use ScheduleAnyway in spread example; note DoNotSchedule rollout deadlock Multi-node verification: default scheduling already spreads replicas one-per-node; the operator merges workloadOverride.podTemplate.topologySpreadConstraints into the Deployment. DoNotSchedule with replicas == schedulable nodes deadlocks rolling updates (surge pod can't place). Switch the example to ScheduleAnyway (verified clean rollout) and document DoNotSchedule + the node-count/maxSurge caveat for a hard guarantee. * docs: clarify custom-zone records are per-name (no whole-domain shadowing) Verified on the lab: a NetBird custom zone serves only the records you add; other names under the domain fall through to upstream DNS. Reusing a real internal domain for friendly names is safe except for exact-name collisions. * docs: expand into full 'Route to a Kubernetes service' how-to Restructure the HA use-case page into an end-to-end guide covering the whole journey: create the custom DNS zone, groups, and access policy (dashboard) -> deploy HA routing peers (NetworkRouter, replicas:3) -> expose a Service (NetworkResource) -> verify + failover. Generic, human-readable example names (k8s.company.internal, kubernetes-clients/-services, network 'kubernetes', nginx). Keeps the failure-domains diagram + ScheduleAnyway/DoNotSchedule note and the friendly-DNS appendix. Adds <img> slots for 5 dashboard/terminal screenshots (to be supplied). Renames the page + nav entry to route-to-a-kubernetes-service; old slug removed. * docs: add dashboard/terminal screenshots to the K8s how-to Four screenshots (DNS zone, access policy, the kubernetes network with HA + 3 routing peers, kubectl pods-across-nodes). Drop the groups screenshot and renumber the <img> refs to match. * docs: swap in cleaner pods-across-nodes screenshot for Step 5 * docs: make node-spread central to the HA guide Node-spread is the point of an HA guide, not a tail-end section. Move the topology diagram up to 'What you'll achieve', fold the node-spread story into Step 3 (deploy HA routing peers) - leading with the verified fact that the scheduler spreads replicas across nodes by default (HA out of the box), with topologySpreadConstraints as optional hardening - and drop the orphaned 'Spread across failure domains' section. * docs: clarify the custom zone is created empty (operator fills the record) Step 1 showed the auto-created A record without saying you don't enter it. Note that you create only the zone (no hostname/IP/TTL by hand) and the operator adds <service>.<namespace>.<zone> -> ClusterIP (5-min TTL) in Step 4. * docs: replace Excalidraw topology with a custom dark-mode SVG Hand-authored dark-background topology diagram (NetBird overlay -> routing peers one-per-node -> Service) that matches the dark docs theme, replacing the light Excalidraw-derived SVG. Removes the orphaned ha-routing-peers-spread-nodes.svg. * docs: add CNAME dialog screenshot to the friendly-DNS appendix Show the Add DNS Record dialog (CNAME 'app' -> nginx.default.k8s.company.internal) and align the example hostname to 'app' to match. * docs: drop maxSurge:0 workaround (not configurable via the operator) The operator's workloadOverride only exposes annotations, labels, podTemplate, and replicas — there is no hook for the Deployment's strategy.rollingUpdate.maxSurge. Keep the achievable workaround (more schedulable nodes than replicas). * docs: drop manual topology spread guidance (operator handles it by default)
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
@@ -0,0 +1,60 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 880 480" width="880" height="480" font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif">
|
||||
<defs>
|
||||
<marker id="ah" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M0,0 L10,5 L0,10 z" fill="context-stroke"/>
|
||||
</marker>
|
||||
</defs>
|
||||
|
||||
<!-- card background -->
|
||||
<rect x="2" y="2" width="876" height="476" rx="16" fill="#0d1117" stroke="#21262d" stroke-width="1.5"/>
|
||||
|
||||
<text x="40" y="46" font-size="21" font-weight="600" fill="#e6edf3">Highly available routing peers</text>
|
||||
|
||||
<!-- NetBird overlay zone -->
|
||||
<rect x="40" y="80" width="230" height="356" rx="14" fill="#0f1b2d" stroke="#1f4f8f" stroke-width="1.5"/>
|
||||
<text x="62" y="110" font-size="15" font-weight="600" fill="#58a6ff">NetBird overlay</text>
|
||||
|
||||
<!-- client -->
|
||||
<rect x="66" y="236" width="180" height="78" rx="12" fill="#15294a" stroke="#4d8bf0" stroke-width="1.5"/>
|
||||
<text x="156" y="270" text-anchor="middle" font-size="14" fill="#dbeafe">Your laptop</text>
|
||||
<text x="156" y="290" text-anchor="middle" font-size="12" fill="#93b6e6">NetBird client</text>
|
||||
|
||||
<!-- Kubernetes cluster zone -->
|
||||
<rect x="330" y="80" width="510" height="356" rx="14" fill="#0d1f15" stroke="#1f6f3a" stroke-width="1.5"/>
|
||||
<text x="352" y="110" font-size="15" font-weight="600" fill="#3fb950">Kubernetes cluster</text>
|
||||
|
||||
<!-- node 1 -->
|
||||
<rect x="360" y="132" width="330" height="84" rx="10" fill="#161b22" stroke="#30363d" stroke-width="1"/>
|
||||
<text x="376" y="154" font-size="12" fill="#8b949e">node-1</text>
|
||||
<rect x="470" y="152" width="200" height="44" rx="8" fill="#122a1c" stroke="#2ea043" stroke-width="1.5"/>
|
||||
<text x="570" y="179" text-anchor="middle" font-size="13" fill="#56d364">routing-peer pod</text>
|
||||
|
||||
<!-- node 2 -->
|
||||
<rect x="360" y="240" width="330" height="84" rx="10" fill="#161b22" stroke="#30363d" stroke-width="1"/>
|
||||
<text x="376" y="262" font-size="12" fill="#8b949e">node-2</text>
|
||||
<rect x="470" y="260" width="200" height="44" rx="8" fill="#122a1c" stroke="#2ea043" stroke-width="1.5"/>
|
||||
<text x="570" y="287" text-anchor="middle" font-size="13" fill="#56d364">routing-peer pod</text>
|
||||
|
||||
<!-- node 3 -->
|
||||
<rect x="360" y="348" width="330" height="84" rx="10" fill="#161b22" stroke="#30363d" stroke-width="1"/>
|
||||
<text x="376" y="370" font-size="12" fill="#8b949e">node-3</text>
|
||||
<rect x="470" y="368" width="200" height="44" rx="8" fill="#122a1c" stroke="#2ea043" stroke-width="1.5"/>
|
||||
<text x="570" y="395" text-anchor="middle" font-size="13" fill="#56d364">routing-peer pod</text>
|
||||
|
||||
<!-- service -->
|
||||
<rect x="735" y="235" width="92" height="80" rx="12" fill="#11272b" stroke="#2bb3c0" stroke-width="1.5"/>
|
||||
<text x="781" y="269" text-anchor="middle" font-size="14" fill="#9fe7ef">Service</text>
|
||||
<text x="781" y="289" text-anchor="middle" font-size="13" fill="#5fcdd8">nginx</text>
|
||||
|
||||
<!-- client -> routing peers (overlay) -->
|
||||
<polyline points="246,274 470,174" fill="none" stroke="#4d8bf0" stroke-width="2" marker-end="url(#ah)"/>
|
||||
<polyline points="246,274 470,282" fill="none" stroke="#4d8bf0" stroke-width="2" marker-end="url(#ah)"/>
|
||||
<polyline points="246,274 470,390" fill="none" stroke="#4d8bf0" stroke-width="2" marker-end="url(#ah)"/>
|
||||
|
||||
<!-- routing peers -> service -->
|
||||
<polyline points="670,174 735,266" fill="none" stroke="#3fb950" stroke-width="2" marker-end="url(#ah)"/>
|
||||
<polyline points="670,282 735,274" fill="none" stroke="#3fb950" stroke-width="2" marker-end="url(#ah)"/>
|
||||
<polyline points="670,390 735,283" fill="none" stroke="#3fb950" stroke-width="2" marker-end="url(#ah)"/>
|
||||
|
||||
<text x="40" y="463" font-size="13" fill="#8b949e">Clients reach the Service through any routing peer — lose a peer or a node and traffic fails over automatically.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
Reference in New Issue
Block a user