Skip to content

Commit e10996a

Browse files
committed
[zh] Resync server-side-apply page
1 parent 2c7d774 commit e10996a

File tree

1 file changed

+132
-35
lines changed

1 file changed

+132
-35
lines changed

content/zh/docs/reference/using-api/server-side-apply.md

Lines changed: 132 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ weight: 25
55
min-kubernetes-server-version: 1.16
66
---
77
<!--
8-
---
98
title: Server-Side Apply
109
reviewers:
1110
- smarterclayton
@@ -15,7 +14,6 @@ reviewers:
1514
content_type: concept
1615
weight: 25
1716
min-kubernetes-server-version: 1.16
18-
---
1917
-->
2018

2119
<!-- overview -->
@@ -25,15 +23,15 @@ min-kubernetes-server-version: 1.16
2523
<!--
2624
## Introduction
2725
28-
Server Side Apply helps users and controllers manage their resources via
29-
declarative configurations. It allows them to create and/or modify their
26+
Server Side Apply helps users and controllers manage their resources through
27+
declarative configurations. Clients can create and/or modify their
3028
[objects](/docs/concepts/overview/working-with-objects/kubernetes-objects/)
31-
declaratively, simply by sending their fully specified intent.
29+
declaratively by sending their fully specified intent.
3230
-->
3331
## 简介 {#introduction}
3432

3533
服务器端应用协助用户、控制器通过声明式配置的方式管理他们的资源。
36-
它发送完整描述的目标(A fully specified intent),
34+
客户端可以发送完整描述的目标(A fully specified intent),
3735
声明式地创建和/或修改
3836
[对象](/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/)
3937

