Skip to content

Commit

Permalink
Merge pull request #40027 from Jefftree/openapiv3-ga-doc
Browse files Browse the repository at this point in the history
Doc update for KEP-2896 OpenAPIV3
  • Loading branch information
k8s-ci-robot committed Apr 1, 2023
2 parents 9d05239 + 0c9ba63 commit 0faa93c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
14 changes: 6 additions & 8 deletions content/en/docs/concepts/overview/kubernetes-api.md
Expand Up @@ -82,17 +82,13 @@ packages that define the API objects.

### OpenAPI V3

{{< feature-state state="beta" for_k8s_version="v1.24" >}}
{{< feature-state state="stable" for_k8s_version="v1.27" >}}

Kubernetes {{< param "version" >}} offers beta support for publishing its APIs as OpenAPI v3; this is a
beta feature that is enabled by default.
You can disable the beta feature by turning off the
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) named `OpenAPIV3`
for the kube-apiserver component.
Kubernetes supports publishing a description of its APIs as OpenAPI v3.

A discovery endpoint `/openapi/v3` is provided to see a list of all
group/versions available. This endpoint only returns JSON. These group/versions
are provided in the following format:
group/versions available. This endpoint only returns JSON. These
group/versions are provided in the following format:

```yaml
{
Expand Down Expand Up @@ -153,6 +149,8 @@ Refer to the table below for accepted request headers.
</tbody>
</table>

A Golang implementation to fetch the OpenAPI V3 is provided in the package `k8s.io/client-go/openapi3`.

## Persistence

Kubernetes stores the serialized state of objects by writing them into
Expand Down
Expand Up @@ -157,8 +157,6 @@ For a reference to old feature gates that are removed, please refer to
| `NodeSwap` | `false` | Alpha | 1.22 | |
| `OpenAPIEnums` | `false` | Alpha | 1.23 | 1.23 |
| `OpenAPIEnums` | `true` | Beta | 1.24 | |
| `OpenAPIV3` | `false` | Alpha | 1.23 | 1.23 |
| `OpenAPIV3` | `true` | Beta | 1.24 | |
| `PDBUnhealthyPodEvictionPolicy` | `false` | Alpha | 1.26 | |
| `PodAndContainerStatsFromCRI` | `false` | Alpha | 1.23 | |
| `PodDeletionCost` | `false` | Alpha | 1.21 | 1.21 |
Expand Down Expand Up @@ -321,6 +319,9 @@ For a reference to old feature gates that are removed, please refer to
| `ServerSideFieldValidation` | `false` | Alpha | 1.23 | 1.24 |
| `ServerSideFieldValidation` | `true` | Beta | 1.25 | 1.26 |
| `ServerSideFieldValidation` | `true` | GA | 1.27 | - |
| `OpenAPIV3` | `false` | Alpha | 1.23 | 1.23 |
| `OpenAPIV3` | `true` | Beta | 1.24 | 1.26 |
| `OpenAPIV3` | `true` | GA | 1.27 | - |
| `ServiceIPStaticSubrange` | `false` | Alpha | 1.24 | 1.24 |
| `ServiceIPStaticSubrange` | `true` | Beta | 1.25 | 1.25 |
| `ServiceIPStaticSubrange` | `true` | GA | 1.26 | - |
Expand Down
Expand Up @@ -765,7 +765,7 @@ For example:
required:
- minReplicas
- replicas
- maxReplicas
- maxReplicas
```

will reject a request to create this custom resource:
Expand All @@ -788,7 +788,7 @@ The CronTab "my-new-cron-object" is invalid:
* spec: Invalid value: map[string]interface {}{"maxReplicas":10, "minReplicas":0, "replicas":20}: replicas should be smaller than or equal to maxReplicas.
```

`x-kubernetes-validations` could have multiple rules.
`x-kubernetes-validations` could have multiple rules.
The `rule` under `x-kubernetes-validations` represents the expression which will be evaluated by CEL.
The `message` represents the message displayed when validation fails. If message is unset, the
above response would be:
Expand All @@ -798,22 +798,22 @@ The CronTab "my-new-cron-object" is invalid:
* spec: Invalid value: map[string]interface {}{"maxReplicas":10, "minReplicas":0, "replicas":20}: failed rule: self.replicas <= self.maxReplicas
```

Validation rules are compiled when CRDs are created/updated.
The request of CRDs create/update will fail if compilation of validation rules fail.
Validation rules are compiled when CRDs are created/updated.
The request of CRDs create/update will fail if compilation of validation rules fail.
Compilation process includes type checking as well.

The compilation failure:

- `no_matching_overload`: this function has no overload for the types of the arguments.

For example, a rule like `self == true` against a field of integer type will get error:

```none
Invalid value: apiextensions.ValidationRule{Rule:"self == true", Message:""}: compilation failed: ERROR: \<input>:1:6: found no matching overload for '_==_' applied to '(int, bool)'
```

- `no_such_field`: does not contain the desired field.

For example, a rule like `self.nonExistingField > 0` against a non-existing field will return
the following error:

Expand All @@ -822,7 +822,7 @@ The compilation failure:
```

- `invalid argument`: invalid argument to macros.

For example, a rule like `has(self)` will return error:

```none
Expand Down Expand Up @@ -961,7 +961,7 @@ Examples:
The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from
the root of the object and from any `x-kubernetes-embedded-resource` annotated objects. No other
metadata properties are accessible.

