@@ -491,124 +491,3 @@ spec:
491491 # replacement: '...'
492492` ` `
493493
494- # # Technical Details
495-
496- The following sections go into more details of the behind the scenes magic.
497-
498- # ## Synchronization
499-
500- Even though the whole configuration is written from the standpoint of the service owner, the actual
501- synchronization logic considers the kcp side as the canonical source of truth. The Sync Agent
502- continuously tries to make the local objects look like the ones in kcp, while pushing status updates
503- back into kcp (if the given `PublishedResource` (i.e. CRD) has a `status` subresource enabled).
504-
505- # ## Local <-> Remote Connection
506-
507- The Sync Agent tries to keep sync-related metadata on the service cluster, away from the consumers.
508- This is both to prevent vandalism and to hide implementation details.
509-
510- To ensure stability against future changes, once the Sync Agent has determined how a local object
511- should be named, it will remember this decision in the object's metadata. This is so that on future
512- reconciliations, the (potentially costly, but probably not) renaming logic does not need to be
513- applied again. This allows the Sync Agent to change defaults and also allows the service owner to make
514- changes to the naming rules without breaking existing objects.
515-
516- Since we do not want to store metadata on the kcp side, we instead rely on label selectors on
517- the local objects. Each object on the service cluster has a label for the remote cluster name,
518- namespace and object name, and when trying to find the matching local object, the Sync Agent simply
519- does a label-based search.
520-
521- There is currently no sync-related metadata available on source objects (in kcp workspaces), as this
522- would either be annotations (untyped strings...) or require schema changes to allow additional
523- fields in basically random CRDs.
524-
525- Note that fields like `generation` or `resourceVersion` are not relevant for any of the sync logic.
526-
527- # ## Reconcile Loop
528-
529- The sync loop can be divided into 5 parts :
530-
531- 1. find the local object
532- 2. handle deletion
533- 3. ensure the destination object exists
534- 4. ensure the destination object's content matches the source object
535- 5. synchronize related resources the same way (repeat 1-4 for each related resource)
536-
537- # ### Phase 1: Find the Local Object
538-
539- For this, as mentioned in the connection chapter above, the Sync Agent tries to follow label selectors
540- on the service cluster. This helps prevent cluttering with consumer workspaces with sync metadata.
541- If no object is found to match the labels, that's fine and the loop will continue with phase 2,
542- in which a possible Conflict error (if labels broke) is handled gracefully.
543-
544- The remote object in the workspace becomes the `source object` and its local equivalent on the
545- service cluster is called the `destination object`.
546-
547- # ### Phase 2: Handle Deletion
548-
549- A finalizer is used in the kcp workspaces to prevent orphans in the service cluster side. This
550- is the only real evidence in the kcp side that the Sync Agent is even doing things. When a remote
551- (source) object is deleted, the corresponding local object is deleted as well. Once the local object
552- is gone, the finalizer is removed from the source object.
553-
554- # ### Phase 3: Ensure Object Existence
555-
556- We have a source object and now need to create the destination. This chart shows what's happening.
557-
558- ` ` ` mermaid
559- graph TB
560- A(source object):::state --> B([cleanup if in deletion]):::step
561- B --> C([ensure finalizer on source object]):::step
562- C --> D{exists local object?}
563-
564- D -- yes --> I("continue with next phase…"):::state
565- D -- no --> E([apply projection]):::step
566-
567- subgraph "ensure dest object exists"
568- E --> G([ensure resulting namespace exists]):::step
569- G --> H([create local object]):::step
570- H --> H_err{Errors?}
571- H_err -- Conflict --> J([attempt to adopt existing object]):::step
572- end
573-
574- H_err -- success --> I
575- J --> I
576-
577- classDef step color:#77F
578- classDef state color:#F77
579- ` ` `
580-
581- After we followed through with these steps, both the source and destination objects exists and we
582- can continue with phase 4.
583-
584- Resource adoption happens when creation of the initial local object fails. This can happen when labels
585- get mangled. If such a conflict happens, the Sync Agent will "adopt" the existing local object by
586- adding / fixing the labels on it, so that for the next reconciliation it will be found and updated.
587-
588- # ### Phase 4: Content Synchronization
589-
590- Content synchronization is rather simple, really.
591-
592- First the source "spec" is used to patch the local object. Note that this step is called "spec", but
593- should actually be called "all top-level elements besides `apiVersion`, `kind`, `status` and
594- ` metadata` , but still including some labels and annotations"; so if you were to publish RBAC objects,
595- the syncer would include `roleRef` field, for example).
596-
597- To allow proper patch generation, the last known state is kept on the local object, similar to how
598- ` kubectl` creates an annotation for it. This is required for the Sync Agent to properly detect changes
599- made by mutation webhooks on the service cluster.
600-
601- If the published resource (CRD) has a `status` subresource enabled (not just a `status` field in its
602- scheme, it must be a real subresource), then the Sync Agent will copy the status from the local object
603- back up to the remote (source) object.
604-
605- # ### Phase 5: Sync Related Resources
606-
607- The same logic for synchronizing the main published resource applies to their related resources as
608- well. The only difference is that the source side can be either remote (workspace) or local
609- (service cluster).
610-
611- Since the Sync Agent tries its best to keep sync-related data out of kcp workspaces, the last known
612- state for related resources is _not_ kept together with the destination object in the kcp workspaces.
613- Instead all known states (from the main object and all related resources) is kept in a single Secret
614- on the service cluster side.
0 commit comments