In the first two parts of this series we describe the overall process of API server and how the API objects are stored in ETCD. In this article we will explore how to extend the API resources.
In the beginning, the only way to extend the API resources is to extend the relevant API source code and integrate it into the resources you need. Or, push a whole new type into the community code for the new core object API. However, this can lead to a constant increase in the core API resource types until the API is overloaded. To avoid the unrestricted expansion of this API resource, there are two ways to extend the core API in Kubernetes:
- Using a custom resource definition (CRDs), the first time is called a third-party resource (TPRS). By using CRD, you can define your own resource object types in a simple and flexible way and have the API server handle the entire lifecycle.
- Use a user API Servers (UAS) that runs in parallel with the main API Servers. This way, perhaps more design code development, you may need to devote more time and effort. Of course, this approach also allows you to have a more detailed and comprehensive understanding of API resources.
In this article, we mainly discuss the definition and use of CRD.
Declaration and creation of CRDs
As mentioned in the first part of this series, each API resource is categorized according to the group group, and each object has a corresponding version number associated with the HTTP path. Now if you want to implement a CRD, the first thing you need is to name a new API group group, this API group cannot be duplicated with existing groups. In your own new API group, you can have any number of resources, and they can have the same name as the resources in other groups. Let's cite a practical example:
As we have described before, each version of the Kubernetes resource managed by the API group is related to the HTTP path. CRD is similar to the definition of a class in object-oriented programming, and the actual CR used can be seen as a set of instances of it. First we describe some of the fields in the example, and the CRD apiversion in the first line is defined after Kube-apiserver 1.7. From line 5th we define the relevant fields of the spec. In line 6th Spec.group is the API group that defines the CRD you created (as defined in this example in order to example.com). Line 7th defines the version of the CRD object. There is only one fixed version per resource, but there are several different versions of resources in the API group. The 8th line of Spec.names has two required fields: kind, in accordance with the customary first letter capitalization, plural, by convention all lowercase, this field is related to the final generated HTTP path, for example, in this case, the final HTTP path is https://<server/ Apis/example.com/v1/namespaces/default/databases. There is also an optional singular field, which defaults to a lowercase type value that can be used in the context of KUBECTL. In addition, there are many optional fields in Spec.names that will be automatically generated and populated by the API server.
The kind above is primarily used to describe the type of object, while the resource resource is associated with an HTTP path. In most cases, these two are matched, but in some specific cases the same API HTTP path may return kind (such as the status Error object will return another kind).
It is important to note that the resource resource (in this case, databases) and group group (example.com in this case) must match the Metadata.name field (in this case, line fourth databases. example.com).
Now we create a CRD based on the Yaml file above:
$ kubectl create-f Databases-crd.yaml
Customresourcedefinition "Databases.example.com" created
Since this creation process is asynchronous, you must check the status of the CRD you created, confirming that the CRD you created does not conflict with other resources, and that API server has called the relevant handler to complete the creation. You can do this in a script or in code by polling. Finally we can get the following status:
$ kubectl Get CRD databases.example.com-o Yaml
Apiversion:apiextensions.k8s.io/v1beta1
Kind:customresourcedefinition
Metadata
creationtimestamp:2017-08-09t09:21:43z
Name:databases.example.com
Resourceversion: "792"
Selflink:/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/databases.example.com
Uid:28c94a05-7ce4-11e7-888c-42010a9a0fd5
Spec
Group:example.com
Names
Kind:database
Listkind:databaselist
Plural:databases
Singular:database
scope:namespaced
Version:v1
Status
Acceptednames:
Kind:database
Listkind:databaselist
Plural:databases
Singular:database
Conditions
- lasttransitiontime:null
message:no conflicts found
reason:noconflicts
Status: "True"
Type: namesaccepted
- lasttransitiontime:2017-08-09t09:21:43z
message:the Initial names have been accepted
reason:initialnamesaccepted
Status: "True"
type:established
above, we can see that through kubectl we can see the CRD we created before, And it shows some status information of CRD.
CRDs use
after opening the kubernetes API via Kubectl Proxy to the local agent, view the CRD we just created:
$ http 127.0.0.1:8001/apis/example.com
http/1.1 OK
content-length:223
Content-type:application/json
date:wed, 09:25:44 GMT
{
"Apiversion": "V1",
"Kind": "Apigroup",
"Name": "example.com",
"Preferredversion": {
"Groupversion": "Example.com/v1",
"Version": "V1"
},
"Serveraddressbyclientcidrs": null,
"Versions": [
{
"Groupversion": "Example.com/v1",
"Version": "V1"
}
]
}
Note that in 10 minutes by default, Kubectl is viewing the cache stored in the ~/.kube/cache/discovery directory. So it may take 10 minutes before you can see your newly created CRD resource. However, when there is no cache, Kubectl does not find the resource it needs, and then it caches it again.
Next, let's look at an instance of CRD:
$ cat Wordpress-database.yaml
Apiversion:example.com/v1
Kind:database
Metadata
Name:wordpress
Spec
User:wp
Password:secret
Encoding:unicode
$ kubectl create-f Wordpress-databases.yaml
Database "WordPress" created
$ kubectl Get databases.example.com
NAME KIND
WordPress Database.v1.example.com
To monitor the creation and updating of resources through the API, you can monitor watch by modifying a resourceversion (we monitor the specified version of database via Curl).
$ http 127.0.0.1:8001/apis/example.com/v1/namespaces/default/databases
http/1.1 OK
content-length:593
Content-type:application/json
date:wed, 09:38:49 GMT
{
"Apiversion": "Example.com/v1",
"Items": [
{
"Apiversion": "Example.com/v1",
"Kind": "Database",
"Metadata": {
"ClusterName": "",
"Creationtimestamp": "2017-08-09t09:38:30z",
"Deletiongraceperiodseconds": null,
"Deletiontimestamp": null,
"Name": "WordPress",
"namespace": "Default",
"Resourceversion": "2154",
"Selflink": "/apis/example.com/v1/namespaces/default/databases/wordpress",
"UID": "8101A7AF-7CE6-11E7-888C-42010A9A0FD5"
},
"Spec": {
"Encoding": "Unicode",
"Password": "Secret",
"User": "WP"
}
}
],
"Kind": "Databaselist",
"Metadata": {
"Resourceversion": "2179",
"Selflink": "/apis/example.com/v1/namespaces/default/databases"
}
}
We can use the "resourceversion" of the/APIS/EXAMPLE.COM/V1/NAMESPACES/DEFAULT/DATABASES/WORDPRESSCRD HTTP path via the Curl command: "2154" To monitor Watch:
$ curl-f 127.0.0.1:8001/apis/example.com/v1/namespaces/default/databases?watch=true&resourceversion=2154
Now we open a new Shell dialog window, delete the WordPress CRD resources, we can see just the Monitoring Watch window received this message:
$ kubectl Delete databases.example.com/wordpress
Please note: We are able to delete the CRD resource using KUBECTL Delete database WordPress because there is no database resource defined previously in Kubernetes. In addition, database is the Spec.name.singular field in our CRD, derived from English grammar.
We can see the update status returned from API server before monitoring watch CRD databases:
{"type": "DELETED", "Object": {"apiversion": "Example.com/v1", "kind": "Database", "metadata": {"clustername": "", " Creationtimestamp ":" 2017-0[0/515]
: 38:30z "," deletiongraceperiodseconds ": null," Deletiontimestamp ": null," name ":" WordPress "," namespace ":" Default "," Resourceversion ":" 2154 "," Selflink ":"/apis/example.com/v1/namespaces/
Default/databases/wordpress "," UID ":" 8101a7af-7ce6-11e7-888c-42010a9a0fd5 "}," spec ": {" encoding ":" Unicode "," Password ":" Secret "," user ":" WP "}}}
The operation and output of the above shell session are as follows:
Finally, let's look at how the various data of the CRD database are stored in ETCD. Here's what we get from accessing ETCD directly through the HTTP API:
$ curl-s Localhost:2379/v2/keys/registry/example.com/databases/default | JQ.
{
"Action": "Get",
"Node": {
"Key": "/registry/example.com/databases/default",
"dir": true,
"Nodes": [
{
"Key": "/registry/example.com/databases/default/wordpress",
"Value": "{\" apiversion\ ": \" example.com/v1\ ", \" kind\ ": \" database\ ", \" Metadata\ ": {\" clustername\ ": \" \ ", \" Creationtimestamp\ ": \" 2017-08-09t14:53:40z\ ", \" deletiongraceperiodseconds\ ": Null,\" deletiontimestamp\ ": null,\" Name\ ": \" Wordpress\ ", \" namespace\ ": \" default\ ", \" selflink\ ": \" \ ", \" uid\ ": \" 8837f788-7d12-11e7-9d28-080027390640\ "},\" spec\ ": {\" encoding\ ": \" unicode\ ", \" password\ ": \" secret\ ", \" User\ ": \" Wp\ "}}\n",
"Modifiedindex": 670,
"Createdindex": 670
}
],
"Modifiedindex": 670,
"Createdindex": 670
}
}
As can be seen from the above, the CRD data in the ETCD finally in an unresolved state exists. Now the CRD is deleted, all the CRD instances are also deleted, this is a cascade delete operation.
Current status, limitations and future prospects of crds
The development status of CRDs is as follows:
- In the Kubernetes 1.7 release crds began to replace Thirdpartyresources (TPRS), and Tprs will be removed in kubernetes 1.8.
- Migrating Tprs to an CRDs instance can refer to document migration.
- Support for a single version of the CRD, of course, there may be multiple version versions in a group.
- CRDs provides an API solution that is basically no different from the user's point of view with Kubernetes native API resources
- CRDs is the basis for multi-version multi-branch stability. The format validation of Json-schema for CRD resources can refer to the document CRD validation proposal. Refer to document garbage collection for related resource recycling.
Next, let's look at some CRDs limitations:
- CRD does not provide version conversion functionality, that is, there can be only one version per CRD (not expected to be seen in the near or medium term to support CRD version conversions).
- In Kubernetes1.7, there is no correlation check validation for CRD at present.
- There is no fast, real-time access (admission) mechanism (but can support webhooks form of initialization and access).
- In Kubernetes1.7 you cannot define sub-resources (sub-resources), such as scale or status, but there is a proposal discussion in this area.
- CRD does not currently support default configuration, that is, it is not supported to have a default value for a specific field (which may be supported in subsequent versions of Kubernetes1.7).
To solve the above problem, and flexibly extend the kubernetes, you can run a user API Servers that is parallel to the main API server. We'll detail how to write a UAS in a later section of this blog post, and write a custom controller to fully use CRD. Https://www.huaweicloud.com/product/cce.html
Deep anatomy kubernetes API Server Trilogy-Part 3