-
Notifications
You must be signed in to change notification settings - Fork 38.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify the difference between kinds and resources in the API #4375
Merged
smarterclayton
merged 1 commit into
kubernetes:master
from
smarterclayton:clarify_resources_and_kinds
Feb 20, 2015
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,32 +3,57 @@ API Conventions | |
|
||
The conventions of the Kubernetes API (and related APIs in the ecosystem) are intended to ease client development and ensure that configuration mechanisms can be implemented that work across a diverse set of use cases consistently. | ||
|
||
The general style of the Kubernetes API is RESTful - clients create, update, delete, or retrieve a description of an object via the standard HTTP verbs (POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return JSON. Kubernetes also exposes additional endpoints for non-standard verbs and allows alternative content types. | ||
The general style of the Kubernetes API is RESTful - clients create, update, delete, or retrieve a description of an object via the standard HTTP verbs (POST, PUT, DELETE, and GET) - and those APIs preferentially accept and return JSON. Kubernetes also exposes additional endpoints for non-standard verbs and allows alternative content types. All of the JSON accepted and returned by the server has a schema, identified by the "kind" and "apiVersion" fields. | ||
|
||
The following terms are defined: | ||
|
||
* **Endpoint** a URL on an HTTP server that modifies, retrieves, or transforms a Resource. | ||
* **Resource** an object manipulated via an HTTP action in an API | ||
* **Kind** a resource has a string that identifies the schema of the JSON used (e.g. a "Car" and a "Dog" would have different attributes and properties) | ||
* **Kind** the name of a particular object schema (e.g. the "Cat" and "Dog" kinds would have different attributes and properties) | ||
* **Resource** a representation of a system entity, sent or retrieved as JSON via HTTP to the server. Resources are exposed via: | ||
* Collections - a list of resources of the same type, which may be queryable | ||
* Elements - an individual resource, addressible via a URL | ||
|
||
Types of Resources | ||
------------------ | ||
Each resource typically accepts and returns data of a single kind. A kind may be accepted or returned by multiple resources that reflect specific use cases. For instance, the kind "pod" is exposed as a "pods" resource that allows end users to create, update, and delete pods, while a separate "pod status" resource (that acts on "pod" kind) allows automated processes to update a subset of the fields in that resource. A "restart" resource might be exposed for a number of different resources to allow the same action to have different results for each object. | ||
|
||
|
||
Types (Kinds) | ||
------------- | ||
|
||
Kinds are grouped into three categories: | ||
|
||
1. **Objects** represent a persistent entity in the system. | ||
|
||
Creating an API object is a record of intent - once created, the system will work to ensure that resource exists. All API objects have common metadata. | ||
|
||
All API resources are either: | ||
An object may have multiple resources that clients can use to perform specific actions than create, update, delete, or get. | ||
|
||
1. **Objects** represents a physical or virtual construct in the system. An API object is a record of intent - once created, the system will work to ensure that resource exists. All API objects have common metadata intended for client use. | ||
2. **Lists** are collections of **objects** of one or more types. Lists have a limited set of common metadata. All lists use the "items" field to contain the array of objects they return. Each resource kind should have an endpoint that returns the full set of resources, as well as zero or more endpoints that return subsets of the full list. | ||
Examples: Pods, ReplicationControllers, Services, Namespaces, Nodes | ||
|
||
2. **Lists** are collections of **resources** of one (usually) or more (occasionally) kinds. | ||
|
||
Lists have a limited set of common metadata. All lists use the "items" field to contain the array of objects they return. | ||
|
||
Most objects defined in the system should have an endpoint that returns the full set of resources, as well as zero or more endpoints that return subsets of the full list. Some objects may be singletons (the current user, the system defaults) and may not have lists. | ||
|
||
In addition, all lists that return objects with labels should support label filtering (see [labels.md](labels.md), and most lists should support filtering by fields. | ||
|
||
Examples: PodLists, ServiceLists, NodeLists | ||
|
||
TODO: Describe field filtering below or in a separate doc. | ||
|
||
3. **Simple** kinds are used for specific actions on objects and for non-persistent entities. | ||
|
||
Given their limited scope, they have the same set of limited common metadata as lists. | ||
|
||
The "size" action may accept a simple resource that has only a single field as input (the number of things). The "status" kind is returned when errors occur and is not persisted in the system. | ||
|
||
Examples: Binding, Status | ||
|
||
The standard REST verbs (defined below) MUST return singular JSON objects. Some API endpoints may deviate from the strict REST pattern and return resources that are not singular JSON objects, such as streams of JSON objects or unstructured text log data. | ||
|
||
|
||
### Resources | ||
|
||
All singular JSON resources returned by an API MUST have the following fields: | ||
All JSON objects returned by an API MUST have the following fields: | ||
|
||
* kind: a string that identifies the schema this object should have | ||
* apiVersion: a string that identifies the version of the schema the object should have | ||
|
@@ -38,7 +63,7 @@ All singular JSON resources returned by an API MUST have the following fields: | |
|
||
#### Metadata | ||
|
||
Every object MUST have the following metadata in a nested object field called "metadata": | ||
Every object kind MUST have the following metadata in a nested object field called "metadata": | ||
|
||
* namespace: a namespace is a DNS compatible subdomain that objects are subdivided into. The default namespace is 'default'. See [namespaces.md](namespaces.md) for more. | ||
* name: a string that uniquely identifies this object within the current namespace (see [identifiers.md](identifiers.md)). This value is used in the path when retrieving an individual object. | ||
|
@@ -55,15 +80,17 @@ Labels are intended for organizational purposes by end users (select the pods th | |
|
||
#### Spec and Status | ||
|
||
By convention, the Kubernetes API makes a distinction between the specification of the desired state of a resource (a nested object field called "spec") and the status of the resource at the current time (a nested object field called "status"). The specification is persisted in stable storage with the API object and reflects user input. The status is generated at runtime and summarizes the current effect that the spec has on the system. | ||
By convention, the Kubernetes API makes a distinction between the specification of the desired state of an object (a nested object field called "spec") and the status of the object at the current time (a nested object field called "status"). The specification is persisted in stable storage with the API object and reflects user input. The status is summarizes the current state of the object in the system, and is usually persisted with the object by an automated processes (but may be created on the fly). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing I would like to add re. status, since it has come up a couple times recently: Even if persisted, status MUST be reconstructable from other sources. |
||
|
||
For example, a pod object has a "spec" field that defines how the pod should be run. The pod also has a "status" field that shows details about what is happening on the host that is running the containers in the pod (if available) and a summarized "status" string that can guide callers as to the overall state of their pod. | ||
For example, a pod object has a "spec" object field that defines how the pod should be run. The pod also has a "status" object field that shows details about what is happening on the host that is running the containers in the pod (if available) and a summarized "phase" string that indicates where the pod is in its lifecycle. | ||
|
||
When a new version of an object is POSTed or PUT, the "spec" is updated and available immediately. Over time the system will work to bring the "status" into line with the "spec". The system will drive toward the most recent "spec" regardless of previous versions of that stanza. In other words, if a value is changed from 2 to 5 in one PUT and then back down to 3 in another PUT the system is not required to 'touch base' at 5 before changing the "status" to 3. | ||
|
||
The PUT and POST verbs will ignore the "status" values. Otherwise, PUT expects the whole object to be specified. Therefore, if a field is omitted it is assumed that the client wants to clear that field's value. | ||
The PUT and POST verbs on objects will ignore the "status" values. Otherwise, PUT expects the whole object to be specified. Therefore, if a field is omitted it is assumed that the client wants to clear that field's value. | ||
|
||
Modification of just part of an object may be achieved by GETting the resource, modifying part of the spec, labels, or annotations, and then PUTting it back. See [concurrency control](#concurrency-control-and-consistency), below, regarding read-modify-write consistency when using this pattern. Some objects may expose alternative resource representations that allow mutation of the status, or performing custom actions on the object. | ||
|
||
Modification of just part of an object may be achieved by GETting the resource, modifying part of the spec, labels, or annotations, and then PUTting it back. See [concurrency control](#concurrency-control-and-consistency), below, regarding read-modify-write consistency when using this pattern. | ||
All objects that represent a physical resource whose state may vary from the user's desired intent SHOULD have a "spec" and a "status". Objects whose state cannot vary from the user's desired intent MAY have only "spec", and MAY rename "spec" to a more appropriate name. | ||
|
||
#### Lists of named subobjects preferred over maps | ||
|
||
|
@@ -84,27 +111,36 @@ ports: | |
|
||
This rule maintains the invariant that all JSON/YAML keys are fields in API objects. The only exceptions are pure maps in the API (currently, labels, selectors, and annotations), as opposed to sets of subobjects. | ||
|
||
### Lists | ||
|
||
Every list SHOULD have the following metadata in a nested object field called "metadata": | ||
### Lists and Simple kinds | ||
|
||
Every list or simple kind SHOULD have the following metadata in a nested object field called "metadata": | ||
|
||
* resourceVersion: a string that identifies the common version of the objects returned by in a list. This value MUST be treated as opaque by clients and passed unmodified back to the server. A resource version is only valid within a single namespace on a single kind of resource. | ||
|
||
Every simple kind returned by the server, and any simple kind sent to the server that must support idempotency or optimistic concurency should return this value.Since simple resources are often used as input alternate actions that modify objects, the resource version of the simple resource should correspond to the resource version of the object. | ||
|
||
Special Resources | ||
----------------- | ||
|
||
Kubernetes MAY return two resources from any API endpoint in special circumstances. Clients SHOULD handle these types of objects when appropriate. | ||
Returning Errors | ||
---------------- | ||
|
||
A "Status" object SHOULD be returned by an API when an operation is not successful (when the server would return a non 2xx HTTP status code). The status object contains fields for humans and machine consumers of the API to determine failures. The information in the status object supplements, but does not override, the HTTP status code's meaning. | ||
Kubernetes MAY return the Status kind from any API endpoint. Clients SHOULD handle these types of objects when appropriate. | ||
|
||
A Status kind SHOULD be returned by an API when an operation is not successful (when the server would return a non 2xx HTTP status code). The status object contains fields for humans and machine consumers of the API to determine failures. The information in the status object supplements, but does not override, the HTTP status code's meaning. | ||
|
||
TODO: More details (refer to another doc for details) | ||
|
||
|
||
Synthetic Resources | ||
------------------- | ||
Differing Representations | ||
------------------------- | ||
|
||
An API may represent a single entity in different ways for different clients, or transform an object after certain transitions in the system occur. In these cases, one request object may have two representations available as different resources, or different kinds. | ||
|
||
An example is a Service, which represents the intent of the user to group a set of pods with common behavior on common ports. When Kubernetes detects a pod matches the service selector, the IP address and port of the pod are added to an Endpoints resource for that Service. The Endpoints resource exists only if the Service exists, but exposes only the IPs and ports of the selected pods. The full service is represented by two distinct resources - under the original Service resource the user created, as well as in the Endpoints resource. | ||
|
||
An API may represent a single object in different ways for different clients, or transform an object after certain transitions in the system occur. In these cases, one request object may have two representations available as different resource kinds. An example is a Pod, which represents the intent of the user to run a container with certain parameters. When Kubernetes schedules the Pod, it creates a Binding object that ties that Pod to a single host in the system. After this occurs, the pod is represented by two distinct resources - under the original Pod resource the user created, as well as in a BoundPods object that the host may query but not update. | ||
As another example, a "pod status" resource may accept a PUT with the "pod" kind, with different rules about what fields may be changed. | ||
|
||
Future versions of Kubernetes may allow alternative encodings of objects beyond JSON. | ||
|
||
|
||
Verbs on Resources | ||
|
@@ -118,14 +154,16 @@ API resources should use the traditional REST pattern: | |
* DELETE /<resourceNamePlural>/<name> - Delete the single resource with the given name. | ||
* PUT /<resourceNamePlural>/<name> - Update or create the resource with the given name with the JSON object provided by the client. | ||
|
||
Kubernetes by convention exposes additional verbs as new endpoints with singular names. Examples: | ||
Kubernetes by convention exposes additional verbs as new root endpoints with singular names. Examples: | ||
|
||
* GET /watch/<resourceNamePlural> - Receive a stream of JSON objects corresponding to changes made to any resource of the given kind over time. | ||
* GET /watch/<resourceNamePlural>/<name> - Receive a stream of JSON objects corresponding to changes made to the named resource of the given kind over time. | ||
* GET /redirect/<resourceNamePlural>/<name> - If the named resource can be described by a URL, return an HTTP redirect to that URL instead of a JSON response. For example, a service exposes a port and IP address and a client could invoke the redirect verb to receive an HTTP 307 redirection to that port and IP. | ||
* GET /proxy/<resourceNamePlural>/<name>/{subpath:*} - Proxy GET request to the named resource of the given kind. Can be used for example, to access log files on pods. | ||
|
||
Support of additional verbs is not required for all object types. | ||
These are verbs which change the fundamental type of data returned (watch returns a stream of JSON instead of a single JSON object). Support of additional verbs is not required for all object types. | ||
|
||
When resources wish to expose alternative actions that are closely coupled to a single resource, they should do so using new sub-resources. An example is allowing automated processes to update the "status" field of a Pod. The `/pods` endpoint only allows updates to "metadata" and "spec", since those reflect end-user intent. An automated process should be able to modify status for users to see by sending an updated Pod kind to the server to the "/pods/<name>/status" endpoint - the alternate endpoint allows different rules to be applied to the update, and access to be appropriately restricted. Likewise, some actions like "stop" or "resize" are best represented as REST sub-resources that are POSTed to. The POST action may require a simple kind to be provided if the action requires parameters, or function without a request body. | ||
|
||
TODO: more documentation of Watch | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we actually going to use ListMeta, or just populate a subset of ObjectMeta, or will it depend on whether the schema of an object is reused (as in status) or not (as in binding)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ListMeta (poorly named though it is), seems appropriate. Status doesn't really have a name or namespace or labels or annotations, so I think our initial call on ListMeta vs Object was accurate. Maybe we rename ListMeta to SimpleMeta eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. SimpleMeta, BasicMeta, SchemaMeta, KindMeta ...