Chapter 21. Extending the Kubernetes API with Custom Resources
In the Kubernetes API a resource is an endpoint that stores a collection of API objects of a certain kind. For example, the built-in pods resource contains a collection of Pod objects.
A custom resource is an object that extends the Kubernetes API or allows you to introduce your own API into a project or a cluster.
A custom resource definition (CRD) file defines your own object kinds and lets the API Server handle the entire lifecycle. Deploying a CRD into the cluster causes the Kubernetes API server to begin serving the specified custom resource.
When you create a new custom resource definition (CRD), the Kubernetes API Server reacts by creating a new RESTful resource path, that can be accessed by an entire cluster or a single project (namespace). As with existing built-in objects, deleting a project deletes all custom objects in that project.
21.1. Creating Custom Resource Definitions
To create a CRD, open a YAML file and enter the fields in the following example.
Example YAML file for a Custom Resource Definition
apiVersion: apiextensions.k8s.io/v1beta1 1 kind: CustomResourceDefinition metadata: name: crontabs.stable.example.com 2 spec: group: stable.example.com 3 version: v1 4 scope: Namespaced 5 names: plural: crontabs 6 singular: crontab 7 kind: CronTab 8 shortNames: - ct 9
- 1
- Use the
apiextensions.k8s.io/v1beta1API. - 2
- Specify a name for the definition. This must be in the <plural-name><group> format using the values from the
groupandpluralfields. - 3
- Specify a group name for the API. An API group is a collection of objects that are logically related. For example, all batch objects like
JoborScheduledJobcould be in the batch API Group (such as batch.api.example.com). A good practice is to use a fully-qualified-domain name of your organization. - 4
- Specify a version name to be used in the URL. Each API Group can exist in multiple versions. For example:
v1alpha,vibeta,v1. - 5
- Specify whether the custom objects are available to a project (
Namespaced) or all projects in the cluster (Cluster). - 6
- Specify the plural name to be used in the URL. The
pluralfield is the same as a resource in an API URL. - 7
- Specify a singular name to be used as an alias on the CLI and for display.
- 8
- Specify the kind of objects that can be created. The type can be in CamelCase.
- 9
- Specify a shorter string to match your resource on the CLI.
By default, a custom resource definition is cluster-scoped and available to all projects.
After configuring the definition file, create the object:
oc create -f <file-name>.yaml
A new RESTful API endpoint is created at:
/apis/<spec:group>/<spec:version>/<scope>/*/<names-plural>/...
For example, using the example file, the following endpoint would be created:
/apis/stable.example.com/v1/namespaces/*/crontabs/...
This endpoint URL can then be used to create and manage custom objects. The kind of object is based on the spec.kind field of the Custom Resource Definition object you created.
21.2. Create Custom Objects
After the custom resource definition object has been created, you can create custom objects.
Custom objects can contain custom fields. These fields can contain arbitrary JSON.
In the following example, the cronSpec and image custom fields are set in a custom object of kind CronTab. The kind CronTab comes from the spec.kind field of the custom resource definition object you created above.
Example YAML file for a Custom Object
apiVersion: "stable.example.com/v1" 1 kind: CronTab 2 metadata: name: my-new-cron-object 3 spec: 4 cronSpec: "* * * * /5" image: my-awesome-cron-image
After configuring the object file, create the object:
oc create -f <file-name>.yaml
21.3. Manage Custom Objects
You can then manage your custom resources.
To get information on a specific kind of custom resource, enter:
oc get <kind>
For example:
oc get crontab NAME KIND my-new-cron-object CronTab.v1.stable.example.com
Note that resource names are not case-sensitive, and you can use either the singular or plural forms defined in the CRD, as well as any short name. For example:
oc get crontabs oc get crontab oc get ct
You can also view the raw JSON data:
oc get <kind> -o yaml
You should see that it contains the custom <1> cronSpec and <2> image fields from the YAML you used to create it:
oc get ct -o yaml
apiVersion: v1
items:
- apiVersion: stable.example.com/v1
kind: CronTab
metadata:
clusterName: ""
creationTimestamp: 2017-05-31T12:56:35Z
deletionGracePeriodSeconds: null
deletionTimestamp: null
name: my-new-cron-object
namespace: default
resourceVersion: "285"
selfLink: /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object
uid: 9423255b-4600-11e7-af6a-28d2447dc82b
spec:
cronSpec: '* * * * /5' 1
image: my-awesome-cron-image 221.4. Finalizers
Custom objects support finalizers, which allow controllers to implement conditions that must be completed before the object can be deleted.
You can add a finalizer to a custom object like this:
apiVersion: "stable.example.com/v1" kind: CronTab metadata: finalizers: - finalizer.stable.example.com
The first delete request on an object with finalizers sets a value for the metadata.deletionTimestamp field instead of deleting the object. This triggers controllers watching the object to execute any finalizers they handle.
Each controller then removes the finalizer from the list and issues the delete request again. This request deletes the object only if the list of finalizers is empty, meaning all finalizers are done.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.