ADR-0012: Activation controller
- Status
- proposed
- Authors
- Category
- Deployment
- Impact
- High
This decision is still under discussion and may change before it is accepted.
Context
After a new vector has been successfully deployed and any associated migration tasks have been completed (as per ADR-0008 Task Engine), the new software version is running but not yet serving live traffic. The final step in the lifecycle is the activation: a controlled and reliable process of switching traffic to the newly deployed artifacts.
Requirements
- Declarative Activation: The activation process must be triggered declaratively by creating a Kubernetes custom resource. The system will then reconcile the state of the landscape to match the desired activation.
- Concurrency Control: The system must strictly enforce that only one activation process for a given
Stagecan run at a time. This prevents race conditions where a slower, older activation could overwrite a faster, newer one. - Extensibility: The platform must support various routing and service mesh technologies (e.g., Gateway API, Istio, CloudFoundry, etc.). The architecture must allow for new activation mechanisms to be added without modifying the core activation controller.
- The system must prevent the underlying
StageVersionand its artifacts from being deleted or modified while an activation is in progress. - Dependencies between activation tasks must be manageable, allowing certain tasks to run only after others have completed successfully. This includes the ability to define tasks that must run before or after others, as it must be possible to define dependencies in both directions with predefined tasks that shipped with the platform.
Considered Solutions
Option 1: Generic task orchestration for both migration and activation (discarded)
- Vector Activation Controller: A high-level controller that manages the overall activation process, including locking and lifecycle tracking. It does not interact with routing or other activation resources directly.
- Task Orchestration Engine: A generic orchestration engine that creates task executions, respecting dependencies and execution order. This engine is shared between migration and activation processes.
- Task Execution Controllers (Executors): Specialized controllers that handle the actual work of modifying routing resources for a specific technology, or other activation tasks. They are implemented in the same way as migration task execution controllers.
The Vector Activation Controller creates a TaskExecutionPlan CR that contains a list tasks to be executed, including their type and dependency relationships. The task list is compiled based on ActivationTaskRegistration CRs found in the landscape's namespace and the konfidence-system namespace. The Task Orchestration Engine controller reconciles the TaskExecutionPlan CR and creates the TaskExecution CRs with the correct type and in the correct order based on the dependency tree. For each task type, a corresponding Task Execution Controller watches for TaskExecution CRs of its type and performs the necessary actions to complete the task, e.g. updating Gateway API HTTPRoute resources.
ActivationTaskRegistration CR example:
apiVersion: landscape.konfidence.cloud/v1alpha1
kind: ActivationTaskRegistration
metadata:
name: activationtaskregistration-sample
spec:
type: custom-k8s-activation
spec: ""
suceeds:
- activation-A
- activation-B
precedes:
- activation-CTaskExecutionPlan CR example:
apiVersion: landscape.konfidence.cloud/v1alpha1
kind: TaskExecutionPlan
metadata:
name: taskexecutionplan-sample
spec:
tasks:
- type: activation-A
spec: ""
- type: activation-B
spec: ""
- type: custom-k8s-activation
spec: ""
dependsOn:
- activation-A
- activation-B
- type: activation-C
spec: ""
dependsOn:
- custom-k8s-activationAdvantages
- reuse of the task orchestration logic
- offers a high degree of extensibility for new activation mechanisms
- enables complex dependency management between activation tasks (which can also be a disadvantage)
Disadvantages
- the dependency management is spread across all ActivationTaskRegistration CRs, making it harder to understand and configure the full activation process with all dependencies
- future diverging requirements for migration and activation tasks could lead to complexity in the shared orchestration engine
Option 2: Dedicated activation task orchestration based on a ActivationExecutionPlan CR (preferred)
- Vector Activation Controller: A high-level controller that manages the overall activation process, including locking and lifecycle tracking. It reads ActivationTaskRegistration CR(s) and optionally an ActivationExecutionPlan CR that define the execution order of the tasks, and creates ActivationExecution CRs in the correct order.
- Activation Execution Controllers (Executors): Specialized controllers that handle the actual work of modifying routing resources for a specific technology, or other activation tasks.
ActivationTaskRegistration CR example:
apiVersion: landscape.konfidence.cloud/v1alpha1
kind: ActivationTaskRegistration
metadata:
name: activationtask-1
spec:
type: custom-k8s-activation
spec: ""ActivationExecutionPlan CR example:
apiVersion: landscape.konfidence.cloud/v1alpha1
kind: ActivationExecutionPlan
metadata:
name: activationexecutionplan
spec:
steps:
- name: step1
tasks:
- activationtask-1
- name: step2
tasks:
- k8s-gateway-activationtaskregistration-sampleActivationExecution CR example:
apiVersion: landscape.konfidence.cloud/v1alpha1
labels:
registration: activationtask-1
kind: ActivationExecution
metadata:
name: activation-execution-h7txf
spec:
type: custom-k8s-activation
vectorActivation: vector-activation-gjs82
vectorDeployment: vector-deployment-fg3hd
spec: ""The ActivationTaskRegistration and ActivationExecutionPlan CRs are created in the konfidence-system namespace and apply to all landscapes managed by the corresponding LCP.
Advantages
- offers a high degree of extensibility for new activation mechanisms
- clear separation of migration and activation logic
- dependency configuration in a central place (ActivationExecutionPlan CR)
Disadvantages
- no reuse of overlapping logic with migration task orchestration
Concurrency Control Mechanism
Kubernetes Lease Object
The controller would leverage the built-in Kubernetes Lease resource (coordination.k8s.io/v1). Before starting an activation, the controller must acquire a named Lease for that Stage. This is the idiomatic, battle-tested Kubernetes way to handle leader election and distributed locks. It provides a robust guarantee of serialized execution.
Decision
We will adopt Option 2 for the activation process, secured by a Kubernetes Lease object for concurrency control.
The process is as follows:
- Trigger: After a
VectorMigrationsucceeds, theStage Controllercreates aVectorActivationresource for the newStageVersion. - Reconciliation & Locking: The
Vector Activation Controllerreconciles theVectorActivation. Its first action is to acquire an exclusiveLeasefor the targetStage. If the lease is held by another process, the controller will requeue and wait, ensuring activations are serialized. - Check if VectorActivation is for Newer StageVersion: If the
VectorActivationis still in an initial state, the controller reads the currently activeStageVersionUsagefor theStageto determine the activeStageVersion. If theVectorActivationbelongs to an olderStageVersionthan the currently active one, the controller updates theVectorActivationstatus toSkippedand releases theLease. - StageVersionUsage Creation: The controller creates a new
StageVersionUsagefor theactivationto ensure that theStageVersionremains deployed during the activation process. - Set Activation In Progress: The controller updates the
VectorActivationstatus toInProgress. - ActivationExecutionPlan: The controller reads the optional
ActivationExecutionPlanresource. - Task Orchestration: If an
ActivationExecutionPlanwas found, the controller createsActivationExecutionCRs based on theActivationExecutionPlan. The steps defined in theActivationExecutionPlanare processed in order, and theActivationExecutionCRs of a step are only created once allActivationExecutionCRs of the previous step have been completed successfully. If noActivationExecutionPlanis found, the controller createsActivationExecutionCRs for all registeredActivationTaskRegistrationCRs in an arbitrary order. - Execution: A specialized
ActivationExecutioncontroller (e.g.,GatewayAPIActivationExecutionController) watches for CRs of its type. It performs the actual routing changes in the landscape cluster and updates theActivationExecutionstatus. - Status & Usage Update: The
Vector Activation Controllermonitors the status of itsActivationExecutionchildren. Once all have succeeded, it updates theStageVersionUsageactiveto the just activatedStageVersion, deletes theStageVersionUsageactivationand updates theVectorActivationstatus toSucceeded - Release Lock: The
Vector Activation Controllerreleases theLease.
In the event of activation failures, the controller updates the VectorActivation status to Failed once all running ActivationExecutions have reached a final state (Succeeded or Error), release the lease, and allows for retries.
Architecture
Sequence Diagram
The following sequence diagram illustrates a successful activation process (happy path):
sequenceDiagram
autonumber
participant SC as Stage Controller
participant VAC as Vector Activation Controller
participant Lease as Lease (for Stage)
participant AEP as ActivationExecutionPlan
participant EC as Activation Execution Controller
participant SVUA as StageVersionUsage "active"
create participant VA as VectorActivation
SC ->> VA: Create VectorActivation
activate VAC
VAC ->> VA: Read VectorActivation
VAC ->> VAC: Check for VectorActivations currently in progress (with expired lease)
VAC ->> Lease: Attempt to acquire Lease
Lease -->> VAC: Lease acquired
VAC ->> SVUA: Read currently active StageVersion
VAC ->> VAC: check if VectorActivation belongs to newer StageVersion than currently active StageVersion
create participant SVU as StageVersionUsage "activation"
VAC ->> SVU: Create StageVersionUsage
VAC ->> VA: Update status to InProgress
VAC ->> AEP: Read ActivationExecutionPlan
AEP -->> VAC: steps
loop For each step in steps
loop For each task in step
create participant AE as ActivationExecution
VAC ->> AE: Create ActivationExecution
end
loop While not all tasks in step are completed
EC ->> AE: Execute
VAC ->> AE: Observe ActivationExecution
end
end
VAC ->> SVUA: Update StageVersionUsage "active" to point to new StageVersion
destroy SVU
VAC ->> SVU: Delete StageVersionUsage "activation"
VAC ->> VA: Update VectorActivation Status: Succeeded
VAC ->> Lease: Release lock
deactivate VACSpecial and error cases
Lease already held by another activation
If the Lease for the Stage is already held by another activation process, the VectorActivation controller must requeue the current VectorActivation reconciliation.
Other activation ongoing, lease expired
If another activation is already in progress, the activation controller must requeue the current VectorActivation. To determine whether another activation is in progress, it is not sufficient to attempt to require the Lease for the Stage, as the Lease of an ongoing activation could expire if the executions take too long and not other event occurs that triggers a reconciliation for the ongoing VectorActivation.
ActivationExecution stuck in progress
An ActivationExcution could remain in progress indefinitely, e.g., if an unhandled error occurs during the execution. To mitigate this, each ActivationTaskRegistration should have a configurable timeout. After the timeout has been exceeded, the ActivationExecution controller tries to abort execution and marks the execution as Error.
Cleanup Strategy
The ActivationExecution and StageVersionUsage activation CRs are created with an owner reference to the VectorActivation CR. Thus, when the VectorActivation is deleted, Kubernetes garbage collection will automatically clean up these resources.
Consequences
- Safety and Reliability: The use of a
Leasefor locking provides a strong guarantee against race conditions during the critical traffic-switching phase. - High Extensibility: The platform can easily support new routing technologies in the future by adding new
ActivationExecutioncontrollers, with no changes required to the core orchestration logic. - Increased Resource Count: The architecture introduces four new CRDs (
VectorActivation,ActivationExecution,ActivationTaskRegistration,ActivationExecutionPlan) and oneLeaseobject per stage.