Skip to content

Commit e44ac80

Browse files
author
Tim Bannister
committed
Add more detail about media types
- Add section about JSON encoding for API - Mention that the HTTP API doesn't use YAML
1 parent 61cd60c commit e44ac80

File tree

2 files changed

+169
-112
lines changed

2 files changed

+169
-112
lines changed

content/en/docs/reference/glossary/manifest.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ aka:
99
tags:
1010
- fundamental
1111
---
12-
Specification of a Kubernetes API object in JSON or YAML format.
12+
Specification of a Kubernetes API object in [JSON](https://www.json.org/json-en.html)
13+
or [YAML](https://yaml.org/) format.
1314

1415
<!--more-->
15-
A manifest specifies the desired state of an object that Kubernetes will maintain when you apply the manifest. Each configuration file can contain multiple manifests.
16+
A manifest specifies the desired state of an object that Kubernetes will maintain when you apply the manifest.
17+
For YAML format, each file can contain multiple manifests.

content/en/docs/reference/using-api/api-concepts.md

Lines changed: 165 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,171 @@ see the [API reference](/docs/reference/kubernetes-api/) for more information. I
122122
is not possible to access sub-resources across multiple resources - generally a new
123123
virtual resource type would be used if that becomes necessary.
124124

125+
## HTTP media types {#alternate-representations-of-resources}
126+
127+
Over HTTP, Kubernetes supports JSON and Protobuf wire encodings.
128+
129+
{{% note %}}
130+
Although YAML is widely used to define Kubernetes manifests locally, Kubernetes does not
131+
support the [`application/yaml`](https://www.rfc-editor.org/rfc/rfc9512.html) media type
132+
for API operations.
133+
134+
All JSON documents are valid YAML, so you can also use a JSON API response anywhere that is
135+
expecting a YAML input.
136+
{{% /note %}}
137+
138+
By default, Kubernetes returns objects in [JSON serialization](#json-encoding), using the
139+
`application/json` media type. Although JSON is the default, clients may request the more
140+
efficient binary [Protobuf representation](#protobuf-encoding) for better performance at scale.
141+
142+
The Kubernetes API implements standard HTTP content type negotiation: passing an
143+
`Accept` header with a `GET` call will request that the server tries to return
144+
a response in your preferred media type. If you want to send an object in Protobuf to
145+
the server for a `PUT` or `POST` request, you must set the `Content-Type` request header
146+
appropriately.
147+
148+
If you request an available media type, the API server returns a response with a suitable
149+
`Content-Type`; if none of the media types you request are supported, the API server returns
150+
a `406 Not acceptable` error message.
151+
All built-in resource types support the `application/json` media type.
152+
153+
### JSON resource encoding {#json-encoding}
154+
155+
The Kubernetes API defaults to using [JSON](https://www.json.org/json-en.html) for encoding
156+
HTTP message bodies.
157+
158+
For example:
159+
160+
1. List all of the pods on a cluster, without specifying a preferred format
161+
162+
```
163+
GET /api/v1/pods
164+
---
165+
200 OK
166+
Content-Type: application/json
167+
168+
… JSON encoded collection of Pods (PodList object)
169+
```
170+
171+
1. Create a pod by sending JSON to the server, requesting a JSON response.
172+
173+
```
174+
POST /api/v1/namespaces/test/pods
175+
Content-Type: json
176+
Accept: application/json
177+
… JSON encoded Pod object
178+
---
179+
200 OK
180+
Content-Type: application/json
181+
182+
{
183+
"kind": "Pod",
184+
"apiVersion": "v1",
185+
186+
}
187+
```
188+
189+
### Kubernetes Protobuf encoding {#protobuf-encoding}
190+
191+
Kubernetes uses an envelope wrapper to encode [Protobuf](https://protobuf.dev/) responses.
192+
That wrapper starts with a 4 byte magic number to help identify content in disk or in etcd as Protobuf
193+
(as opposed to JSON). The 4 byte magic number data is followed by a Protobuf encoded wrapper message, which
194+
describes the encoding and type of the underlying object. Within the Protobuf wrapper message,
195+
the inner object data is recorded using the `raw` field of Unknown (see the [IDL](##protobuf-encoding-idl)
196+
for more detail).
197+
198+
For example:
199+
200+
1. List all of the pods on a cluster in Protobuf format.
201+
202+
```
203+
GET /api/v1/pods
204+
Accept: application/vnd.kubernetes.protobuf
205+
---
206+
200 OK
207+
Content-Type: application/vnd.kubernetes.protobuf
208+
209+
… JSON encoded collection of Pods (PodList object)
210+
```
211+
212+
1. Create a pod by sending Protobuf encoded data to the server, but request a response
213+
in JSON.
214+
215+
```
216+
POST /api/v1/namespaces/test/pods
217+
Content-Type: application/vnd.kubernetes.protobuf
218+
Accept: application/json
219+
… binary encoded Pod object
220+
---
221+
200 OK
222+
Content-Type: application/json
223+
224+
{
225+
"kind": "Pod",
226+
"apiVersion": "v1",
227+
...
228+
}
229+
```
230+
231+
You can use both techniques together and use Kubernetes' Protobuf encoding to interact with any API that
232+
supports it, for both reads and writes. Only some API resource types are [compatible](#protobuf-encoding-compatibility)
233+
with Protobuf.
234+
235+
<a id="protobuf-encoding-idl" />
236+
237+
The wrapper format is:
238+
239+
```
240+
A four byte magic number prefix:
241+
Bytes 0-3: "k8s\x00" [0x6b, 0x38, 0x73, 0x00]
242+
243+
An encoded Protobuf message with the following IDL:
244+
message Unknown {
245+
// typeMeta should have the string values for "kind" and "apiVersion" as set on the JSON object
246+
optional TypeMeta typeMeta = 1;
247+
248+
// raw will hold the complete serialized object in protobuf. See the protobuf definitions in the client libraries for a given kind.
249+
optional bytes raw = 2;
250+
251+
// contentEncoding is encoding used for the raw data. Unspecified means no encoding.
252+
optional string contentEncoding = 3;
253+
254+
// contentType is the serialization method used to serialize 'raw'. Unspecified means application/vnd.kubernetes.protobuf and is usually
255+
// omitted.
256+
optional string contentType = 4;
257+
}
258+
259+
message TypeMeta {
260+
// apiVersion is the group/version for this type
261+
optional string apiVersion = 1;
262+
// kind is the name of the object schema. A protobuf definition should exist for this object.
263+
optional string kind = 2;
264+
}
265+
```
266+
267+
{{< note >}}
268+
Clients that receive a response in `application/vnd.kubernetes.protobuf` that does
269+
not match the expected prefix should reject the response, as future versions may need
270+
to alter the serialization format in an incompatible way and will do so by changing
271+
the prefix.
272+
{{< /note >}}
273+
274+
#### Compatibility with Kubernetes Protobuf {#protobuf-encoding-compatibility}
275+
276+
Not all API resource types support Kubernetes' Protobuf encoding; specifically, Protobuf isn't
277+
available for resources that are defined as
278+
{{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinitions" >}}
279+
or are served via the
280+
{{< glossary_tooltip text="aggregation layer" term_id="aggregation-layer" >}}.
281+
282+
As a client, if you might need to work with extension types you should specify multiple
283+
content types in the request `Accept` header to support fallback to JSON.
284+
For example:
285+
286+
```
287+
Accept: application/vnd.kubernetes.protobuf, application/json
288+
```
289+
125290

126291
## Efficient detection of changes
127292

@@ -602,116 +767,6 @@ extensions, you should make requests that specify multiple content types in the
602767
Accept: application/json;as=Table;g=meta.k8s.io;v=v1, application/json
603768
```
604769
605-
## Alternate representations of resources
606-
607-
By default, Kubernetes returns objects serialized to JSON with content type
608-
`application/json`. This is the default serialization format for the API. However,
609-
clients may request the more efficient
610-
[Protobuf representation](#protobuf-encoding) of these objects for better performance at scale.
611-
The Kubernetes API implements standard HTTP content type negotiation: passing an
612-
`Accept` header with a `GET` call will request that the server tries to return
613-
a response in your preferred media type, while sending an object in Protobuf to
614-
the server for a `PUT` or `POST` call means that you must set the `Content-Type`
615-
header appropriately.
616-
617-
The server will return a response with a `Content-Type` header if the requested
618-
format is supported, or the `406 Not acceptable` error if none of the media types you
619-
requested are supported. All built-in resource types support the `application/json`
620-
media type.
621-
622-
See the Kubernetes [API reference](/docs/reference/kubernetes-api/) for a list of
623-
supported content types for each API.
624-
625-
For example:
626-
627-
1. List all of the pods on a cluster in Protobuf format.
628-
629-
```
630-
GET /api/v1/pods
631-
Accept: application/vnd.kubernetes.protobuf
632-
---
633-
200 OK
634-
Content-Type: application/vnd.kubernetes.protobuf
635-
636-
... binary encoded PodList object
637-
```
638-
639-
1. Create a pod by sending Protobuf encoded data to the server, but request a response
640-
in JSON.
641-
642-
```
643-
POST /api/v1/namespaces/test/pods
644-
Content-Type: application/vnd.kubernetes.protobuf
645-
Accept: application/json
646-
... binary encoded Pod object
647-
---
648-
200 OK
649-
Content-Type: application/json
650-
651-
{
652-
"kind": "Pod",
653-
"apiVersion": "v1",
654-
...
655-
}
656-
```
657-
658-
Not all API resource types support Protobuf; specifically, Protobuf isn't available for
659-
resources that are defined as
660-
{{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinitions" >}}
661-
or are served via the
662-
{{< glossary_tooltip text="aggregation layer" term_id="aggregation-layer" >}}.
663-
As a client, if you might need to work with extension types you should specify multiple
664-
content types in the request `Accept` header to support fallback to JSON.
665-
For example:
666-
667-
```
668-
Accept: application/vnd.kubernetes.protobuf, application/json
669-
```
670-
671-
### Kubernetes Protobuf encoding {#protobuf-encoding}
672-
673-
Kubernetes uses an envelope wrapper to encode Protobuf responses. That wrapper starts
674-
with a 4 byte magic number to help identify content in disk or in etcd as Protobuf
675-
(as opposed to JSON), and then is followed by a Protobuf encoded wrapper message, which
676-
describes the encoding and type of the underlying object and then contains the object.
677-
678-
The wrapper format is:
679-
680-
```
681-
A four byte magic number prefix:
682-
Bytes 0-3: "k8s\x00" [0x6b, 0x38, 0x73, 0x00]
683-
684-
An encoded Protobuf message with the following IDL:
685-
message Unknown {
686-
// typeMeta should have the string values for "kind" and "apiVersion" as set on the JSON object
687-
optional TypeMeta typeMeta = 1;
688-
689-
// raw will hold the complete serialized object in protobuf. See the protobuf definitions in the client libraries for a given kind.
690-
optional bytes raw = 2;
691-
692-
// contentEncoding is encoding used for the raw data. Unspecified means no encoding.
693-
optional string contentEncoding = 3;
694-
695-
// contentType is the serialization method used to serialize 'raw'. Unspecified means application/vnd.kubernetes.protobuf and is usually
696-
// omitted.
697-
optional string contentType = 4;
698-
}
699-
700-
message TypeMeta {
701-
// apiVersion is the group/version for this type
702-
optional string apiVersion = 1;
703-
// kind is the name of the object schema. A protobuf definition should exist for this object.
704-
optional string kind = 2;
705-
}
706-
```
707-
708-
{{< note >}}
709-
Clients that receive a response in `application/vnd.kubernetes.protobuf` that does
710-
not match the expected prefix should reject the response, as future versions may need
711-
to alter the serialization format in an incompatible way and will do so by changing
712-
the prefix.
713-
{{< /note >}}
714-
715770
## Resource deletion
716771
717772
When you **delete** a resource this takes place in two phases.

0 commit comments

Comments
 (0)