Extending the Kubernetes API

Kubernetes is an extremely flexible and extensible platform. It even allows you to extend its own API with new types of resources called third-party-resources. What can you do with third-party-resources? Plenty. You can use them to manage through the Kubernetes API resources that live outside the Kubernetes cluster, but your pods communicate with. By adding those external resources as third-party-resources, you get a full picture of your system and you benefit from many Kubernetes API features such as the following:

  • Custom CRUD REST endpoints
  • Versioning
  • Watches
  • Automatic integration with generic Kubernetes tooling

Other use cases for third-party-resources are metadata for custom controllers and automation programs.

Let's dive in and see what third-party-resources are all about.

Understanding the structure of a third-party-resource

In order to play nice with the Kubernetes API server, third-party-resources must conform to some basic requirements. Similar to built-in API objects, they must have the following fields:

  • metadata: Standard Kubernetes object metadata
  • kind: The kind of resources described by this third-party-resource
  • description: A free text description of the resource
  • versions: A list of the versions of the resource

The kind field requires some explanation. Kubernetes uses CamelCase for resource types. The kind field must be of the form <kind name>.<domain>. The kind name should be all lowercase with hyphens between words. Kubernetes will transform it to a CamelCase resource kind. For example, awesome-resource will become AwesomeResource.

Beyond these fields, you can add any fields you want and store arbitrary JSON to create any structure you like.

Developing third-party-resources

It's important to distinguish between the third-party-resource that you define, which is not bound to a namespace, and the actual object that you create, which is always bound to a namespace. Currently, Kubernetes doesn't support namespace-less custom objects based on third-party-resources. Here is an example of a third-party-resource:

apiVersion: extensions/v1beta1
kind: ThirdPartyResource
metadata:
name: cron-tab.stable.example.com
description: A pod that runs on schedule
versions:
name: v1

It has all the required fields: kind, metadata, description, and versions. It also has apiVersion field to associate it with the extensions/v1beta1 API group.

Let's create it:

$ k create -f 3rd-party-resource.yaml
thirdpartyresource "cron-tab.stable.example.com" created

Now, let's verify we can access it:

$ kubectl get thirdpartyresources
NAME                        DESCRIPTION                 VERSION(S)
cron-tab.stable.example.com A pod that runs on schedule v1

There is also a new API endpoint for managing this new resource:

/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/

Let's use our Python code to access it:

>>> config.load_kube_config()
>>> print(k('get', 'thirdpartyresources'))
NAME                          DESCRIPTION                   VERSION(S)
cron-tab.stable.example.com   A pod that runs on schedule   v1

Integrating third party resources

Once the ThirdPartyResource object has been created, you can create custom objects of that resource kind, in particular, CronTab in this case (CronTab becomes CamelCase CronTab). CronTab objects can contain arbitrary fields with arbitrary JSON. In the following example, cronSpec and image custom fields are set on the CronTab object. Also, the stable.example.com API group is derived from the metadata.name of the ThirdPartyResource:

apiVersion: stable.example.com/v1
kind: CronTab
metadata:
name: new-cron-object
cronSpec: * * * * /5
image: my-awesome-cron-image

Let's create it:

$ kubectl create -f crontab.yaml
crontab "new-cron-object" created

At this point, kubectl can operate on CronTab objects just like it works on built-in objects. Note that resource names are case-insensitive when using kubectl:

$ kubectl get crontab
NAME                 LABELS    DATA
new-cron-object      <none>    {"apiVersion":"stable.example.com/v1","cronSpec":"...

We can also view the raw JSON data using the standard -o json flag.:

$ kubectl get crontab -o json
{
    "kind": "List",
    "apiVersion": "v1",
    "metadata": {},
    "items": [
        {
            "apiVersion": "stable.example.com/v1",
            "cronSpec": "* * * * /5",
            "image": "my-awesome-cron-image",
            "kind": "CronTab",
            "metadata": {
                "creationTimestamp": "2016-09-29T04:59:00Z",
                "name": "new-cron-object",
                "namespace": "default",
                "resourceVersion": "12601503",
                "selfLink": "/apis/stable.example.com/v1/namespaces/default/crontabs/new-cron-object",
                "uid": "6f65e7a3-8601-11e6-a23e-42010af0000c"
            }
        }
    ]
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset