Gefyra Bridge Mount#
Overview#
A GefyraBridgeMount is a Kubernetes custom resource managed by the Gefyra operator that enables local development traffic intercept at the workload level. Where a GefyraBridge patches a single pod container, a GefyraBridgeMount operates at a higher level β it duplicates the entire target workload (Deployment, StatefulSet, or Pod) into a "shadow" copy that acts as the stable cluster-side upstream for all bridges associated with that workload. The shadow workload absorbs cluster-internal traffic while the original pods are patched with the Carrier2 proxy image to intercept and redirect requests to a local developer machine.
The state machine is defined in bridge_mount_state.py and the kopf event handlers live in handler/bridge_mounts.py. The only currently registered provider is carrier2mount, implemented in bridge_mount/carrier2mount/__init__.py.
State Machine#
GefyraBridgeMount extends StateChart and StateControllerMixin . States and allowed transitions:
Key transitions :
| Event | Valid From | Destination |
|---|---|---|
arrange | REQUESTED, RESTORING, ERROR, PREPARING | PREPARING |
install | PREPARING, INSTALLING, RESTORING | INSTALLING |
activate | INSTALLING, ACTIVE | ACTIVE |
restore | ACTIVE, ERROR, INSTALLING, PREPARING, RESTORING | RESTORING |
impair | PREPARING, REQUESTED, INSTALLING, ACTIVE, ERROR | ERROR |
mark_missing | ACTIVE, ERROR, RESTORING, PREPARING, INSTALLING, REQUESTED | MISSING |
recover | MISSING | PREPARING |
terminate | Any non-TERMINATED state | TERMINATED |
Lifecycle Phases#
1. PREPARING β Shadow Workload Duplication (prepare)#
on_arrange calls bmp.prepare(), which invokes _duplicate_workload(). This:
- Deep-copies the original workload spec via
_clone_workload_structure(), renaming it with a-gefyrasuffix and rewriting all labels to add-gefyra. - Adds a unique
bridge.gefyra.dev/duplication-idlabel used as the shadow Service selector . - Creates the shadow workload and a paired
Servicein the target namespace . - If an HPA targets the original Deployment, duplicates it for the shadow Deployment via
_handle_hpa_for_deployment().
The install transition is gated by _bridge_mount_prepared(), which waits until at least one shadow pod is Ready (via _duplicated_pods_ready) before advancing.
2. INSTALLING β Carrier2 Injection (install)#
on_install calls bmp.install() , which:
- Lists all original pods for the target workload.
- Aborts with a
TemporaryErrorif multiple replica-set owners are detected (rolling update in progress) . - For each pod, replaces the target container image with the Carrier2 image .
- Stores the original container config (image, command, args) in the
gefyra-carrier2-restore-configmapConfigMap via_store_pod_original_config(). - Waits for the container to restart (up to 120 s) .
- Configures the Carrier2 upstream pointing to the shadow Service via
_set_carrier_upstream()and commits the config. - Optionally injects TLS cert/key files from Kubernetes Secrets if
providerParameterspecifies TLS .
3. ACTIVE β Steady State#
The activate transition is gated by _bridge_mount_finished(), which calls bmp.ready(). ready() requires all four conditions simultaneously :
_duplicated_pods_readyβ at least one shadow pod is Running + Ready._carrier_installedβ all original pod containers are running the Carrier2 image._original_pods_readyβ all original pods are Running + Ready._upstream_setβ Carrier2 config in each pod has a non-emptyclusterUpstream.
During reconciliation (every 60 s), is_intact re-checks prepared() and ready() . If either fails, the mount is transitioned back to RESTORING.
4. MISSING β Grace Period Handling#
When target_exists() returns False from any operational state, mark_missing fires. on_mark_missing posts a warning event and calls bmp.uninstall() to clean up artifacts. During MISSING:
- If the target reappears within the grace period (default from
OperatorConfiguration.BRIDGE_MOUNT_MISSING_GRACE_PERIOD, overridable per-resource viamissingGracePeriod),recovertransitions the mount back to PREPARING . - If the grace period expires, the mount is
terminated and the CR is deleted .
5. TERMINATED β Cleanup (uninstall)#
on_terminate calls bmp.uninstall() and then cleanup_all_bridges(). uninstall() :
- Deletes the shadow workload (and its HPA if one exists) via
uninstall_duplicated_workload(). - Deletes the shadow Service via
uninstall_service(). - Restores the original workload by restarting it (Deployment/StatefulSet) or patching back the stored container image (Pod) via
restore_original_workload().
cleanup_all_bridges() deletes all GefyraBridge CRs labeled gefyra.dev/bridge-mount=<name> .
Provider Architecture#
The provider abstraction lives in bridge_mount/abstract.py with interface methods: prepare, install, ready, prepared, uninstall, target_exists, validate.
The factory bridge_mount_provider_factory uses BridgeMountProviderType to select an implementation. Currently CARRIER2MOUNT is the only registered type . The provider is lazily instantiated via the bridge_mount_provider property on GefyraBridgeMount .
Kopf Handlers#
All handler entry points are in handler/bridge_mounts.py:
| Handler | Trigger | Behavior |
|---|---|---|
bridge_mount_created | kopf.on.create / kopf.on.resume | Drives state from REQUESTED β ACTIVE; skips if already activated |
bridgemount_deleted | kopf.on.delete | Transitions to TERMINATED if not already |
bridge_mount_reconcile | kopf.timer every 60 s | Checks sunset, MISSING/recovery, integrity; restores if impaired |
TransitionNotAllowed exceptions from the state machine are caught and re-raised as kopf.TemporaryError with a 15 s retry delay .
Key Files at a Glance#
| File | Purpose |
|---|---|
operator/gefyra/bridge_mount_state.py | State machine, transitions, action handlers |
operator/gefyra/handler/bridge_mounts.py | Kopf event/timer handlers |
operator/gefyra/bridge_mount/carrier2mount/__init__.py | carrier2mount provider β shadow duplication + Carrier2 injection |
operator/gefyra/bridge_mount/abstract.py | Provider interface |
operator/gefyra/bridge_mount/factory.py | Provider factory + registration |