Imperative vs Declarative
By Andrew Chen and Dominik Tornow
Kubernetes is a Container Orchestration Engine designed to host containerized applications on a set of nodes, commonly referred to as a cluster. Using a systems modeling approach, this series aims to advance the understanding of Kubernetes and its underlying concepts.
Kubernetes is often described as a declarative system and compared with imperative systems. However, the meaning of the terms “declarative” and “imperative” are not readily obvious. This blog post provides a concise model to illustrate the similarities and difference between the two.
Model of Computation
The remainder of this post will adopt a simple state machine model of computation. In the state machine model, a computation is defined as applying a command which transitions the system from one state to another. A running system is therefore a series of commands that transitions the system through various states.
The system is considered to be in a state match if the current state is equal to the desired state. In contrast, the system is considered to be in a state drift if the current state is not equal to the desired state. The set of commands that transitions the system from its current state to a given desired state is called the set of mitigating actions.
For example, given the initial state S, the command c transitions the system to the state S’. Similarly, c’ transitions the system to S’’ and so forth. With S being the current state and S’’’ being the desired state, the set of mitigating actions is equal to {c, c’, c’’}.
Figure 2. highlights the actors involved in the state machine model of computation. The automaton is responsible for applying a given command to the current state which transitions the system to the next state. However, the environment in which the system exists can also affect the state.
Here, an intended state change is any state change that is a result of an explicitly supplied command. In contrast, an unintended state change is any change in state that is a result of an interaction with the environment.
In the context of Kubernetes, an intended state change might be the deployment of a Pod or a ReplicaSet, whereas an unintended state change might be a single container or an entire node going down.
Imperative Systems
In an imperative system, the user knows the desired state, determines the sequence of commands to transition the system to the desired state, and supplies a representation of the commands to the system. The component of the system that applies the command to transition the state is called a processor.
Declarative Systems
By contrast, in a declarative system, the user knows the desired state, supplies a representation of the desired state to the system, then the system reads the current state and determines the sequence of commands to transition the system to the desired state. The component that determines the necessary sequence of commands is called a controller.
Declarative systems have the distinct advantage of being able to react to unintended state changes without further supervision: In the event of an unintended state change leading to a state drift, the system may autonomously determine and apply the set of mitigating actions leading to a state match. This process is called a control loop, a popular choice for the implementation of controllers.
Kubernetes
Kubernetes is a declarative system. Instead of a single controller, however, it has several controllers that are each responsible for a different Kubernetes object type, such as ReplicaSet or Deployment, for example. The API Server acts as the processor, applying the commands given by the controllers to the system state, which is stored in the Kubernetes Object Store.
In summary
The defining aspect of imperative and declarative systems is the answer to the question of who is in the driver’s seat. Is the user or the system responsible for orchestrating the transition to the desired state?
In an imperative system, the user is responsible for knowing how to drive the system to the desired state, whereas in a declarative system, the system is responsible for knowing how to drive itself to the desired state.
About this post
This blog post is part of a collaborative effort between the CNCF, Google, and SAP to advance the understanding of Kubernetes and its underlying concepts.