@@ -84,7 +82,7 @@ Server side apply is meant both as a replacement for the original `kubectl
8482
apply` and as a simpler mechanism for controllers to enact their changes.
8583
8684
If you have Server Side Apply enabled, the control plane tracks managed fields
87-
for all newlly created objects.
85+
for all newly created objects.
8886
-->
8987
服务器端应用既是原有 `kubectl apply` 的替代品,
9088
也是控制器发布自身变化的一个简化机制。
@@ -133,7 +131,7 @@ the appliers, results in a conflict. Shared field owners may give up ownership
133131
of a field by removing it from their configuration.
134132
135133
Field management is stored in a`managedFields` field that is part of an object's
136-
[`metadata`](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#objectmeta-v1-meta).
134+
[`metadata`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#objectmeta-v1-meta).
137135
138136
A simple example of an object created by Server Side Apply could look like this:
139137
-->
@@ -142,7 +140,8 @@ A simple example of an object created by Server Side Apply could look like this:
142140
共享字段的所有者可以放弃字段的所有权,这只需从配置文件中删除该字段即可。
143141

144142
字段管理的信息存储在 `managedFields` 字段中,该字段是对象的
145-
[`metadata`](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#objectmeta-v1-meta)中的一部分。
143+
[`metadata`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#objectmeta-v1-meta)
144+
中的一部分。
146145

147146
服务器端应用创建对象的简单示例如下:
148147

@@ -356,15 +355,14 @@ would have failed due to conflicting ownership.
356355

357356
The merging strategy, implemented with Server Side Apply, provides a generally
358357
more stable object lifecycle. Server Side Apply tries to merge fields based on
359-
the fact who manages them instead of overruling just based on values. This way
360-
it is intended to make it easier and more stable for multiple actors updating
361-
the same object by causing less unexpected interference.
358+
the actor who manages them instead of overruling based on values. This way
359+
multiple actors can update the same object without causing unexpected interference.
362360
-->
363361
## 合并策略 {#merge-strategy}
364362

365363
由服务器端应用实现的合并策略,提供了一个总体更稳定的对象生命周期。
366-
服务器端应用试图依据谁管理它们来合并字段,而不只是根据值来否决
367-
这么做是为了多个参与者可以更简单、更稳定的更新同一个对象,且避免引起意外干扰
364+
服务器端应用试图依据负责管理它们的主体来合并字段,而不是根据值来否决
365+
这么做是为了多个主体可以更新同一个对象,且不会引起意外的相互干扰
368366

369367
<!--
370368
When a user sends a "fully-specified intent" object to the Server Side Apply
@@ -387,7 +385,7 @@ merging, see
387385
A number of markers were added in Kubernetes 1.16 and 1.17, to allow API
388386
developers to describe the merge strategy supported by lists, maps, and
389387
structs. These markers can be applied to objects of the respective type,
390-
in Go files or in the OpenAPI schema definition of the
388+
in Go files or in the OpenAPI schema definition of the
391389
[CRD](/docs/reference/generated/kubernetes-api/{{< param "version" >}}#jsonschemaprops-v1-apiextensions-k8s-io):
392390
-->
393391
Kubernetes 1.16 和 1.17 中添加了一些标记,
@@ -399,18 +397,116 @@ Kubernetes 1.16 和 1.17 中添加了一些标记,
399397
<!--
400398
| Golang marker | OpenAPI extension | Accepted values | Description | Introduced in |
401399
|---|---|---|---|---|
402-
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | Applicable to lists. `atomic` and `set` apply to lists with scalar elements only. `map` applies to lists of nested types only. If configured as `atomic`, the entire list is replaced during merge; a single manager manages the list as a whole at any one time. If `set` or `map`, different managers can manage entries separately. | 1.16 |
403-
| `//+listMapKey` | `x-kubernetes-list-map-keys` | Slice of map keys that uniquely identify entries for example `["port", "protocol"]` | Only applicable when `+listType=map`. A slice of strings whose values in combination must uniquely identify list entries. While there can be multiple keys, `listMapKey` is singular because keys need to be specified individually in the Go type. | 1.16 |
400+
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | Applicable to lists. `set` applies to lists that include only scalar elements. These elements must be unique. `map` applies to lists of nested types only. The key values (see `listMapKey`) must be unique in the list. `atomic` can apply to any list. If configured as `atomic`, the entire list is replaced during merge. At any point in time, a single manager owns the list. If `set` or `map`, different managers can manage entries separately. | 1.16 |
401+
| `//+listMapKey` | `x-kubernetes-list-map-keys` | List of field names, e.g. `["port", "protocol"]` | Only applicable when `+listType=map`. A list of field names whose values uniquely identify entries in the list. While there can be multiple keys, `listMapKey` is singular because keys need to be specified individually in the Go type. The key fields must be scalars. | 1.16 |
404402
| `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to maps. `atomic` means that the map can only be entirely replaced by a single manager. `granular` means that the map supports separate managers updating individual fields. | 1.17 |
405403
| `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | Applicable to structs; otherwise same usage and OpenAPI annotation as `//+mapType`.| 1.17 |
406404
-->
407405
| Golang 标记 | OpenAPI extension | 可接受的值 | 描述 | 引入版本 |
408406
|---|---|---|---|---|
409-
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | 适用于 list。 `atomic` 和 `set` 适用于只包含标量元素的 list。 `map` 适用于只包含嵌套类型的 list。 如果配置为 `atomic`, 合并时整个列表会被替换掉; 任何时候,唯一的管理器都把列表作为一个整体来管理。如果是 `set` 或 `map` ,不同的管理器也可以分开管理条目。 | 1.16 |
410-
| `//+listMapKey` | `x-kubernetes-list-map-keys` | 用来唯一标识条目的 map keys 切片,例如 `["port", "protocol"]` | 仅当 `+listType=map` 时适用。组合值的字符串切片必须唯一标识列表中的条目。尽管有多个 key,`listMapKey` 是单数的,这是因为 key 需要在 Go 类型中单独的指定。 | 1.16 |
407+
| `//+listType` | `x-kubernetes-list-type` | `atomic`/`set`/`map` | 适用于 list。`set` 适用于仅包含标量元素的列表。这些元素必须是不重复的。`map` 仅适用于包含嵌套类型的列表。列表中的键(参见 `listMapKey`)不可以重复。`atomic` 适用于任何类型的列表。如果配置为 `atomic`,则合并时整个列表会被替换掉。任何时候,只有一个管理器负责管理指定列表。如果配置为 `set` 或 `map`,不同的管理器也可以分开管理条目。 | 1.16 |
408+
| `//+listMapKey` | `x-kubernetes-list-map-keys` | 字段名称的列表,例如`["port", "protocol"]` | 仅当 `+listType=map` 时适用。取值为字段名称的列表,这些字段值的组合能够唯一标识列表中的条目。尽管可以存在多个键,`listMapKey` 是单数的,这是因为键名需要在 Go 类型中各自独立指定。键字段必须是标量。 | 1.16 |
411409
| `//+mapType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 map。 `atomic` 指 map 只能被单个的管理器整个的替换。 `granular` 指 map 支持多个管理器各自更新自己的字段。 | 1.17 |
412410
| `//+structType` | `x-kubernetes-map-type` | `atomic`/`granular` | 适用于 structs;否则就像 `//+mapType` 有相同的用法和 openapi 注释.| 1.17 |
413411

412+
<!--
413+
If `listType` is missing, the API server interprets a
414+
`patchMergeStrategy=merge` marker as a `listType=map` and the
415+
corresponding `patchMergeKey` marker as a `listMapKey`.
416+
417+
The `atomic` list type is recursive.
418+
419+
These markers are specified as comments and don't have to be repeated as
420+
field tags.
421+
-->
422+
若未指定 `listType`,API 服务器将 `patchMergeStrategy=merge` 标记解释为
423+
`listType=map` 并且视对应的 `patchMergeKey` 标记为 `listMapKey` 取值。
424+
425+
`atomic` 列表类型是递归的。
426+
427+
这些标记都是用源代码注释的方式给出的,不必作为字段标签(tag)再重复。
428+
429+
<!--
430+
### Compatibility across topology changes
431+
-->
432+
### 拓扑变化时的兼容性 {#compatibility-across-toplogy-changes}
433+
434+
<!--
435+
On rare occurences, a CRD or built-in type author may want to change the
436+
specific topology of a field in their resource without incrementing its
437+
version. Changing the topology of types, by upgrading the cluster or
438+
updating the CRD, has different consequences when updating existing
439+
objects. There are two categories of changes: when a field goes from
440+
`map`/`set`/`granular` to `atomic` and the other way around.
441+
-->
442+
在极少的情况下,CRD 或者内置类型的作者可能希望更改其资源中的某个字段的
443+
拓扑配置,同时又不提升版本号。
444+
通过升级集群或者更新 CRD 来更改类型的拓扑信息与更新现有对象的结果不同。
445+
变更的类型有两种:一种是将字段从 `map`/`set`/`granular` 更改为 `atomic`,
446+
另一种是做逆向改变。
447+
448+
<!--
449+
When the `listType`, `mapType`, or `structType` changes from
450+
`map`/`set`/`granular` to `atomic`, the whole list, map or struct of
451+
existing objects will end-up being owned by actors who owned an element
452+
of these types. This means that any further change to these objects
453+
would cause a conflict.
454+
-->
455+
当 `listType`、`mapType` 或 `structType` 从 `map`/`set`/`granular` 改为
456+
`atomic` 时,现有对象的整个列表、映射或结构的属主都会变为这些类型的
457+
元素之一的属主。这意味着,对这些对象的进一步变更会引发冲突。
458+
459+
<!--
460+
When a list, map, or struct changes from `atomic` to
461+
`map`/`set`/`granular`, the API server won't be able to infer the new
462+
ownership of these fields. Because of that, no conflict will be produced
463+
when objects have these fields updated. For that reason, it is not
464+
recommended to change a type from `atomic` to `map`/`set`/`granular`.
465+
466+
Take for example, the custom resource:
467+
-->
468+
当一个列表、映射或结构从 `atomic` 改为 `map`/`set`/`granular` 之一
469+
时,API 服务器无法推导这些字段的新的属主。因此,当对象的这些字段
470+
再次被更新时不会引发冲突。出于这一原因,不建议将某类型从 `atomic` 改为
471+
`map`/`set`/`granular`。
472+
473+
以下面的自定义资源为例:
474+
475+
```yaml
476+
apiVersion: example.com/v1
477+
kind: Foo
478+
metadata:
479+
name: foo-sample
480+
managedFields:
481+
- manager: manager-one
482+
operation: Apply
483+
apiVersion: example.com/v1
484+
fields:
485+
f:spec:
486+
f:data: {}
487+
spec:
488+
data:
489+
key1: val1
490+
key2: val2
491+
```
492+
493+
<!--
494+
Before `spec.data` gets changed from `atomic` to `granular`,
495+
`manager-one` owns the field `spec.data`, and all the fields within it
496+
(`key1` and `key2`). When the CRD gets changed to make `spec.data`
497+
`granular`, `manager-one` continues to own the top-level field
498+
`spec.data` (meaning no other managers can delete the map called `data`
499+
without a conflict), but it no longer owns `key1` and `key2`, so another
500+
manager can then modify or delete those fields without conflict.
501+
-->
502+
在 `spec.data` 从 `atomic` 改为 `granular` 之前,`manager-one` 是
503+
`spec.data` 字段及其所包含字段(`key1` 和 `key2`)的属主。
504+
当对应的 CRD 被更改,使得 `spec.data` 变为 `granular` 拓扑时,
505+
`manager-one` 继续拥有顶层字段 `spec.data`(这意味着其他管理者想
506+
删除名为 `data` 的映射而不引起冲突是不可能的),但不再拥有
507+
`key1` 和 `key2`。因此,其他管理者可以在不引起冲突的情况下更改
508+
或删除这些字段。
509+
414510
<!--
415511
### Custom Resources
416512

@@ -435,7 +531,7 @@ type.
435531
这些注解将在合并此类型的对象时使用。
436532

437533
<!--
438-
### Using Server-Side Apply in a controller
534+
## Using Server-Side Apply in a controller
439535

440536
As a developer of a controller, you can use server-side apply as a way to
441537
simplify the update logic of your controller. The main differences with a
@@ -450,7 +546,7 @@ read-modify-write and/or patch are the following:
450546
It is strongly recommended for controllers to always "force" conflicts, since they
451547
might not be able to resolve or act on these conflicts.
452548
-->
453-
### 在控制器中使用服务器端应用 {#using-server-side-apply-in-controller}
549+
## 在控制器中使用服务器端应用 {#using-server-side-apply-in-controller}
454550

455551
控制器的开发人员可以把服务器端应用作为简化控制器的更新逻辑的方式。
456552
读-改-写 和/或 patch 的主要区别如下所示:
@@ -463,7 +559,7 @@ might not be able to resolve or act on these conflicts.
463559
强烈推荐:设置控制器在冲突时强制执行,这是因为冲突发生时,它们没有其他解决方案或措施。
464560

465561
<!--
466-
### Transferring Ownership
562+
## Transferring Ownership
467563

468564
In addition to the concurrency controls provided by [conflict resolution](#conflicts),
469565
Server Side Apply provides ways to perform coordinated
@@ -476,7 +572,7 @@ resource and its accompanying controller.
476572

477573
Say a user has defined deployment with `replicas` set to the desired value:
478574
-->
479-
### 转移所有权 {#transferring-ownership}
575+
## 转移所有权 {#transferring-ownership}
480576

481577
除了通过[冲突解决方案](#conflicts)提供的并发控制,
482578
服务器端应用提供了一些协作方式来将字段所有权从用户转移到控制器。
@@ -526,7 +622,7 @@ is not what the user wants to happen, even temporarily.
526622
<!--
527623
There are two solutions:
528624

529-
- (easy) Leave `replicas` in the configuration; when HPA eventually writes to that
625+
- (basic) Leave `replicas` in the configuration; when HPA eventually writes to that
530626
field, the system gives the user a conflict over it. At that point, it is safe
531627
to remove from the configuration.
532628

@@ -539,9 +635,9 @@ First, the user defines a new configuration containing only the `replicas` field
539635
-->
540636
这里有两个解决方案:
541637

542-
- 容易) 把 `replicas` 留在配置文件中;当 HPA 最终写入那个字段,
638+
- 基本操作)把 `replicas` 留在配置文件中;当 HPA 最终写入那个字段,
543639
系统基于此事件告诉用户:冲突发生了。在这个时间点,可以安全的删除配置文件。
544-
- 高级)然而,如果用户不想等待,比如他们想为合作伙伴保持集群清晰,
640+
- 高级操作)然而,如果用户不想等待,比如他们想为合作伙伴保持集群清晰,
545641
那他们就可以执行以下步骤,安全的从配置文件中删除 `replicas`。
546642

547643
首先,用户新定义一个只包含 `replicas` 字段的配置文件:
@@ -561,13 +657,13 @@ kubectl apply -f https://k8s.io/examples/application/ssa/nginx-deployment-replic
561657

562658
<!--
563659
If the apply results in a conflict with the HPA controller, then do nothing. The
564-
conflict just indicates the controller has claimed the field earlier in the
660+
conflict indicates the controller has claimed the field earlier in the
565661
process than it sometimes does.
566662

567663
At this point the user may remove the `replicas` field from their configuration.
568664
-->
569665
如果应用操作和 HPA 控制器产生冲突,那什么都不做。
570-
冲突只是表明控制器在更早的流程中已经对字段声明过所有权
666+
冲突表明控制器在更早的流程中已经对字段声明过所有权
571667

572668
在此时间点,用户可以从配置文件中删除 `replicas` 。
573669

@@ -583,15 +679,15 @@ automatically deleted. No clean up is required.
583679
这里不需要执行清理工作。
584680

585681
<!--
586-
## Transferring Ownership Between Users
682+
### Transferring Ownership Between Users
587683

588684
Users can transfer ownership of a field between each other by setting the field
589685
to the same value in both of their applied configs, causing them to share
590686
ownership of the field. Once the users share ownership of the field, one of them
591687
can remove the field from their applied configuration to give up ownership and
592688
complete the transfer to the other user.
593689
-->
594-
## 在用户之间转移所有权 {#transferring-ownership-between-users}
690+
### 在用户之间转移所有权 {#transferring-ownership-between-users}
595691

596692
通过在配置文件中把一个字段设置为相同的值,用户可以在他们之间转移字段的所有权,
597693
从而共享了字段的所有权。
@@ -763,7 +859,7 @@ Data: [{"op": "replace", "path": "/metadata/managedFields", "value": [{}]}]
763859
<!--
764860
This will overwrite the managedFields with a list containing a single empty
765861
entry that then results in the managedFields being stripped entirely from the
766-
object. Note that just setting the managedFields to an empty list will not
862+
object. Note that setting the managedFields to an empty list will not
767863
reset the field. This is on purpose, so managedFields never get stripped by
768864
clients not aware of the field.
769865

@@ -772,9 +868,9 @@ than the managedFields, this will result in the managedFields being reset
772868
first and the other changes being processed afterwards. As a result the
773869
applier takes ownership of any fields updated in the same request.
774870
-->
775-
这一操作将用只包含一个空条目的 list 覆写 managedFields,
871+
这一操作将用只包含一个空条目的列表覆写 managedFields,
776872
来实现从对象中整个的去除 managedFields。
777-
注意,只把 managedFields 设置为空 list 并不会重置字段
873+
注意,只把 managedFields 设置为空列表并不会重置字段
778874
这么做是有目的的,所以 managedFields 将永远不会被与该字段无关的客户删除。
779875

780876
在重置操作结合 managedFields 以外其他字段更改的场景中,
@@ -804,7 +900,8 @@ should have the same flag setting.
804900
-->
805901
## 禁用此功能 {#disabling-the-feature}
806902

807-
服务器端应用是一个 beta 版特性,默认启用。
903+
服务器端应用是一个 Beta 版特性,默认启用。
808904
要关闭此[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates),
809905
你需要在启动 `kube-apiserver` 时包含参数 `--feature-gates ServerSideApply=false`。
810-
如果你有多个 `kube-apiserver` 副本,他们都应该有相同的标记设置。
906+
如果你有多个 `kube-apiserver` 副本,它们的标志设置应该都相同。
907+

0 commit comments

Comments
 (0)