@@ -150,7 +150,7 @@ sub-resources. Common subresources include:
150
150
* ` /binding ` : Used to bind a resource representing a user request (e.g., Pod,
151
151
PersistentVolumeClaim) to a cluster infrastructure resource (e.g., Node,
152
152
PersistentVolume).
153
- * ` /status ` : Used to write just the status portion of a resource. For
153
+ * ` /status ` : Used to write just the ` status ` portion of a resource. For
154
154
example, the ` /pods ` endpoint only allows updates to ` metadata ` and ` spec ` ,
155
155
since those reflect end-user intent. An automated process should be able to
156
156
modify status for users to see by sending an updated Pod kind to the server to
@@ -250,25 +250,35 @@ tooling to decorate objects with additional metadata for their own use.
250
250
#### Spec and Status
251
251
252
252
By convention, the Kubernetes API makes a distinction between the specification
253
- of the desired state of an object (a nested object field called " spec" ) and the
253
+ of the desired state of an object (a nested object field called ` spec ` ) and the
254
254
status of the object at the current time (a nested object field called
255
- " status" ). The specification is a complete description of the desired state,
255
+ ` status ` ). The specification is a complete description of the desired state,
256
256
including configuration settings provided by the user,
257
257
[ default values] ( #defaulting ) expanded by the system, and properties initialized
258
258
or otherwise changed after creation by other ecosystem components (e.g.,
259
259
schedulers, auto-scalers), and is persisted in stable storage with the API
260
260
object. If the specification is deleted, the object will be purged from the
261
- system. The status summarizes the current state of the object in the system, and
262
- is usually persisted with the object by automated processes but may be
263
- generated on the fly. At some cost and perhaps some temporary degradation in
264
- behavior, the status could be reconstructed by observation if it were lost.
265
-
266
- When a new version of an object is POSTed or PUT, the "spec" is updated and
267
- available immediately. Over time the system will work to bring the "status" into
268
- line with the "spec". The system will drive toward the most recent "spec"
269
- regardless of previous versions of that stanza. In other words, if a value is
261
+ system.
262
+
263
+ The ` status ` summarizes the current state of the object in the system, and is
264
+ usually persisted with the object by automated processes but may be generated
265
+ on the fly. As a general guideline, fields in ` status ` should be the most recent
266
+ observations of actual state, but they may contain information such as the
267
+ results of allocations or similar operations which are executed in response to
268
+ the object's ` spec ` . See [ below] ( #representing-allocated-values ) for more
269
+ details.
270
+
271
+ Types with both ` spec ` and ` status ` stanzas can (and usually should) have distinct
272
+ authorization scopes for them. This allows users to be granted full write
273
+ access to ` spec ` and read-only access to status, while relevant controllers are
274
+ granted read-only access to ` spec ` but full write access to status.
275
+
276
+ When a new version of an object is POSTed or PUT, the ` spec ` is updated and
277
+ available immediately. Over time the system will work to bring the ` status ` into
278
+ line with the ` spec ` . The system will drive toward the most recent ` spec `
279
+ regardless of previous versions of that stanza. For example, if a value is
270
280
changed from 2 to 5 in one PUT and then back down to 3 in another PUT the system
271
- is not required to 'touch base' at 5 before changing the " status" to 3. In other
281
+ is not required to 'touch base' at 5 before changing the ` status ` to 3. In other
272
282
words, the system's behavior is * level-based* rather than * edge-based* . This
273
283
enables robust behavior in the presence of missed intermediate state changes.
274
284
@@ -279,8 +289,8 @@ specification should have declarative rather than imperative names and
279
289
semantics -- they represent the desired state, not actions intended to yield the
280
290
desired state.
281
291
282
- The PUT and POST verbs on objects MUST ignore the " status" values, to avoid
283
- accidentally overwriting the status in read-modify-write scenarios. A ` /status `
292
+ The PUT and POST verbs on objects MUST ignore the ` status ` values, to avoid
293
+ accidentally overwriting the ` status ` in read-modify-write scenarios. A ` /status `
284
294
subresource MUST be provided to enable system components to update statuses of
285
295
resources they manage.
286
296
@@ -295,21 +305,20 @@ alternative resource representations that allow mutation of the status, or
295
305
performing custom actions on the object.
296
306
297
307
All objects that represent a physical resource whose state may vary from the
298
- user's desired intent SHOULD have a " spec" and a " status" . Objects whose state
299
- cannot vary from the user's desired intent MAY have only " spec" , and MAY rename
300
- " spec" to a more appropriate name.
308
+ user's desired intent SHOULD have a ` spec ` and a ` status ` . Objects whose state
309
+ cannot vary from the user's desired intent MAY have only ` spec ` , and MAY rename
310
+ ` spec ` to a more appropriate name.
301
311
302
- Objects that contain both spec and status should not contain additional
312
+ Objects that contain both ` spec ` and ` status ` should not contain additional
303
313
top-level fields other than the standard metadata fields.
304
314
305
315
Some objects which are not persisted in the system - such as ` SubjectAccessReview `
306
- and other webhook style calls - may choose to add spec and status to encapsulate
307
- a "call and response" pattern. The spec is the request (often a request for
308
- information) and the status is the response. For these RPC like objects the only
316
+ and other webhook style calls - may choose to add ` spec ` and ` status ` to encapsulate
317
+ a "call and response" pattern. The ` spec ` is the request (often a request for
318
+ information) and the ` status ` is the response. For these RPC like objects the only
309
319
operation may be POST, but having a consistent schema between submission and
310
320
response reduces the complexity of these clients.
311
321
312
-
313
322
##### Typical status properties
314
323
315
324
** Conditions** provide a standard mechanism for higher-level status reporting
@@ -343,7 +352,7 @@ Conditions are most useful when they follow some consistent conventions:
343
352
344
353
* Not all controllers will observe the previous advice about reporting
345
354
"Unknown" or "False" values. For known conditions, the absence of a
346
- condition status should be interpreted the same as ` Unknown ` , and
355
+ condition ` status ` should be interpreted the same as ` Unknown ` , and
347
356
typically indicates that reconciliation has not yet finished (or that the
348
357
resource state may not yet be observable).
349
358
@@ -365,10 +374,10 @@ Conditions are most useful when they follow some consistent conventions:
365
374
resource, rather than describing the current state transitions. This
366
375
typically means that the name should be an adjective ("Ready", "OutOfDisk")
367
376
or a past-tense verb ("Succeeded", "Failed") rather than a present-tense verb
368
- ("Deploying"). Intermediate states may be indicated by setting the status of
377
+ ("Deploying"). Intermediate states may be indicated by setting the ` status ` of
369
378
the condition to ` Unknown ` .
370
379
371
- * For state transitions which take a long period of time (rule of thumb: > 1
380
+ * For state transitions which take a long period of time (e.g. more than 1
372
381
minute), it is reasonable to treat the transition itself as an observed
373
382
state. In these cases, the Condition (such as "Resizing") itself should not
374
383
be transient, and should instead be signalled using the
@@ -414,7 +423,7 @@ can cause a large fan-out effect for some resources.
414
423
Condition types should be named in PascalCase. Short condition names are
415
424
preferred (e.g. "Ready" over "MyResourceReady").
416
425
417
- Condition status values may be ` True ` , ` False ` , or ` Unknown ` . The absence of a
426
+ Condition ` status ` values may be ` True ` , ` False ` , or ` Unknown ` . The absence of a
418
427
condition should be interpreted the same as ` Unknown ` . How controllers handle
419
428
` Unknown ` depends on the Condition in question.
420
429
@@ -486,7 +495,7 @@ referring object's status.
486
495
487
496
For references to specific objects, see [ Object references] ( #object-references ) .
488
497
489
- References in the status of the referee to the referrer may be permitted, when
498
+ References in the ` status ` of the referee to the referrer may be permitted, when
490
499
the references are one-to-one and do not need to be frequently updated,
491
500
particularly in an edge-based manner.
492
501
@@ -1671,7 +1680,6 @@ be less than 256", "must be greater than or equal to 0". Do not use words
1671
1680
like "larger than", "bigger than", "more than", "higher than", etc.
1672
1681
* When specifying numeric ranges, use inclusive ranges when possible.
1673
1682
1674
-
1675
1683
# # Automatic Resource Allocation And Deallocation
1676
1684
1677
1685
API objects often are [union](#Unions) object containing the following:
@@ -1694,3 +1702,122 @@ allocates resources such as `NodePorts` and `ClusterIPs` and automatically fill
1694
1702
represent them in case of the service is of type `NodePort` or `ClusterIP` (`discriminator` values).
1695
1703
These resources and the fields representing them are automatically cleared when the users changes
1696
1704
service type to `ExternalName` where these resources and field values no longer apply.
1705
+
1706
+ # # Representing Allocated Values
1707
+
1708
+ Many API types include values that are allocated on behalf of the user from
1709
+ some larger space (e.g. IP addresses from a range, or storage bucket names).
1710
+ These allocations are usually driven by controllers asynchronously to the
1711
+ user's API operations. Sometimes the user can request a specific value and a
1712
+ controller must confirm or reject that request. There are many examples of
1713
+ this in Kubernetes, and there a handful of patterns used to represent it.
1714
+
1715
+ The common theme among all of these is that the system should not trust users
1716
+ with such fields, and must verify or otherwise confirm such requests before
1717
+ using them.
1718
+
1719
+ Some examples :
1720
+
1721
+ * Service `clusterIP`: Users may request a specific IP in `spec` or will be
1722
+ allocated one (in the same `spec` field). If a specific IP is requested, the
1723
+ apiserver will either confirm that IP is available or, failing that, will
1724
+ reject the API operation synchronously (rare). Consumers read the result
1725
+ from `spec`. This is safe because the value is either valid or it is never
1726
+ stored.
1727
+ * Service `loadBalancerIP`: Users may request a specific IP in `spec` or will
1728
+ be allocated one which is reported in `status`. If a specific IP is
1729
+ requested, the LB controller will either ensure that IP is available or
1730
+ report failure asynchronously. Consumers read the result from `status`.
1731
+ This is safe because most users do not have acces to write to `status`.
1732
+ * PersistentVolumeClaims: Users may request a specific PersistentVolume in
1733
+ ` spec` or will be allocated one (in the same `spec` field). If a specific PV
1734
+ is requested, the volume controller will either ensure that the volume is
1735
+ available or report failure asynchronously. Consumers read the result by
1736
+ examining both the PVC and the PV. This is more complicated than the others
1737
+ because the `spec` value is stored before being confirmed, which could
1738
+ (hypothetically, thanks to extra checking) lead to a user accessing someone
1739
+ else's PV.
1740
+ * VolumeSnapshots: Users may request a particular source to be snaphotted in
1741
+ ` spec` . The details of the resulting snapshot is reflected in `status`.
1742
+
1743
+ A counter-example :
1744
+
1745
+ * Service `externalIPs`: Users must specify one or more specific IPs in `spec`.
1746
+ The system cannot easily verify those IPs (by their definition, they are
1747
+ external). Consumers read the result from `spec`. This is UNSAFE and has
1748
+ caused problems with untrusted users.
1749
+
1750
+ In the past, API conventions dictated that `status` fields always come from
1751
+ observation, which made some of these cases more complicated than necessary.
1752
+ The conventions have been updated to allow `status` to hold such allocated
1753
+ values. This is not a one-size-fits-all solution, though.
1754
+
1755
+ # ## When to use a `spec` field
1756
+
1757
+ New APIs should almost never do this. Instead, they should use `status`.
1758
+ PersistentVolumes might have been simpler if we had done this.
1759
+
1760
+ # ## When to use a `status` field
1761
+
1762
+ Storing such values in `status` is the easiest and most straight-forward
1763
+ pattern. This is appropriate when :
1764
+
1765
+ * the allocated value is highly coupled to the rest of the object (e.g. pod
1766
+ resource allocations)
1767
+ * the allocated value is always or almost always needed (i.e. most instances of
1768
+ this type will have a value)
1769
+ * the schema and controller are known a priori (i.e. it's not an extension)
1770
+ * it is "safe" to allow the controller(s) to write to `status` (i.e.
1771
+ there's low risk of them causing problems via other `status` fields).
1772
+
1773
+ Consumers of such values can look at the `status` field for the "final" value
1774
+ or an error or condition indicating why the allocation could not be performed.
1775
+
1776
+ # ### Sequencing operations
1777
+
1778
+ Since almost everything is happening asynchronously to almost everything else,
1779
+ controller implementations should take care around the ordering of operations.
1780
+ For example, whether the controller updates a `status` field before or after it
1781
+ actuates a change depends on what guarantees need to be made to observers of
1782
+ the system. In some cases, writing to a `status` field represents an
1783
+ acknowledgement or acceptance of a `spec` value, and it is OK to write it before
1784
+ actuation. However, if it would be problematic for a client to observe the
1785
+ ` status` value before it is actuated then the controller must actuate first and
1786
+ update `status` afterward. In some rarer cases, controllers will need to
1787
+ acknowledge, then actuate, then update to a "final" value.
1788
+
1789
+ Controllers must take care to consider how a `status` field will be handled in
1790
+ the case of interrupted control loops (e.g. controller crash and restart), and
1791
+ must act idempotently and consistently. This is particularly important when
1792
+ using an informer-fed cache, which might not be updated with recent writes.
1793
+ Using a resourceVersion precondition to detect the "conflict" is the common
1794
+ pattern in this case. See [this issue](http://issue.k8s.io/105199) for an
1795
+ example.
1796
+
1797
+ # ## When to use a different type
1798
+
1799
+ Storing allocated values in a different type is more complicated but also more
1800
+ flexible. This is most appropriate when :
1801
+
1802
+ * the allocated value is optional (i.e. many instances of this type will not
1803
+ have a value at all)
1804
+ * the schema and controller are not known a priori (i.e. it's an extension)
1805
+ * the schema is sufficiently complicated (i.e. it doesn't make sense to burden
1806
+ the main type with it)
1807
+ * access control for this type demands finer granularity than "all of status"
1808
+ * the lifecycle of the allocated value is different than the lifecycle of the
1809
+ allocation holder
1810
+
1811
+ Services and Endpoints could be considered a form of this pattern, as could
1812
+ PersistentVolumes and PersistentVolumeClaims.
1813
+
1814
+ When using this pattern, you must account for lifecycle of the allocated
1815
+ objects (who cleans them up and when) as well as the "linkage" between them and
1816
+ the main type (often using the same name, an object-ref field, or a selector).
1817
+
1818
+ There will always be some cases which could follow either path, and these will
1819
+ need human evaluation to decide. For example, Service `clusterIP` is highly
1820
+ coupled to the rest of Service and most instances use it. But it also is
1821
+ strictly optional and has an increasingly complicated schema of related fields.
1822
+ An argument could be made for either path.
1823
+ >>>>>>> 49012588 (Loosen the meaning of status in API conventions)
0 commit comments