Custom resource docs
This commit is contained in:
parent
d8f5b4f8a4
commit
171a5aeddf
|
|
@ -23,6 +23,7 @@ toc:
|
|||
|
||||
- title: Extending the Kubernetes API
|
||||
section:
|
||||
- docs/concepts/api-extension/custom-resources.md
|
||||
- docs/concepts/api-extension/apiserver-aggregation.md
|
||||
|
||||
- title: Containers
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ toc:
|
|||
- docs/tasks/access-kubernetes-api/http-proxy-access-api.md
|
||||
- docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
|
||||
- docs/tasks/access-kubernetes-api/extend-api-third-party-resource.md
|
||||
- docs/tasks/access-kubernetes-api/migrate-third-party-resource.md
|
||||
- docs/tasks/access-kubernetes-api/configure-aggregation-layer.md
|
||||
- docs/tasks/access-kubernetes-api/setup-extension-api-server.md
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
title: Custom Resources
|
||||
assignees:
|
||||
- enisoc
|
||||
- deads2k
|
||||
---
|
||||
|
||||
{% capture overview %}
|
||||
This page explains the concept of *custom resources*, which are extensions of the Kubernetes API.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture body %}
|
||||
## Custom resources
|
||||
|
||||
A *resource* is an endpoint in the [Kubernetes API](/docs/reference/api-overview/) that stores a
|
||||
collection of [API objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/) of a
|
||||
certain kind.
|
||||
For example, the built-in *pods* resource contains a collection of Pod objects.
|
||||
|
||||
A *custom resource* is an extension of the Kubernetes API that is not necessarily available on every
|
||||
Kubernetes cluster.
|
||||
In other words, it represents a customization of a particular Kubernetes installation.
|
||||
|
||||
Custom resources can appear and disappear in a running cluster through dynamic registration,
|
||||
and cluster admins can update custom resources independently of the cluster itself.
|
||||
Once a custom resource is installed, users can create and access its objects with
|
||||
[kubectl](/docs/user-guide/kubectl-overview/), just as they do for built-in resources like *pods*.
|
||||
|
||||
## Custom controllers
|
||||
|
||||
On their own, custom resources simply let you store and retrieve structured data.
|
||||
It is only when combined with a *controller* that they become a true
|
||||
[declarative API](/docs/concepts/overview/working-with-objects/kubernetes-objects/#understanding-kubernetes-objects).
|
||||
The controller interprets the structured data as a record of the user's desired state,
|
||||
and continually takes action to achieve and maintain that state.
|
||||
|
||||
A *custom controller* is a controller that users can deploy and update on a running cluster,
|
||||
independently of the cluster's own lifecycle.
|
||||
Custom controllers can work with any kind of resource, but they are especially effective when
|
||||
combined with custom resources.
|
||||
The [Operator](https://coreos.com/blog/introducing-operators.html) pattern is one example of such a
|
||||
combination. It allows developers to encode domain knowledge for specific applications into an
|
||||
extension of the Kubernetes API.
|
||||
|
||||
## CustomResourceDefinitions
|
||||
|
||||
[CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
|
||||
(CRD) is a built-in API that offers a simple way to create custom resources.
|
||||
Deploying a CRD into the cluster causes the Kubernetes API server to begin serving the specified
|
||||
custom resource on your behalf.
|
||||
|
||||
This frees you from writing your own API server to handle the custom resource,
|
||||
but the generic nature of the implementation means you have less flexibility than with
|
||||
[API server aggregation](#api-server-aggregation).
|
||||
|
||||
CRD is the successor to the deprecated *ThirdPartyResource* (TPR) API, and is available as of
|
||||
Kubernetes 1.7.
|
||||
|
||||
## API server aggregation
|
||||
|
||||
Usually, each resource in the Kubernetes API requires code that handles REST requests and manages
|
||||
persistent storage of objects.
|
||||
The main Kubernetes API server handles built-in resources like *pods* and *services*,
|
||||
and can also handle custom resources in a generic way through [CustomResourceDefinitions](#customresourcedefinitions).
|
||||
|
||||
The [aggregation layer](/docs/concepts/api-extension/) allows you to provide specialized
|
||||
implementations for your custom resources by writing and deploying your own standalone API server.
|
||||
The main API server delegates requests to you for the custom resources that you handle,
|
||||
making them available to all of its clients.
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% capture whatsnext %}
|
||||
* Learn how to [Extend the Kubernetes API with the aggregation layer](/docs/concepts/api-extension/apiserver-aggregation/).
|
||||
* Learn how to [Extend the Kubernetes API with CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
|
||||
* Learn how to [Migrate a ThirdPartyResource to CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/).
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/concept.md %}
|
||||
|
|
@ -82,9 +82,10 @@ Currently there are several API groups in use:
|
|||
(e.g. `apiVersion: batch/v1`). Full list of supported API groups can be seen in [Kubernetes API reference](/docs/reference/).
|
||||
|
||||
|
||||
There are two supported paths to extending the API.
|
||||
1. [Third Party Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/extending-api.md)
|
||||
are for users with very basic CRUD needs.
|
||||
There are two supported paths to extending the API with [custom resources](/docs/concepts/api-extension/custom-resources/):
|
||||
|
||||
1. [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
|
||||
is for users with very basic CRUD needs.
|
||||
1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver
|
||||
and use the [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/aggregated-api-servers.md)
|
||||
to make it seamless for clients.
|
||||
|
|
|
|||
|
|
@ -154,11 +154,9 @@ kubectl delete replicaset my-repset --cascade=false
|
|||
```
|
||||
|
||||
## Known issues
|
||||
* In 1.6, garbage collection does not support non-core resources, e.g.,
|
||||
resources added via ThirdPartyResource or via aggregated API servers. It will
|
||||
support non-core resources in the future. When it does, garbage collector will
|
||||
delete objects with ownerRefereneces referring to non-existent object of a
|
||||
valid non-core resource.
|
||||
* As of 1.7, garbage collection does not yet support
|
||||
[custom resources](/docs/concepts/api-extension/custom-resources/),
|
||||
such as those added through CustomResourceDefinition or aggregated API servers.
|
||||
|
||||
[Other known issues](https://github.com/kubernetes/kubernetes/issues/26120)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,9 +65,13 @@ Currently, there are several API groups in use:
|
|||
* The named groups are at REST path `/apis/$GROUP_NAME/$VERSION`, and use `apiVersion: $GROUP_NAME/$VERSION`
|
||||
(for example, `apiVersion: batch/v1`). Full list of supported API groups can be seen in [Kubernetes API reference](/docs/reference/).
|
||||
|
||||
There is a supported path to extending the API:
|
||||
* [Third Party Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/extending-api.md)
|
||||
are for users with very basic CRUD needs.
|
||||
There are two supported paths to extending the API with [custom resources](/docs/concepts/api-extension/custom-resources/):
|
||||
|
||||
1. [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
|
||||
is for users with very basic CRUD needs.
|
||||
1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver
|
||||
and use the [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/aggregated-api-servers.md)
|
||||
to make it seamless for clients.
|
||||
|
||||
|
||||
## Enabling API groups
|
||||
|
|
|
|||
|
|
@ -1,48 +1,36 @@
|
|||
---
|
||||
title: Extend the Kubernetes API with CustomResourceDefinitions
|
||||
assignees:
|
||||
- IanLewis
|
||||
title: Extending the Kubernetes API Using Custom Resource Definitions
|
||||
redirect_from:
|
||||
- "/docs/user-guide/customresourcedefinitions/"
|
||||
- "/docs/user-guide/customresourcedefinitions.html"
|
||||
- "/docs/concepts/ecosystem/customresourcedefinitions/"
|
||||
- "/docs/concepts/ecosystem/customresourcedefinitions.html"
|
||||
- deads2k
|
||||
- enisoc
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% capture overview %}
|
||||
This page shows how to install a [custom resource](/docs/concepts/api-extension/custom-resources/)
|
||||
into the Kubernetes API by creating a CustomResourceDefinition.
|
||||
{% endcapture %}
|
||||
|
||||
## What is a CustomResourceDefinition?
|
||||
{% capture prerequisites %}
|
||||
* Read about [custom resources](/docs/concepts/api-extension/custom-resources/).
|
||||
* Make sure your Kubernetes cluster has a master version of 1.7.0 or higher.
|
||||
{% endcapture %}
|
||||
|
||||
Kubernetes comes with many built-in API objects. However, there are often times
|
||||
when you might need to extend Kubernetes with your own API objects in order to do custom automation.
|
||||
{% capture steps %}
|
||||
## Create a CustomResourceDefinition
|
||||
|
||||
`CustomResourceDefinition` objects are a way to extend the Kubernetes API with
|
||||
a new API object type. The new API object type will be given an API endpoint
|
||||
URL and support CRUD operations, and watch API. You can then create custom
|
||||
objects using this API endpoint. You can think of `CustomResourceDefinitions`
|
||||
as being much like the schema for a database table. Once you have created the
|
||||
table, you can then start storing rows in the table. Once created,
|
||||
`CustomResourceDefinitions` can act as the data model behind custom controllers
|
||||
or automation programs.
|
||||
|
||||
A `CustomResourceDefinition` creates the REST API for a custom resource of your chosen name.
|
||||
|
||||
## Creating a CustomResourceDefinition
|
||||
|
||||
When you create a new `CustomResourceDefinition`, the Kubernetes API Server
|
||||
reacts by creating a new RESTful resource path (namespaced or cluster-scoped)
|
||||
depending on your request. As with existing built-in objects, deleting a
|
||||
When you create a new *CustomResourceDefinition* (CRD), the Kubernetes API Server
|
||||
reacts by creating a new RESTful resource path, either namespaced or cluster-scoped,
|
||||
as specified in the CRD's `scope` field. As with existing built-in objects, deleting a
|
||||
namespace deletes all custom objects in that namespace.
|
||||
`CustomResourceDefinitions` themselves are non-namespaced and are available to all namespaces.
|
||||
CustomResourceDefinitions themselves are non-namespaced and are available to all namespaces.
|
||||
|
||||
For example, if you save the following `CustomResourceDefinition` to `resourcedefinition.yaml`:
|
||||
For example, if you save the following CustomResourceDefinition to `resourcedefinition.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
# name must be in the form: plural.group
|
||||
# name must match the spec fields below, and be in the form: <plural>.<group>
|
||||
name: crontabs.stable.example.com
|
||||
spec:
|
||||
# group name to use for REST API: /apis/<group>/<version>
|
||||
|
|
@ -54,9 +42,9 @@ spec:
|
|||
names:
|
||||
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
|
||||
plural: crontabs
|
||||
# singular name to be used as alias on the CLI and for display
|
||||
# singular name to be used as an alias on the CLI and for display
|
||||
singular: crontab
|
||||
# kind is normally the CamelCased singular type. Your resource manifests use this
|
||||
# kind is normally the CamelCased singular type. Your resource manifests use this.
|
||||
kind: CronTab
|
||||
# shortNames allow shorter string to match your resource on the CLI
|
||||
shortNames:
|
||||
|
|
@ -66,27 +54,28 @@ spec:
|
|||
And create it:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f resourcedefinition.yaml
|
||||
customresourcedefinitions "crontabs.stable.example.com" created
|
||||
kubectl create -f resourcedefinition.yaml
|
||||
```
|
||||
|
||||
Then a new RESTful API endpoint is created at:
|
||||
Then a new namespaced RESTful API endpoint is created at:
|
||||
|
||||
`/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/...`
|
||||
```
|
||||
/apis/stable.example.com/v1/namespaces/*/crontabs/...
|
||||
```
|
||||
|
||||
This endpoint URL can then be used to create and manage custom objects.
|
||||
The `kind` of these objects will be `CronTab` from the spec of the
|
||||
`CustomResourceDefinition` object we created above.
|
||||
CustomResourceDefinition object you created above.
|
||||
|
||||
|
||||
## Creating Custom Objects
|
||||
## Create custom objects
|
||||
|
||||
After the `CustomResourceDefinition` object has been created you can create
|
||||
After the CustomResourceDefinition 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, a `cronSpec` and `image` custom fields are set to the
|
||||
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 of the
|
||||
`CustomResourceDefinition` object we created above.
|
||||
CustomResourceDefinition object you created above.
|
||||
|
||||
If you save the following YAML to `my-crontab.yaml`:
|
||||
|
||||
|
|
@ -103,23 +92,36 @@ spec:
|
|||
and create it:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f my-crontab.yaml
|
||||
crontab "my-new-cron-object" created
|
||||
kubectl create -f my-crontab.yaml
|
||||
```
|
||||
|
||||
You can then manage our `CronTab` objects using kubectl. Note that resource
|
||||
names are not case-sensitive when using kubectl:
|
||||
You can then manage your CronTab objects using kubectl. For example:
|
||||
|
||||
```shell
|
||||
$ kubectl get crontab
|
||||
kubectl get crontab
|
||||
```
|
||||
|
||||
Should print a list like this:
|
||||
|
||||
```console
|
||||
NAME KIND
|
||||
my-new-cron-object CronTab.v1.stable.example.com
|
||||
```
|
||||
|
||||
You can also view the raw JSON data. Here you can see that it contains the custom `cronSpec` and `image` fields from the yaml you used to create it:
|
||||
Note that resource names are not case-sensitive when using kubectl,
|
||||
and you can use either the singular or plural forms defined in the CRD,
|
||||
as well as any short names.
|
||||
|
||||
```yaml
|
||||
$ kubectl get ct -o yaml
|
||||
You can also view the raw JSON data:
|
||||
|
||||
```shell
|
||||
kubectl get ct -o yaml
|
||||
```
|
||||
|
||||
You should see that it contains the custom `cronSpec` and `image` fields
|
||||
from the yaml you used to create it:
|
||||
|
||||
```console
|
||||
apiVersion: v1
|
||||
items:
|
||||
- apiVersion: stable.example.com/v1
|
||||
|
|
@ -142,11 +144,17 @@ metadata:
|
|||
resourceVersion: ""
|
||||
selfLink: ""
|
||||
```
|
||||
{% endcapture %}
|
||||
|
||||
{% capture discussion %}
|
||||
## Advanced topics
|
||||
|
||||
## Advanced Topics
|
||||
### Finalizers
|
||||
CustomResources (objects created in the schema defined by CustomResourceDefintions)
|
||||
support finalizers. If you add a `metadata.finalizers` stanza like
|
||||
|
||||
*Finalizers* allow controllers to implement asynchronous pre-delete hooks.
|
||||
Custom objects support finalizers just like built-in objects.
|
||||
|
||||
You can add a finalizer to a custom object like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: "stable.example.com/v1"
|
||||
|
|
@ -156,7 +164,21 @@ metadata:
|
|||
- finalizer.stable.example.com
|
||||
```
|
||||
|
||||
Then when the CustomResource is deleted, the `metadata.deletionTimestamp` will
|
||||
be set and update watch events will be sent to a controller which can perform
|
||||
finalization steps before removing the finalizer and deleting the object again.
|
||||
This allows cleanup for CustomResources like "normal" Kubernetes APIs.
|
||||
The first delete request on an object with finalizers merely sets a value for the
|
||||
`metadata.deletionTimestamp` field instead of deleting it.
|
||||
This triggers controllers watching the object to execute any finalizers they handle.
|
||||
|
||||
Each controller then removes its finalizer from the list and issues the delete request again.
|
||||
This request only deletes the object if the list of finalizers is now empty,
|
||||
meaning all finalizers are done.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture whatsnext %}
|
||||
* Learn how to [Migrate a ThirdPartyResource to CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/).
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/task.md %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
---
|
||||
assignees:
|
||||
- enisoc
|
||||
- IanLewis
|
||||
title: Extend the Kubernetes API Using Third Party Resources
|
||||
title: Extend the Kubernetes API with ThirdPartyResources
|
||||
redirect_from:
|
||||
- "/docs/user-guide/thirdpartyresources/"
|
||||
- "/docs/user-guide/thirdpartyresources.html"
|
||||
|
|
@ -9,29 +10,24 @@ redirect_from:
|
|||
- "/docs/concepts/ecosystem/thirdpartyresource.html"
|
||||
---
|
||||
|
||||
{% assign for_k8s_version="1.7" %}{% include feature-state-deprecated.md %}
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## What is ThirdPartyResource?
|
||||
|
||||
**WARNING: ThirdPartyResources are deprecated as of 1.7 and will be removed as soon as possible without access to existing data! See https://kubernetes.io/docs/reference/deprecation-policy/ for deprecation rules. Please [migrate to CustomResourceDefinition](#Migration-to-CustomResourceDefinitions).**
|
||||
**ThirdPartyResource is deprecated as of Kubernetes 1.7 and may be removed in version 1.8 in
|
||||
accordance with the [deprecation policy](/docs/reference/deprecation-policy) for beta features.**
|
||||
|
||||
**To avoid losing data stored in ThirdPartyResources, you must
|
||||
[migrate to CustomResourceDefinition](/docs/tasks/access-kubernetes-api/migrate-third-party-resource/)
|
||||
before upgrading to Kubernetes 1.8 or higher.**
|
||||
|
||||
Kubernetes comes with many built-in API objects. However, there are often times when you might need to extend Kubernetes with your own API objects in order to do custom automation.
|
||||
|
||||
`ThirdPartyResource` objects are a way to extend the Kubernetes API with a new API object type. The new API object type will be given an API endpoint URL and support CRUD operations, and watch API. You can then create custom objects using this API endpoint. You can think of `ThirdPartyResources` as being much like the schema for a database table. Once you have created the table, you can then start storing rows in the table. Once created, `ThirdPartyResources` can act as the data model behind custom controllers or automation programs.
|
||||
|
||||
## Migration to CustomResourceDefinitions
|
||||
`ThirdPartyResources` are being replaced by `CustomResourceDefinitions` as of 1.7, so you must migrate your data from one to the other.
|
||||
The types are not directly compatible so you'll need to perform some manual steps.
|
||||
You should do a dry-run of these steps in a non-production cluster to make sure things work as expected.
|
||||
1. Create a `CustomResourceDefinition` that has a spec matching your current `ThirdPartyResource`.
|
||||
2. Stop your ThirdPartyResource controllers.
|
||||
3. Backup your ThirdPartyResource *Data* (the custom objects you've created).
|
||||
4. Delete the `ThirdPartyResource`. This will trigger migration to the `CustomResourceDefinition`
|
||||
5. Wait for the `ThirdPartyResource` to be removed.
|
||||
6. Confirm that your custom objects are still present. If this doesn't work, simply recreate your `ThirdPartyResource` to get your data back.
|
||||
7. Restart your ThirdPartyResource controllers.
|
||||
|
||||
## Structure of a ThirdPartyResource
|
||||
|
||||
Each `ThirdPartyResource` has the following:
|
||||
|
|
@ -80,12 +76,12 @@ Then a new RESTful API endpoint is created at:
|
|||
|
||||
This endpoint URL can then be used to create and manage custom objects.
|
||||
The `kind` of these objects will be `CronTab` following the camel case
|
||||
rules applied to the `metadata.name` of this `ThirdPartyResource`
|
||||
rules applied to the `metadata.name` of this `ThirdPartyResource`
|
||||
(`cron-tab.stable.example.com`)
|
||||
|
||||
## Creating Custom Objects
|
||||
|
||||
After the `ThirdPartyResource` object has been created you can create custom objects. Custom objects can contain custom fields. These fields can contain arbitrary JSON.
|
||||
After the `ThirdPartyResource` 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, a `cronSpec` and `image` custom fields are set to the custom object of kind `CronTab`. The kind `CronTab` is derived from the
|
||||
`metadata.name` of the `ThirdPartyResource` object we created above.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,165 @@
|
|||
---
|
||||
title: Migrate a ThirdPartyResource to CustomResourceDefinition
|
||||
assignees:
|
||||
- enisoc
|
||||
- deads2k
|
||||
---
|
||||
|
||||
{% capture overview %}
|
||||
This page shows how to migrate data stored in a ThirdPartyResource (TPR) to a CustomResourceDefinition (CRD).
|
||||
|
||||
Kubernetes does not automatically migrate existing TPRs.
|
||||
This is due to API changes introduced as part of
|
||||
[graduating to beta](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/thirdpartyresources.md)
|
||||
under a new name and API group.
|
||||
Instead, both TPR and CRD are available and operate independently in Kubernetes 1.7.
|
||||
Users must migrate each TPR one by one to preserve their data before upgrading to Kubernetes 1.8.
|
||||
|
||||
The simplest way to migrate is to stop all clients that use a given TPR, then delete the TPR and
|
||||
start from scratch with a CRD.
|
||||
This page describes an optional process that eases the transition by migrating existing TPR data for
|
||||
you **on a best-effort basis**.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture prerequisites %}
|
||||
* Make sure your Kubernetes cluster has a **master version of exactly 1.7.x** (any patch release),
|
||||
as this is the only version that supports both TPR and CRD.
|
||||
* If you use a TPR-based custom controller, check with the author of the controller first.
|
||||
Some or all of these steps may be unnecessary if the custom controller handles the migration for
|
||||
you.
|
||||
* Be familiar with the concept of [custom resources](/docs/concepts/api-extension/custom-resources/),
|
||||
which were known as *third-party resources* until Kubernetes 1.7.
|
||||
* Be familiar with [CustomResourceDefinitions](/docs/concepts/api-extension/custom-resources/#customresourcedefinitions),
|
||||
which are a simple way to implement custom resources.
|
||||
* **Before performing a migration on real data, conduct a dry run by going through these steps in a test cluster.**
|
||||
{% endcapture %}
|
||||
|
||||
{% capture steps %}
|
||||
## Migrate TPR data
|
||||
|
||||
1. **Rewrite the TPR definition**
|
||||
|
||||
Clients that access the REST API for your custom resource should not need any changes.
|
||||
However, you will need to rewrite your TPR definition as a CRD.
|
||||
|
||||
Make sure you specify values for the CRD fields that match what the server used to fill in for
|
||||
you with TPR.
|
||||
|
||||
For example, if your ThirdPartyResource looks like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: ThirdPartyResource
|
||||
metadata:
|
||||
name: cron-tab.stable.example.com
|
||||
description: "A specification of a Pod to run on a cron style schedule"
|
||||
versions:
|
||||
- name: v1
|
||||
```
|
||||
|
||||
A matching CustomResourceDefinition could look like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: crontabs.stable.example.com
|
||||
spec:
|
||||
scope: Namespaced
|
||||
group: stable.example.com
|
||||
version: v1
|
||||
names:
|
||||
kind: CronTab
|
||||
plural: crontabs
|
||||
singular: crontab
|
||||
```
|
||||
|
||||
1. **Install the CustomResourceDefinition**
|
||||
|
||||
While the source TPR is still active, install the matching CRD with `kubectl create`.
|
||||
Existing TPR data remains accessible because TPRs take precedence over CRDs when both try
|
||||
to serve the same resource.
|
||||
|
||||
After you create the CRD, make sure the *Established* condition goes to True.
|
||||
You can check it with a command like this:
|
||||
|
||||
```shell
|
||||
kubectl get crd -o 'custom-columns=NAME:{.metadata.name},ESTABLISHED:{.status.conditions[?(@.type=="Established")].status}'
|
||||
```
|
||||
|
||||
The output should look like this:
|
||||
|
||||
```console
|
||||
NAME ESTABLISHED
|
||||
crontabs.stable.example.com True
|
||||
```
|
||||
|
||||
1. **Stop all clients that use the TPR**
|
||||
|
||||
The API server attempts to prevent TPR data for the resource from changing while it
|
||||
copies objects to the CRD, but it can't guarantee consistency in all cases, such as with
|
||||
[multiple masters](/docs/admin/high-availability/).
|
||||
Stopping clients, such as TPR-based custom controllers, helps to avoid inconsistencies in
|
||||
the copied data.
|
||||
|
||||
In addition, clients that watch TPR data do not receive any more events once the migration
|
||||
begins.
|
||||
You must restart them after the migration completes so they start watching CRD data instead.
|
||||
|
||||
1. **Back up TPR data**
|
||||
|
||||
In case the data migration fails, save a copy of existing data for the resource:
|
||||
|
||||
```shell
|
||||
kubectl get crontabs --all-namespaces -o yaml > crontabs.yaml
|
||||
```
|
||||
|
||||
You should also save a copy of the TPR definition if you don't have one already:
|
||||
|
||||
```shell
|
||||
kubectl get thirdpartyresource cron-tab.stable.example.com -o yaml --export > tpr.yaml
|
||||
```
|
||||
|
||||
1. **Delete the TPR definition**
|
||||
|
||||
Normally, when you delete a TPR definition, the API server tries to clean up any objects stored
|
||||
in that resource.
|
||||
Because a matching CRD exists, the server copies objects to the CRD instead of deleting them.
|
||||
|
||||
```shell
|
||||
kubectl delete thirdpartyresource cron-tab.stable.example.com
|
||||
```
|
||||
|
||||
1. **Verify the new CRD data**
|
||||
|
||||
It can take up to 10 seconds for the TPR controller to notice when you delete the TPR definition
|
||||
and to initiate the migration. The TPR data remains accessible during this time.
|
||||
|
||||
Once the migration completes, the resource begins serving through the CRD.
|
||||
Check that all your objects were correctly copied:
|
||||
|
||||
```shell
|
||||
kubectl get crontabs --all-namespaces -o yaml
|
||||
```
|
||||
|
||||
If the copy failed, you can quickly revert to the set of objects that existed just before the
|
||||
migration by recreating the TPR definition:
|
||||
|
||||
```shell
|
||||
kubectl create -f tpr.yaml
|
||||
```
|
||||
|
||||
1. **Restart clients**
|
||||
|
||||
After verifying the CRD data, restart any clients you stopped before the migration, such as
|
||||
custom controllers and other watchers.
|
||||
These clients now access CRD data when they make requests on the same API endpoints
|
||||
that the TPR previously served.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture whatsnext %}
|
||||
* Learn more about [custom resources](/docs/concepts/api-extension/custom-resources/).
|
||||
* Learn more about [using CustomResourceDefinitions](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/).
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/task.md %}
|
||||
|
|
@ -941,10 +941,11 @@ template:
|
|||
controller-selector: "extensions/v1beta1/deployment/nginx"
|
||||
```
|
||||
|
||||
## Support for ThirdPartyResources
|
||||
## Known Issues
|
||||
|
||||
As of Kubernetes 1.5, ThirdPartyResources are not supported by `kubectl apply`.
|
||||
The recommended approach for ThirdPartyResources is to use [imperative object configuration](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/).
|
||||
* Prior to Kubernetes 1.6, `kubectl apply` did not support operating on objects stored in a
|
||||
[custom resource](/docs/concepts/api-extension/custom-resources/).
|
||||
For these cluster versions, you should instead use [imperative object configuration](/docs/tutorials/object-management-kubectl/imperative-object-management-configuration/).
|
||||
{% endcapture %}
|
||||
|
||||
{% capture whatsnext %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue