diff --git a/docs/concepts/api-extension/custom-resources.md b/docs/concepts/api-extension/custom-resources.md
index a7a0ccbbef96d..8c0e50be2278a 100644
--- a/docs/concepts/api-extension/custom-resources.md
+++ b/docs/concepts/api-extension/custom-resources.md
@@ -154,12 +154,12 @@ Aggregated APIs offer more advanced API features and customization of other feat
| Feature | Description | CRDs | Aggregated API |
|-|-|-|-|
-| Validation | Help users prevent errors and allow you to evolve your API independently of your clients. These features are most useful when there are many clients who can't all update at the same time. | Alpha feature of CRDs in v1.8. Checks limited to what is supported by OpenAPI v3.0. | Yes, arbitrary validation checks |
+| Validation | Help users prevent errors and allow you to evolve your API independently of your clients. These features are most useful when there are many clients who can't all update at the same time. | Beta feature of CRDs in v1.9. Checks limited to what is supported by OpenAPI v3.0. | Yes, arbitrary validation checks |
| Defaulting | See above | No, but can achieve the same effect with an Initializer (requires programming) | Yes |
| Multi-versioning | Allows serving the same object through two API versions. Can help ease API changes like renaming fields. Less important if you control your client versions. | No | Yes |
| Custom Storage | If you need storage with a different performance mode (for example, time-series database instead of key-value store) or isolation for security (for example, encryption secrets or different | No | Yes |
| Custom Business Logic | Perform arbitrary checks or actions when creating, reading, updating or deleting an object | No, but can get some of the same effects with Initializers or Finalizers (requires programming) | Yes |
-| Subresources | {::nomarkdown}
- Add extra operations other than CRUD, such as "scale" or "exec"
- Allows systems like like HorizontalPodAutoscaler and PodDisruptionBudget interact with your new resource
- Finer-grained access control: user writes spec section, controller writes status section.
- Allows incrementing object Generation on custom resource data mutation (requires separate spec and status sections in the resource)
{:/} | No but planned | Yes, any Subresource |
+| Subresources | {::nomarkdown}- Add extra operations other than CRUD, such as "scale" or "exec"
- Allows systems like like HorizontalPodAutoscaler and PodDisruptionBudget interact with your new resource
- Finer-grained access control: user writes spec section, controller writes status section.
- Allows incrementing object Generation on custom resource data mutation (requires separate spec and status sections in the resource)
{:/} | `status` and `scale` subresources are supported | Yes, any Subresource |
| strategic-merge-patch | The new endpoints support PATCH with `Content-Type: application/strategic-merge-patch+json`. Useful for updating objects that may be modified both locally, and by the server. For more information, see ["Update API Objects in Place Using kubectl patch"](/docs/tasks/run-application/update-api-object-kubectl-patch/) | No | Yes |
| Protocol Buffers | The new resource supports clients that want to use Protocol Buffers | No | Yes |
| OpenAPI Schema | Is there an OpenAPI (swagger) schema for the types that can be dynamically fetched from the server? Is the user protected from misspelling field names by ensuring only allowed fields are set? Are types enforced (in other words, don't put an `int` in a `string` field?) | No but planned | Yes |
@@ -217,7 +217,7 @@ When you add a custom resource, you can access it using:
- kubectl
- The kubernetes dynamic client.
- A REST client that you write.
- - A client generated using Kubernetes client generation tools (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA).
+ - A client generated using [Kubernetes client generation tools](https://github.com/kubernetes/code-generator) (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA).
{% endcapture %}
diff --git a/docs/reference/feature-gates.md b/docs/reference/feature-gates.md
index 4c0391ef95c47..2be2692961c3f 100644
--- a/docs/reference/feature-gates.md
+++ b/docs/reference/feature-gates.md
@@ -42,6 +42,7 @@ different Kubernetes components.
| `CustomPodDNS` | `false` | Alpha | 1.9 | |
| `CustomResourceValidation` | `false` | Alpha | 1.8 | 1.8 |
| `CustomResourceValidation` | `true` | Beta | 1.9 | |
+| `CustomResourceSubresources` | `false` | Alpha | 1.10 | |
| `DevicePlugins` | `false` | Alpha | 1.8 | 1.9 |
| `DevicePlugins` | `true` | Beta | 1.10 | |
| `DynamicKubeletConfig` | `false` | Alpha | 1.4 | |
@@ -133,6 +134,8 @@ Each feature gate is designed for enabling/disabling a specific feature:
Check [Pod's DNS Config](/docs/concepts/services-networking/dns-pod-service/#pods-dns-config)
for more details.
- `CustomeResourceValidation`: Enable schema based validation on resources created from [CustomResourceDefinition](/docs/concepts/api-extension/custom-resources/).
+- `CustomResourceSubresources`: Enable `/status` and `/scale` subresources
+on resources created from [CustomResourceDefinition](/docs/concepts/api-extension/custom-resources/).
- `DevicePlugins`: Enable the [device-plugins](/docs/concepts/cluster-administration/device-plugins/)
based resource provisioning on nodes.
- `DynamicKubeletConfig`: Enable the dynamic configuration of kubelet. See [Reconfigure kubelet](/docs/tasks/administer-cluster/reconfigure-kubelet/).
diff --git a/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md b/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
index fa4cb453fe79b..041e04fc09a6c 100644
--- a/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
+++ b/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions.md
@@ -216,8 +216,8 @@ Validation of custom objects is possible via
[OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject).
Additionally, the following restrictions are applied to the schema:
-- The fields `default`, `nullable`, `discriminator`, `readOnly`, `writeOnly`, `xml` and
-`deprecated` cannot be set.
+- The fields `default`, `nullable`, `discriminator`, `readOnly`, `writeOnly`, `xml`,
+`deprecated` and `$ref` cannot be set.
- The field `uniqueItems` cannot be set to true.
- The field `additionalProperties` cannot be set to false.
@@ -328,6 +328,218 @@ And create it:
kubectl create -f my-crontab.yaml
crontab "my-new-cron-object" created
```
+
+### Subresources
+
+Custom resources support `/status` and `/scale` subresources.
+This feature is __alpha__ in v1.10 and may change in backward incompatible ways.
+
+Enable this feature using the `CustomResourceSubresources` feature gate on
+the [kube-apiserver](/docs/admin/kube-apiserver):
+
+```
+--feature-gates=CustomResourceSubresources=true
+```
+
+When the `CustomResourceSubresources` feature gate is enabled, only the `properties` construct
+is allowed in the root schema for custom resource validation.
+
+The status and scale subresources can be optionally enabled by
+defining them in the CustomResourceDefinition.
+
+#### Status subresource
+
+When the status subresource is enabled, the `/status` subresource for the custom resource is exposed.
+
+- The status and the spec stanzas are represented by the `.status` and `.spec` JSONPaths respectively inside of a custom resource.
+- `PUT` requests to the `/status` subresource take a custom resource object and ignore changes to anything except the status stanza.
+- `PUT` requests to the `/status` subresource only validate the status stanza of the custom resource.
+- `PUT`/`POST`/`PATCH` requests to the custom resource ignore changes to the status stanza.
+- Any changes to the spec stanza increments the value at `.metadata.generation`.
+
+#### Scale subresource
+
+When the scale subresource is enabled, the `/scale` subresource for the custom resource is exposed.
+The `autoscaling/v1.Scale` object is sent as the payload for `/scale`.
+
+To enable the scale subresource, the following values are defined in the CustomResourceDefinition.
+
+- `SpecReplicasPath` defines the JSONPath inside of a custom resource that corresponds to `Scale.Spec.Replicas`.
+
+ - It is a required value.
+ - Only JSONPaths under `.spec` and with the dot notation are allowed.
+ - If there is no value under the `SpecReplicasPath` in the custom resource,
+the `/scale` subresource will return an error on GET.
+
+- `StatusReplicasPath` defines the JSONPath inside of a custom resource that corresponds to `Scale.Status.Replicas`.
+
+ - It is a required value.
+ - Only JSONPaths under `.status` and with the dotation are allowed.
+ - If there is no value under the `StatusReplicasPath` in the custom resource,
+the status replica value in the `/scale` subresource will default to 0.
+
+- `LabelSelectorPath` defines the JSONPath inside of a custom resource that corresponds to `Scale.Status.Selector`.
+
+ - It is an optional value.
+ - It must be set to work with HPA.
+ - Only JSONPaths under `.status` and with the dotation are allowed.
+ - If there is no value under the `LabelSelectorPath` in the custom resource,
+the status selector value in the `/scale` subresource will default to the empty string.
+
+In the following example, both status and scale subresources are enabled.
+
+Save the CustomResourceDefinition to `resourcedefinition.yaml`:
+
+```yaml
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: crontabs.stable.example.com
+spec:
+ group: stable.example.com
+ version: v1
+ scope: Namespaced
+ names:
+ plural: crontabs
+ singular: crontab
+ kind: CronTab
+ shortNames:
+ - ct
+ # subresources describes the subresources for custom resources.
+ subresources:
+ # status enables the status subresource.
+ status: {}
+ # scale enables the scale subresource.
+ scale:
+ # specReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Spec.Replicas.
+ specReplicasPath: .spec.replicas
+ # statusReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Replicas.
+ statusReplicasPath: .status.replicas
+ # labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector.
+ labelSelectorPath: .status.labelSelector
+```
+
+And create it:
+
+```shell
+kubectl create -f resourcedefinition.yaml
+```
+
+After the CustomResourceDefinition object has been created, you can create custom objects.
+
+If you save the following YAML to `my-crontab.yaml`:
+
+```yaml
+apiVersion: "stable.example.com/v1"
+kind: CronTab
+metadata:
+ name: my-new-cron-object
+spec:
+ cronSpec: "* * * * */5"
+ image: my-awesome-cron-image
+ replicas: 3
+```
+
+and create it:
+
+```shell
+kubectl create -f my-crontab.yaml
+```
+
+Then new namespaced RESTful API endpoints are created at:
+
+```
+/apis/stable.example.com/v1/namespaces/*/crontabs/status
+```
+
+and
+
+```
+/apis/stable.example.com/v1/namespaces/*/crontabs/scale
+```
+
+A custom resource can be scaled using the `kubectl scale` command.
+For example, the following command sets `.spec.replicas` of the
+custom resource created above to 5:
+
+```shell
+kubectl scale --replicas=5 crontabs/my-new-cron-object
+crontabs "my-new-cron-object" scaled
+
+kubectl get crontabs my-new-cron-object -o jsonpath='{.spec.replicas}'
+5
+```
+
+### Categories
+
+Categories is a list of grouped resources the custom resource belongs to (eg. `all`).
+You can use `kubectl get ` to list the resources belonging to the category.
+This feature is __beta__ and available for custom resources from v1.10.
+
+The following example adds `all` in the list of categories in the CustomResourceDefinition
+and illustrates how to output the custom resource using `kubectl get all`.
+
+Save the following CustomResourceDefinition to `resourcedefinition.yaml`:
+
+```yaml
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: crontabs.stable.example.com
+spec:
+ group: stable.example.com
+ version: v1
+ scope: Namespaced
+ names:
+ plural: crontabs
+ singular: crontab
+ kind: CronTab
+ shortNames:
+ - ct
+ # categories is a list of grouped resources the custom resource belongs to.
+ categories:
+ - all
+```
+
+And create it:
+
+```shell
+kubectl create -f resourcedefinition.yaml
+```
+
+After the CustomResourceDefinition object has been created, you can create custom objects.
+
+Save the following YAML to `my-crontab.yaml`:
+
+```yaml
+apiVersion: "stable.example.com/v1"
+kind: CronTab
+metadata:
+ name: my-new-cron-object
+spec:
+ cronSpec: "* * * * */5"
+ image: my-awesome-cron-image
+```
+
+and create it:
+
+```shell
+kubectl create -f my-crontab.yaml
+```
+
+You can specify the category using `kubectl get`:
+
+```
+kubectl get all
+```
+
+and it will include the custom resources of kind `CronTab`:
+
+```console
+NAME AGE
+crontabs/my-new-cron-object 3s
+```
+
{% endcapture %}
{% capture whatsnext %}