What is a Resource
A Kubernetes Resource is a declarative API with a well defined Schema structure and endpoints. Because the structure of the Schema and Endpoints are predictable and structured, most Kubernetes tools work with any Kubernetes API even if they are not part of the core (e.g. extensions through CRDs).
What is a Declarative API
A declarative API expresses a fixed state that the cluster must continually
work towards. Declarative APIs define the what, but not the how.
$ replicas 3
An imperative API expresses an operation that may change state, but does not
define an absolute state that must be maintained. Imperative APIs express the
how, but not what. Example:
$ add-pods 2.
In the declarative case, if a replica is lost the cluster has a clear directive to create another one, whereas in the latter case this is not necessarily true.
Declarative API usage example by invoking
# object.yaml contains an object declaration $ kubectl apply -f object.yaml
Constraints on the how may be defined within declarative APIs, such as performing a rolling update versus deleting and recreating all Pods immediately.
Group, Version, Kind
Every Kubernetes resource has a Group, Version and Kind that uniquely identifies it.
- The resource Kind is the name of the API - such as Deployment or Service.
- The resource Version defines the stability of the API and backward compatibility guarantees - such as v1beta1 or v1.
- The resource Group is similar to package in a language. It disambiguates different APIs that may happen to have identically named Kinds. Groups often contain a domain name, such as k8s.io.
Deployment yaml config Group Version Kind
apiVersion: apps/v1 kind: Deployment
Resources with different Versions but the same Group and Kind differ in the following ways:
- Unspecified fields may have different defaults
- The same logical fields may have different names or representations
However resources with different versions frequently share the same features and controller.
Alpha APIs may break backwards compatibility by changing field names, defaults or behavior. They also may not be supported in the future.
Beta APIs maintain backwards compatibility on field names, defaults and behavior. They may be missing features required for GA. However once the API goes GA, the features should be available in the Beta version.
GA APIs have been available and running in production for sufficient time to have developed a stable set of field names and defaults, as well as a complete feature set.
Spec, Status, Metadata
Most Kubernetes Resource Schemas contain 3 components: Spec, Status and Metadata
Spec: the Resource Spec defines the desired state of the cluster as specified by the user.
Status: the Resource Status publishes the state of the cluster as observed by the controller.
Metadata: the Resource Metadata contains information common to most resources about the object including as the object name, annotations, labels and more.
Note: this config has been abbreviated for the purposes of display
Deployment yaml config with Spec Status and Metadata
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx namespace: default spec: replicas: 1 template: spec: containers: - image: nginx name: nginx status: replicas: 1 unavailableReplicas: 1 updatedReplicas: 1
The resource Status should not contain the source of truth for any information, and should be
possible for Controllers to recreate by looking at the cluster state. Other values assigned by
Controllers, such as the Service
spec.clusterIp, should be set on the Spec not the Status.
Kubernetes Resources have well defined endpoints as described below.
Create, Update, Patch, Delete
The create, update, patch and delete endpoints may be used to modify objects. The update endpoint replaces the object with what is provided, whereas the patch endpoint selectively updates fields.
Get, List, Watch
The get, list and watch endpoints may be used to get a specific resource by name, list all resources matching a labels, or continually watch for updates.
Deployment Endpoints under
name: "deployments" kind: "Deployment" verbs: - "create" - "delete" - "deletecollection" - "get" - "list" - "patch" - "update" - "watch"
When reading objects, the same objects should be returned regardless of which version of the API endpoint is read from (though the structure may differ between versions).
When writing objects, the default values applied to fields may change between API versions, but the written object should be visible when read from any version.
The update API should only be used to read-then-write an object, and never used to update an object directly from declarative config. This is because the object state may be partially managed by Controllers running in the cluster and this state would be lost when the update replaces the current object with the declarative config.
Illustrative example: updating a Service from declarative config rather than a read-then-write
would clear the Service
spec.clusterIp field set by the controller.
If used directly, a watch API call will timeout and need to be re-established. The kubebuilder libraries hide the details behind watches from users and automatically re-establish connections.
While most operations can be represented declaratively, some may not, such as logs, attach or exec. These operations may be implemented as subresources.
Subresources are functions attached to resources, but that have their own Schema and Endpoints. By having different resources each implement the same subresource API, resources can implemented shared interfaces.
For example Deployment, ReplicaSet and StatefulSet each implement the scale subresource API, making it easy to build tools which scale any of them as well as scale any other resources that implement the scale subresource.
Deployment Scale Subresource Endpoints under
name: "deployments/scale" group: "autoscaling" version: "v1" kind: "Scale" verbs: - "get" - "patch" - "update"
Labels, Selectors and Annotations
Labels in ObjectMeta data are key-value pairs that may be queried to find matching objects. Labels are used to connect objects together in a Kubernetes cluster. For instance Services use labels to determine which Pods to direct traffic to, and Deployments use labels (along with OwnersReferences) to identify Pods they created.
Annotations allow arbitrary data to be written to resources that may not fit within the Schema of the resource, but may be needed by end users or tools.
Annotations may be used to define new extension fields on resources without modifying the Schema of the object. This allows users to define their own private schema extensions for existing core Kubernetes resources.
While most resources are Namespaced, that is the objects are scoped to a Namespace, some resources are non-namespaced and scoped to the cluster. Examples of non-namespaced resources include Nodes, Namespaces and ClusterRole.