A trait is a discretionary runtime overlay that augments a component workload instance with operational features. It represents an opportunity for those in the application operator role to make specific decisions about the configuration of components, without having to involve the component provider or breaking the component encapsulation.
For example, a
sidecar
trait that injects a sidecar container to the workload in WordPress Helm chart.
A trait can be any configuration of a distributed application that applies to an individual component, such as traffic routing rules (e.g., load balancing policy, network ingress routing, circuit breaking, rate limiting), auto-scaling policies, upgrade strategies, and more.
This section is normative because traits are an inspectable (and possibly shareable) part of the system. All traits MUST be representable in the following format.
Traits are defined with schematics like components. As with workload definitions, each trait definition has a definitionRef
, which is a reference to a schema that defines the configuration options for the trait.
The top-level attributes of a trait define its metadata, version, kind, and spec.
Attribute | Type | Required | Default Value | Description |
---|---|---|---|---|
apiVersion |
string |
Y | A string that identifies the version of the schema the object should have. The core types uses core.oam.dev/v1beta1 in this version of documentation. |
|
kind |
string |
Y | Must be TraitDefinition |
|
metadata |
Metadata |
Y | Information about the trait. | |
spec |
Spec |
Y | A specification for trait attributes. |
Attribute | Type | Required | Default Value | Description |
---|---|---|---|---|
appliesToWorkloads |
[]string |
* | The collection of workload type characteristics to which this trait applies. If this field is empty or unspecified or specified as "*" , it means applies any workload type. A trait must apply to at least one workload type. This attribute must contain at least one value. |
|
conflictsWith |
[]string |
N | A list of traits that would be conflict with this trait when applied to same workload type. For example, autoscaling may conflict with cron-autoscaling . |
|
definitionRef |
DefinitionRef |
Y | Identifier of the trait capability. |
DefinitionRef
identifies the trait capability, i.e. the trait implementation.
Attribute | Type | Required | Default Value | Description |
---|---|---|---|---|
name |
string |
N | Name identifier of the trait. Mutually exclusive to apiVersion and kind . |
|
apiVersion |
string |
N | API version of the trait. | |
kind |
string |
N | Kind of trait. |
It's RECOMMENDED to use Group/Version/Kind to uniquely identify the trait capability. If using definitionRef.name
, it MUST contain information that can be used to uniquely identify it.
The Application
section will describe how a user can attach traits to component in detail.
WARNING: this section is for OAM platform implementors (i.e. KubVela) only, feel free to skip this section if you are only interested in the OAM concepts.
The traits system is defined in this documentation as the way a runtime applies and manages operational behaviors to instances of components through traits.
Runtime implementations of the model MUST provide the traits system for attaching operational behaviors to instances of components.
Traits SHOULD be applied into the runtime at installation/upgrade time. Traits SHOULD NOT be checked "lazily", but SHOULD be checked when the trait-holding components are created.
When more than one trait is attached to a component, it MUST:
- Apply the traits in the defined order
- Determine compatibility, and fail if the combination of traits cannot be satisfied
Traits are applied in order such that if some set of traits express dependency (e.g. ingress must be set up before SSL), this can be resolved by setting an explicit ordering.
A component instance may only have one configuration of any given trait type.
A deployment SHOULD NOT be marked complete until all trait configurations are completed. For example, if a web server component is deployed with an autoscaler trait, the web server should not be considered "running" until (a) the web server itself is running, as determined by health checks, and (b) the autoscaler trait is running, as determined by the underlying platform.
Components can specify multiple traits; therefore, a runtime MUST support the application of zero or more traits to a component. A runtime MUST produce an error and stop deployment if the requested traits cannot be fulfilled by the underlying runtime.
There is no mechanism for explicitly requiring a combination of traits. For example, a trait (ssl
) cannot specify that it requires that another trait (ingress
) be applied to an object. However, implementations of a trait SHOULD fail if one trait cannot fulfill its contract without the presence of another trait. A system MAY support a mechanism in which a trait (sslIngress
) is opaquely backed by two separate trait implementations (ssl
and ingress
).
Any trait that is made available in a runtime MUST be implemented for that runtime. For example, there cannot be a trait for autoscaling
in a runtime with no implementation of that trait.
The traits system is designed to serve as an extension point for runtime operational capability while also providing common, and in some cases, necessary operational functionality for components.
The implementation details of a trait is beyond the scope of this document. However, to allow runtimes to implement arbitrary traits while maintaining a degree commonality for application portability across runtimes, traits are categorized in the following way:
-
Core traits. This category defines a set of trait definitions with type names in the
core.oam.dev
group. These traits provide operational functionality that is necessary for the operation of certain workload types and component features. Runtimes are REQUIRED to implement these traits as defined in this model. -
Standard traits. The category defines a set of trait definitions with type names in the
standard.oam.dev
group. These traits provide operational functionality that is commonly used by application operators and implemented by most runtimes. Runtimes are RECOMMENDED to use the standard trait definitions as defined in this model when providing equivalent operational functionality to those listed in the standard trait definitions. In other words, if a runtime is implementing trait with behaviorfoo
and a standard trait definition for behaviorfoo
exists, the runtime SHOULD use the standardfoo
trait definition. Application operators that intend to maximize portability of their applications should use these trait definitions when available. Although this does not guarantee portability of an application, it is designed to increase portability across runtimes. -
Extension traits. The category allows a runtime to define its own set of trait definitions that are unique to that runtime in addition to those defined by core and standard traits. A runtime can choose to implement any set of traits in this category with any definition. Extension trait type names MUST NOT be in the
core.oam.dev
orstandard.oam.dev
groups.
An individual trait MAY be tied to specific workloads (or MAY apply to all workloads). A trait MAY declare which workload it applies to.
The model does not set requirements about how simple or complicated a trait may be. Some might expose an expansive set of configurable options while others may expose no configurable options. And it is not required that a trait be as exhaustive as its underlying technology. For example, an implementation of an autoscaling technology may provide numerous ways of determining when a component should scale. But the trait may only surface a few of those. Likewise, multiple autoscaling traits may be defined (each uniquely named), where each trait exposes a different subset of configurable options. Or one large trait may expose all of the possible autoscaling configurations.
Implementations of an OAM platform SHOULD make all supported traits discoverable in the format explained below.
Previous Part | Next Part |
---|---|
5. Application Scopes | 7. Application |