Unknown data preserved in custom resources via `x-kubernetes-preserve-unknown-fields` is not
accessible in CEL expressions. This includes:

Expand Down Expand Up @@ -1007,7 +1007,7 @@ the list type:
- `map`: `X + Y` performs a merge where the array positions of all keys in `X` are preserved but
the values are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements
in `Y` with non-intersecting keys are appended, retaining their partial order.


Here is the declarations type mapping between OpenAPIv3 and CEL type:

Expand Down Expand Up @@ -1131,8 +1131,8 @@ estimated to be prohibitively expensive to execute, the API server rejects the c
or update operation, and returns an error message.
A similar system is used at runtime that observes the actions the interpreter takes. If the interpreter executes
too many instructions, execution of the rule will be halted, and an error will result.
Each CustomResourceDefinition is also allowed a certain amount of resources to finish executing all of
its validation rules. If the sum total of its rules are estimated at creation time to go over that limit,
Each CustomResourceDefinition is also allowed a certain amount of resources to finish executing all of
its validation rules. If the sum total of its rules are estimated at creation time to go over that limit,
then a validation error will also occur.

You are unlikely to encounter issues with the resource budget for validation if you only
Expand All @@ -1145,7 +1145,7 @@ Another example would be if `foo` were an array, and you specified a validation
The cost system always assumes the worst-case scenario if a limit on the length of `foo` is not
given, and this will happen for anything that can be iterated over (lists, maps, etc.).

Because of this, it is considered best practice to put a limit via `maxItems`, `maxProperties`, and
Because of this, it is considered best practice to put a limit via `maxItems`, `maxProperties`, and
`maxLength` for anything that will be processed in a validation rule in order to prevent validation
errors during cost estimation. For example, given this schema with one rule:

Expand All @@ -1164,8 +1164,8 @@ openAPIV3Schema:
then the API server rejects this rule on validation budget grounds with error:

```
spec.validation.openAPIV3Schema.properties[spec].properties[foo].x-kubernetes-validations[0].rule: Forbidden:
CEL rule exceeded budget by more than 100x (try simplifying the rule, or adding maxItems, maxProperties, and
spec.validation.openAPIV3Schema.properties[spec].properties[foo].x-kubernetes-validations[0].rule: Forbidden:
CEL rule exceeded budget by more than 100x (try simplifying the rule, or adding maxItems, maxProperties, and
maxLength where arrays, maps, and strings are used)
```

Expand Down Expand Up @@ -1208,7 +1208,7 @@ openAPIV3Schema:
maxLength: 10
```

If a list inside of a list has a validation rule that uses `self.all`, that is significantly more expensive
If a list inside of a list has a validation rule that uses `self.all`, that is significantly more expensive
than a non-nested list with the same rule. A rule that would have been allowed on a non-nested list might need
lower limits set on both nested lists in order to be allowed. For example, even without having limits set,
the following rule is allowed:
Expand Down Expand Up @@ -1377,28 +1377,31 @@ with `foo` pruned and defaulted because the field is non-nullable, `bar` maintai
value due to `nullable: true`, and `baz` pruned because the field is non-nullable and has no
default.

### Publish Validation Schema in OpenAPI v2
### Publish Validation Schema in OpenAPI

CustomResourceDefinition [OpenAPI v3 validation schemas](#validation) which are
[structural](#specifying-a-structural-schema) and [enable pruning](#field-pruning) are published
as part of the [OpenAPI v2 spec](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions)
from Kubernetes API server.
as [OpenAPI v3](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions) and
OpenAPI v2 from Kubernetes API server. It is recommended to use the OpenAPI v3 document
as it is a lossless representation of the CustomResourceDefinition OpenAPI v3 validation schema
while OpenAPI v2 represents a lossy conversion.

The [kubectl](/docs/reference/kubectl/) command-line tool consumes the published schema to perform
client-side validation (`kubectl create` and `kubectl apply`), schema explanation (`kubectl explain`)
on custom resources. The published schema can be consumed for other purposes as well, like client generation or documentation.

The OpenAPI v3 validation schema is converted to OpenAPI v2 schema, and
show up in `definitions` and `paths` fields in the
#### Compatibility with OpenAPI V2

For compatibility with OpenAPI V2, the OpenAPI v3 validation schema performs a lossy conversion
to the OpenAPI v2 schema. The schema show up in `definitions` and `paths` fields in the
[OpenAPI v2 spec](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions).

The following modifications are applied during the conversion to keep backwards compatibility with
kubectl in previous 1.13 version. These modifications prevent kubectl from being over-strict and rejecting
valid OpenAPI schemas that it doesn't understand. The conversion won't modify the validation schema defined in CRD,
and therefore won't affect [validation](#validation) in the API server.

1. The following fields are removed as they aren't supported by OpenAPI v2
(in future versions OpenAPI v3 will be used without these restrictions)
1. The following fields are removed as they aren't supported by OpenAPI v2.

- The fields `allOf`, `anyOf`, `oneOf` and `not` are removed

Expand Down Expand Up @@ -1800,4 +1803,3 @@ crontabs/my-new-cron-object 3s

* Serve [multiple versions](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/) of a
CustomResourceDefinition.

0 comments on commit 0faa93c

Please sign in to comment.