Skip to content

Latest commit

 

History

History
164 lines (111 loc) · 11 KB

5.traits.md

File metadata and controls

164 lines (111 loc) · 11 KB

5. Traits

A trait is a discretionary runtime overlay that augments a component workload type (workloadType) with additional features. It is an opportunity for those in the application operator role to make specific decisions about the configuration of components, but without involving the developer. 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.

The traits system is defined in this specification as the way a runtime applies and manages operational behaviors to instances of components through traits.

Runtime implementations of the specification MUST provide the traits system for attaching operational behaviors to instances of components.

Traits system rules and characteristics

Traits are applied to component instances in the application configuration.

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 so that should 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.

Categories of traits

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 specification 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 specification.

  • Standard traits. The specification 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 specification when providing equivalent operational functionality to those listed in the standard trait definitions. In other words, if a runtime is implementing trait with behavior foo and a standard trait definition for behavior foo exists, the runtime SHOULD use the standard foo 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 specification 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 or standard.oam.dev groups.

Trait characteristics

An individual trait MAY be tied to specific workload types (or MAY apply to all workload types). A trait MAY declare which workload types it applies to. For example, an autoscaler trait could apply to a workload type Server, but not to type SingletonServer. The autoscaler trait itself MUST define that restriction if present.

The specification 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 runtime SHOULD make all supported traits discoverable in the format explained below.

Trait definition

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. Unlike component schematics, however, each trait definition defines its own unique [properties]((#properties) object schema to define the configuration options for the trait.

Top-Level Attributes

The top-level attributes of a trait define its metadata, version, kind, and spec.

Attribute Type Required Default Value Description
apiVersion string Y The specific version of the specification in use. At present only core.oam.dev/v1alpha1 is defined.
kind string Y The string Trait
metadata Metadata Y Trait metadata.
spec Spec Y A specification for trait attributes.

Spec

The specification defines two major things: The list of workload types to which this trait applies, and the list of configurable parameters on this trait.

Attribute Type Required Default Value Description
appliesTo []string Y ["*"] The list of workload types that this trait applies to. "*" means any workload type. A trait must apply to at least one workload type. This attribute must contain at least one value. An empty array is invalid for this attribute.
properties Properties Y The trait's configuration options. The value is a JSON schema expressed as json string

Properties

A properties object is an object whose structure is determined by the trait property schema. It may be a simple value, or it may be a complex object.

The value of the properties field in a trait definition is a JSON schema expressed as json string. When a trait is applied to a component instance, the properties are validated against the schema defined in the trait's properties attribute.

For example, if a trait defines a schema for properties that requires an array of integers with at least one member, the properties object is expected to be an array of integers with at least one member. During validation of the properties object, the trait's property schema will be applied.

Core traits

Manual Scaler

This trait definition allows operators to manually scale the number of replicas for workload types that allow scaling operations.

Applicable workload types

  • core.oam.dev/v1alpha1.Server
  • core.oam.dev/v1alpha1.Worker
  • core.oam.dev/v1alpha1.Task

Properties

Attribute Type Required Default Value Description
replicaCount integer Y 0 The target number of replicas to create for a given component instance.

Spec

apiVersion: core.oam.dev/v1alpha1
kind: Trait
metadata:
  name: ManualScaler
  annotations:
    version: v1.0.0
    description: "Allow operators to manually scale a workloads that allow multiple replicas."
spec:
  appliesTo:
    - core.oam.dev/v1alpha1.Server
    - core.oam.dev/v1alpha1.Worker
    - core.oam.dev/v1alpha1.Task
  properties: |
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "required": ["replicaCount],
      "properties": {
        "replicaCount": {
          "type": "integer",
          "description": "the target number of replicas to scale a component to.",
          "minimum": 0
        }
      }
    }
    

Usage examples

The following snippet from an application configuration shows how the manual scaler trait is applied and configured for a component. In this example, it is assumed component frontend has a workload type of core.oam.dev/v1alpha1.Server.

apiVersion: core.oam.dev/v1alpha1
kind: ApplicationConfiguration
metadata:
  name: custom-single-app
  annotations:
    version: v1.0.0
    description: "Customized version of single-app"
spec:
  variables:
  components:
    - componentName: frontend
      instanceName: web-front-end
      parameterValues:
      traits:
        - name: ManualScaler
          properties:
            replicaCount: 5

This example illustrates using the manual scaler trait to manually scale a component by specifying the number of replicas the runtime should create. This trait has only one attribute in its properties: replicaCount. This takes an integer, and a value is required for this trait to be successfully applied. If, for example, an application configuration used this trait but did not provide the replicaCount, the system would reject the application configuration.

Previous Part Next Part
4. Application Scopes 6. Application Configuration