website/docs/tasks/access-kubernetes-api/migrate-third-party-resourc...

166 lines
6.0 KiB
Markdown

---
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 %}