Skip to content

feat(frankgateway): split into per-traffic-class instances — inway / outway / internal (IN-2547) - #400

Open
jimleitch01 wants to merge 4 commits into
feature/podiumd-4.8.5from
feature/IN-2547-frankgateway-split-4.8.4
Open

feat(frankgateway): split into per-traffic-class instances — inway / outway / internal (IN-2547)#400
jimleitch01 wants to merge 4 commits into
feature/podiumd-4.8.5from
feature/IN-2547-frankgateway-split-4.8.4

Conversation

@jimleitch01

Copy link
Copy Markdown
Collaborator

What

Frank!Gateway becomes a map of instances instead of a single deployment, so inbound (inway), outbound (outway) and east-west (internal) traffic can each run on their own pods, with their own etcd slice, dashboard and NetworkPolicy.

Closes the chart half of IN-2547. The jim00 rollout (enabling the split, repointing applications) is separate and deploy-side.

Safety: the default render is byte-identical

The instance key gateway is the reserved single-instance default — it keeps the bare object names and the /apisix prefix. A full helm template with ci/lint-values.yaml was diffed against feature/podiumd-4.8.4 and is identical.

The only differences under helm template are the randAlphaNum secrets, which have no cluster to lookup and so differ between any two runs of the same chart. Those are masked by key name for the comparison; everything else is compared verbatim, so a new key, changed indentation or reordered block would still show.

Existing environments — including those already running Frank!Gateway — are unaffected until they opt in.

Design notes

  • One etcd, three prefixes. APISIX in traditional mode loads exactly the objects beneath its configured prefix, so config isolation is complete without three StatefulSets and three PVCs. etcd is not the blast-radius concern.
  • Per-instance checksums. The config and shim checksums come from new helpers rather than hashing the whole template file. A range over instances in one file would give every Deployment the same file-wide checksum, so changing one traffic class would needlessly restart the others.
  • Dashboard per instance. apisix-dashboard binds exactly one etcd prefix, so the whole chain (dashboard + shim + oauth2-proxy + Keycloak client + realm secret) is per instance. The prefix is written into the dashboard conf only when it differs from its built-in /apisix default, which is what keeps the default render unchanged.
  • Routes are not duplicated. They move into per-class directories and each instance declares which directories it seeds. The default seeds outway + internal, i.e. all five legacy apiproxy routes with the same ids. The ConfigMap is keyed by basename in sorted order, so the result does not depend on how many directories contributed.
  • NetworkPolicies are the point of the exercise and are new to this chart — one gateway carrying every class needs the union of all their egress, so nothing meaningful can be restricted. Opt-in, and only for instances with a class.
  • serviceAlias keeps the pre-split frankgateway Service name pointing at a chosen instance so applications can be repointed one at a time.

Migration hazard

The Admin API Secret becomes frankgateway-<instance>-admin-credentials. Deployment pipelines that read frankgateway-admin-credentials by name must be updated — jim00's apply-routes.sh does. This is why the default instance keeps the old names and why serviceAlias exists. Called out in the upgrade notes.

Verification

helm lint charts/podiumd -f charts/podiumd/ci/lint-values.yaml                                  # clean
helm lint charts/podiumd -f charts/podiumd/ci/lint-values.yaml -f charts/podiumd/ci/split-values.yaml  # clean

Split mode renders 3 gateways + 3 dashboard chains + 3 NetworkPolicies + the shared etcd + the alias Service, with distinct etcd prefixes, correctly partitioned routes (internal = BRP, outway = BAG + 3× KVK, inway = empty in-chart), and per-instance Keycloak clients wired end to end.

CI now renders the split shape as well as the default, via ci/split-values.yaml — otherwise a broken split template could merge unnoticed.

Docs

  • New frankgateway-traffic-classes.md with a mermaid architecture diagram (rendered to check it parses), the NetworkPolicy model and the migration order.
  • Exploration doc's "nothing is implemented" banner retired; its four open questions answered in place.
  • Upgrade notes for the 4.8.3 → 4.8.4 hop.

🤖 Generated by Claude Code with help from Jimbo

…s instances

Assesses splitting frankgateway into incoming/outgoing/internal instances:
etcd prefix separation on the shared etcd, map-driven instance templates,
per-class NetworkPolicies as the main win, dashboard single-prefix binding
as the main friction, incoming class blocked on a product use-case.

🤖 Generated by Claude Code with help from Jimbo
Claude-Session: https://claude.ai/code/session_0158uRhyY31d9xzNsgU8gjbx
Frank!Gateway becomes a map of instances instead of a single deployment, so
incoming (inway), outgoing (outway) and east-west (internal) traffic can each
run on their own pods, with their own etcd slice, dashboard and NetworkPolicy.

The instances share the one etcd StatefulSet: APISIX in traditional mode loads
exactly the objects beneath its configured prefix, so config isolation is
complete without running three etcds.

The instance key `gateway` is the reserved single-instance default. It keeps the
bare object names and the `/apisix` prefix, so an environment that does not opt
into the split renders byte-identical manifests — verified by diffing a full
`helm template` against feature/podiumd-4.8.4 (the only differences under
`helm template` are the randAlphaNum secrets, which have no cluster to look up).

Notable details:

- Per-instance config and shim checksums come from new helpers rather than
  hashing the whole template file. A range over instances in one file would
  give every Deployment the same file-wide checksum, so changing one traffic
  class would needlessly restart the others.
- apisix-dashboard binds exactly one etcd prefix, so the whole dashboard chain
  (dashboard + shim + oauth2-proxy + Keycloak client + realm secret) is per
  instance. The prefix is written to the dashboard conf only when it differs
  from its built-in `/apisix` default, keeping the default render unchanged.
- Route JSONs move into per-class directories and each instance declares which
  directories it seeds, so the files live in one place instead of being copied
  per class. The default instance seeds outway + internal, i.e. all five legacy
  apiproxy routes, and the ConfigMap is keyed by basename in sorted order so the
  rendered result is independent of how many directories contributed.
- NetworkPolicies are the point of the exercise and are new to this chart: one
  gateway carrying every class needs the union of all their egress, so nothing
  meaningful can be restricted. They are opt-in, and a cluster whose CNI does
  not enforce them will accept and ignore them.
- `serviceAlias` keeps the pre-split `frankgateway` Service name pointing at a
  chosen instance, so applications can be repointed one at a time.

CI renders the split shape as well as the default via ci/split-values.yaml.
…otes (IN-2547)

Adds frankgateway-traffic-classes.md — what each instance carries, a mermaid
diagram of all three classes with the hairpin drawn as the path being removed,
the NetworkPolicy model, and the migration order via serviceAlias.

Retires the "nothing is implemented" banner on the exploration doc and answers
its four open questions in place, including the two decisions that differ from
the assessment: the instances are named inway/outway/internal rather than
incoming/outgoing, and every instance gets its own dashboard rather than one
designated instance.

Records the one real migration hazard in the upgrade notes: the Admin API
Secret is renamed per instance, and deployment pipelines that read
frankgateway-admin-credentials by name must be updated.
@bas-info-nl
bas-info-nl force-pushed the feature/podiumd-4.8.4 branch from cf458ad to b356f97 Compare August 10, 2026 14:14
Base automatically changed from feature/podiumd-4.8.4 to main August 10, 2026 14:54
@infojohn
infojohn changed the base branch from main to feature/podiumd-4.8.5 August 14, 2026 11:22
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