Custom Observer Schema¶
Purpose¶
When a user creates Kubernetes resources on a Kubernetes cluster via Krake, those resources are managed by Krake and should be “observed”. That’s the role of the Kubernetes Observer (see the dev/observers:Observers documentation). But what parts of the Kubernetes resources should be “observed” by Krake? The purpose of the Observer Schema is to provide a flexible mean for the Krake users to define which fields of the Kubernetes resources should be “observed” and which shouldn’t.
When a field is “observed”, every change to the value of this field made outside of Krake is reverted to the last known state of this field. When a field is not “observed”, Krake doesn’t act on external changes made to this field. This is needed to keep a consistent and predictable application state, especially since changes could also be done in the Kubernetes infrastructure or by the Kubernetes plane itself.
Note
The custom observer schema could be used even when the application is described by a TOSCA template or CSAR archive. Both file types are translated to Kubernetes manifests in Krake’s Kubernetes application controller, hence the custom observer schema file will be applied to the Kubernetes resources just like it happens during a “regular” workflow, when a Kubernetes manifest is used, see dev/tosca:TOSCA Workflow.
Note
As Kubernetes manages some fields of a Kubernetes resource (for instance the ResourceVersion), simply observing the entirety of a Kubernetes resource is not possible. This would lead to infinite reconciliation loops between Krake and Kubernetes, which is not a desirable state.
Format¶
Example¶
This basic example will be re-used at different part of this documentation.
Example of manifest file provided by the user:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-demo
namespace: secondary
spec:
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: k8s.gcr.io/echoserver:1.10
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: echo-demo
namespace: secondary
spec:
type: NodePort
selector:
app: echo
ports:
- port: 8080
protocol: TCP
targetPort: 8080
Example of custom observer schema provided by the user.
---
apiVersion: v1
kind: Service
metadata:
name: echo-demo
namespace: default
spec:
selector:
app: null
ports:
- port: null
protocol: null
targetPort: null
- port: null
protocol: null
targetPort: null
- observer_schema_list_min_length: 1
observer_schema_list_max_length: 4
sessionAffinity: null
Default observer schema¶
By default, all fields defined in spec.manifest
are observed. All other fields are
not observed. By defining a custom observer schema, the user is able to overwrite the
default behavior and precisely define the observed fields.
In the example above, the user didn’t specify a custom observer schema file for the
Deployment
resource. Therefore Krake will generate a default observer schema, and
observe only the fields which are specified in the manifest file.
The result default observer schema for the Deployment
resource is:
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-demo
namespace: secondary
spec:
selector:
matchLabels:
app: null
template:
metadata:
labels:
app: null
spec:
containers:
- name: null
image: null
ports:
- containerPort: null
- observer_schema_list_min_length: 1
observer_schema_list_max_length: 1
- observer_schema_list_min_length: 1
observer_schema_list_max_length: 1
Resource identification¶
In order to identify which resource a schema is referring to, the apiVersion
,
kind
and name
need to be specified. Those fields are also the minimum fields a
user can specify in order to observe a resource. As a result, and without additional
fields to observe, the Kubernetes Observer will simply check the presence of a
Kubernetes resource with this apiVersion
, kind
and name
.
Example of a minimal observer schema for the Service
resource:
---
apiVersion: v1
kind: Service
metadata:
name: echo-demo
Note
The Kubernetes namespace key metadata.namespace
is not mandatory, as it is not
used in the identification of a resource in Krake. Indeed, its value is not always
known at the creation of the application. It can depend from the Kubernetes cluster
the application is scheduled to.
Please note that not all Kubernetes objects are in a namespace. Most Kubernetes resources (e.g. pods, services, replication controllers, and others) are in some namespaces. However, namespace resources are not themselves in a namespace. And low-level resources, such as nodes and persistentVolumes, are not in any namespace.
Therefore, Krake (by default) does not observe a Kubernetes namespace field.
Users may choose to add the metadata.namespace
key to their custom observer schema,
then the metadata.namespace
field will be observed.
Observed fields¶
A field value will be observed if it is defined in the observer schema. Its value should
be null
(in YAML), except for fields used for the resource identification.
In the example above:
- the
spec.type
of the Service is not observed, as it is not present in the custom observer schema. Its original value is specified in the manifest file, but Krake doesn’t guarantee this value to remain. - the
spec.selector.app
of theService
is observed as it is present in the custom observer schema. Krake guarantee that its original value will remain the same, by observing the value and reverting any changes which were not made through Krake. - the
spec.sessionAffinity
of theService
is observed. As it is not present in the manifest, the Kubernetes API will initialize it. Once it has been initialized by Kubernetes, Krake guarantee that its value will not be modified outside of Krake.
Warning
A non-observed field cannot be updated by Krake. In order to update such a field, one also need to observe it (i.e. update the custom observer schema to add this field).
Note
Except for the fields used for identifying the Kubernetes resource, all fields value
MUST be null
. Otherwise, the custom observer schema is invalid.
List length control¶
A list’s length is controlled though the used of a special control dictionary, added as the last element of a list. The minimum and maximum length of the list must be specified.
In the example Service
’s custom observer schema, the number of ports
must be
between 1 and 4. If the length of the ports
list is below 1 or above 4, Krake
reverts the Service
to its last known value.
For the first port, the value of port
, protocol
, targetPort
are defined in
the manifest file.
The presence of a second element in the ports
list in the custom observer schema
doesn’t guarantee its presence. Krake guarantee that, if a second port is set, its value
won’t be allowed to change outside of Krake. It can be removed and re-added, as long as
its value remains unchanged.
Tip
Krake doesn’t allow to set a minimum list length value below the number of element specified in the manifest file.
Tip
An unlimited list length can be specified by setting
observer_schema_list_max_length
to 0.
Note
A list MUST contain the special control dictionary. Otherwise, the custom observer schema is invalid.
Usage¶
A custom observer schema can be specified in rok
with the argument -O
or
--observer_schema
. If none is provided, a default observer schema is generated and
all fields defined in spec.manifest
are observed