Switch language name 'zh' to 'zh-cn'

This is the first step to rename 'zh' to 'zh-cn'. There are several reasons why we rename the language name.

- The upstream docsy theme changed the language name, leading to many warnings during site build;
  The side-effect is that the i18n strings are no longer working.
- We believe renaming the language is the right thing to do, because this move can make room for other variants of Chinese language, such as 'zh-tw', 'zh-sg' etc.

There would be several follow-ups to this PR, such as fixing the intra-site links, adding redirects etc.

We will lock up changes to zh/zh-cn pages for the moment, until this one gets in.

This PR is based on commit cdad0a7342.
This commit is contained in:
Qiming Teng
2022-06-10 20:25:27 +08:00
parent 3d345b1816
commit c52818c03d
1347 changed files with 8 additions and 6 deletions
@@ -0,0 +1,56 @@
---
title: API 访问控制
weight: 15
no_list: true
---
<!--
title: API Access Control
weight: 15
no_list: true
-->
<!--
For an introduction to how Kubernetes implements and controls API access,
read [Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/).
Reference documentation:
-->
关于 Kubernetes 如何实现和控制 API 访问的介绍性材料,可阅读
[控制 Kubernetes API 的访问](/zh/docs/concepts/security/controlling-access/)。
参考文档:
<!--
- [Authenticating](/docs/reference/access-authn-authz/authentication/)
- [Authenticating with Bootstrap Tokens](/docs/reference/access-authn-authz/bootstrap-tokens/)
- [Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/)
- [Dynamic Admission Control](/docs/reference/access-authn-authz/extensible-admission-controllers/)
- [Authorization](/docs/reference/access-authn-authz/authorization/)
- [Role Based Access Control](/docs/reference/access-authn-authz/rbac/)
- [Attribute Based Access Control](/docs/reference/access-authn-authz/abac/)
- [Node Authorization](/docs/reference/access-authn-authz/node/)
- [Webhook Authorization](/docs/reference/access-authn-authz/webhook/)
- [Certificate Signing Requests](/docs/reference/access-authn-authz/certificate-signing-requests/)
- including [CSR approval](/docs/reference/access-authn-authz/certificate-signing-requests/#approval-rejection)
and [certificate signing](/docs/reference/access-authn-authz/certificate-signing-requests/#signing)
- Service accounts
- [Developer guide](/docs/tasks/configure-pod-container/configure-service-account/)
- [Administration](/docs/reference/access-authn-authz/service-accounts-admin/)
-->
- [身份认证](/zh/docs/reference/access-authn-authz/authentication/)
- [使用启动引导令牌来执行身份认证](/zh/docs/reference/access-authn-authz/bootstrap-tokens/)
- [准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/)
- [动态准入控制](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/)
- [鉴权与授权](/zh/docs/reference/access-authn-authz/authorization/)
- [基于角色的访问控制](/zh/docs/reference/access-authn-authz/rbac/)
- [基于属性的访问控制](/zh/docs/reference/access-authn-authz/abac/)
- [节点鉴权](/zh/docs/reference/access-authn-authz/node/)
- [Webhook 鉴权](/zh/docs/reference/access-authn-authz/webhook/)
- [证书签名请求](/zh/docs/reference/access-authn-authz/certificate-signing-requests/)
- 包含 [CSR 的批复](/zh/docs/reference/access-authn-authz/certificate-signing-requests/#approval-rejection)
和[证书签名](/zh/docs/reference/access-authn-authz/certificate-signing-requests/#signing)
- 服务账号
- [开发者指南](/zh/docs/tasks/configure-pod-container/configure-service-account/)
- [管理文档](/zh/docs/reference/access-authn-authz/service-accounts-admin/)
@@ -0,0 +1,307 @@
---
approvers:
- erictune
- lavalamp
- deads2k
- liggitt
title: 使用 ABAC 鉴权
content_type: concept
---
<!--
reviewers:
- erictune
- lavalamp
- deads2k
- liggitt
title: Using ABAC Authorization
content_type: concept
weight: 80
-->
<!-- overview -->
<!--
Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together.
-->
基于属性的访问控制(Attribute-based access control - ABAC)定义了访问控制范例,
其中通过使用将属性组合在一起的策略来向用户授予访问权限。
<!-- body -->
<!--
## Policy File Format
To enable `ABAC` mode, specify `--authorization-policy-file=SOME_FILENAME` and `--authorization-mode=ABAC` on startup.
The file format is [one JSON object per line](http://jsonlines.org/). There
should be no enclosing list or map, only one map per line.
Each line is a "policy object", where each such object is a map with the following
properties:
- Versioning properties:
- `apiVersion`, type string; valid values are "abac.authorization.kubernetes.io/v1beta1". Allows versioning and conversion of the policy format.
- `kind`, type string: valid values are "Policy". Allows versioning and conversion of the policy format.
- `spec` property set to a map with the following properties:
- Subject-matching properties:
- `user`, type string; the user-string from `--token-auth-file`. If you specify `user`, it must match the username of the authenticated user.
- `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `system:authenticated` matches all authenticated requests. `system:unauthenticated` matches all unauthenticated requests.
- Resource-matching properties:
- `apiGroup`, type string; an API group.
- Ex: `apps`, `networking.k8s.io`
- Wildcard: `*` matches all API groups.
- `namespace`, type string; a namespace.
- Ex: `kube-system`
- Wildcard: `*` matches all resource requests.
- `resource`, type string; a resource type
- Ex: `pods`, `deployments`
- Wildcard: `*` matches all resource requests.
- Non-resource-matching properties:
- `nonResourcePath`, type string; non-resource request paths.
- Ex: `/version` or `/apis`
- Wildcard:
- `*` matches all non-resource requests.
- `/foo/*` matches all subpaths of `/foo/`.
- `readonly`, type boolean, when true, means that the Resource-matching policy only applies to get, list, and watch operations, Non-resource-matching policy only applies to get operation.
-->
## 策略文件格式
基于 `ABAC` 模式,可以这样指定策略文件 `--authorization-policy-file=SOME_FILENAME`
此文件格式是 [JSON Lines](https://jsonlines.org/),不应存在外层的列表或映射,每行应只有一个映射。
每一行都是一个策略对象,策略对象是具有以下属性的映射:
- 版本控制属性:
- `apiVersion`,字符串类型:有效值为`abac.authorization.kubernetes.io/v1beta1`,允许对策略格式进行版本控制和转换。
- `kind`,字符串类型:有效值为 `Policy`,允许对策略格式进行版本控制和转换。
- `spec` 配置为具有以下映射的属性:
- 主体匹配属性:
- `user`,字符串类型;来自 `--token-auth-file` 的用户字符串,如果你指定 `user`,它必须与验证用户的用户名匹配。
- `group`,字符串类型;如果指定 `group`,它必须与经过身份验证的用户的一个组匹配,`system:authenticated` 匹配所有经过身份验证的请求。
`system:unauthenticated` 匹配所有未经过身份验证的请求。
- 资源匹配属性:
- `apiGroup`,字符串类型;一个 API 组。
- 例: `apps`, `networking.k8s.io`
- 通配符:`*`匹配所有 API 组。
- `namespace`,字符串类型;一个命名空间。
- 例如:`kube-system`
- 通配符:`*`匹配所有资源请求。
- `resource`,字符串类型;资源类型。
- 例:`pods`, `deployments`
- 通配符:`*`匹配所有资源请求。
- 非资源匹配属性:
- `nonResourcePath`,字符串类型;非资源请求路径。
- 例如:`/version``/apis`
- 通配符:
- `*` 匹配所有非资源请求。
- `/foo/*` 匹配 `/foo/` 的所有子路径。
- `readonly`,键入布尔值,如果为 true,则表示该策略仅适用于 get、list 和 watch 操作。
{{< note >}}
<!--
An unset property is the same as a property set to the zero value for its type
(e.g. empty string, 0, false). However, unset should be preferred for
readability.
In the future, policies may be expressed in a JSON format, and managed via a
REST interface.
-->
属性未设置等效于属性被设置为对应类型的零值( 例如空字符串、0、false),然而,出于可读性考虑,应尽量选择不设置这类属性。
在将来,策略可能以 JSON 格式表示,并通过 REST 界面进行管理。
{{< /note >}}
<!--
## Authorization Algorithm
A request has attributes which correspond to the properties of a policy object.
When a request is received, the attributes are determined. Unknown attributes
are set to the zero value of its type (e.g. empty string, 0, false).
A property set to `"*"` will match any value of the corresponding attribute.
The tuple of attributes is checked for a match against every policy in the
policy file. If at least one line matches the request attributes, then the
request is authorized (but may fail later validation).
To permit any authenticated user to do something, write a policy with the
group property set to `"system:authenticated"`.
To permit any unauthenticated user to do something, write a policy with the
group property set to `"system:unauthenticated"`.
To permit a user to do anything, write a policy with the apiGroup, namespace,
resource, and nonResourcePath properties set to `"*"`.
-->
## 鉴权算法
请求具有与策略对象的属性对应的属性。
当接收到请求时,确定属性。未知属性设置为其类型的零值(例如:空字符串,0,false)。
设置为 `"*"` 的属性将匹配相应属性的任何值。
检查属性的元组,以匹配策略文件中的每个策略。如果至少有一行匹配请求属性,则请求被鉴权(但仍可能无法通过稍后的合法性检查)。
要允许任何经过身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authenticated"`
要允许任何未经身份验证的用户执行某些操作,请将策略组属性设置为 `"system:unauthenticated"`
要允许用户执行任何操作,请使用设置为 `"*"` 的 apiGroupnamespaceresource 和 nonResourcePath 属性编写策略。
<!--
## Kubectl
Kubectl uses the `/api` and `/apis` endpoints of api-server to discover
served resource types, and validates objects sent to the API by create/update
operations using schema information located at `/openapi/v2`.
When using ABAC authorization, those special resources have to be explicitly
exposed via the `nonResourcePath` property in a policy (see [examples](#examples) below):
* `/api`, `/api/*`, `/apis`, and `/apis/*` for API version negotiation.
* `/version` for retrieving the server version via `kubectl version`.
* `/swaggerapi/*` for create/update operations.
To inspect the HTTP calls involved in a specific kubectl operation you can turn
up the verbosity:
kubectl --v=8 version
-->
## kubectl
kubectl 使用 api-server 的 `/api``/apis` 端点来发现服务资源类型,
并使用位于 `/openapi/v2` 的模式信息来验证通过创建/更新操作发送到 API 的对象。
当使用 ABAC 鉴权时,这些特殊资源必须显式地通过策略中的 `nonResourcePath` 属性暴露出来(参见下面的 [示例](#examples)):
* `/api``/api/*``/apis``/apis/*` 用于 API 版本协商。
* `/version` 通过 `kubectl version` 检索服务器版本。
* `/swaggerapi/*` 用于创建 / 更新操作。
要检查涉及到特定 kubectl 操作的 HTTP 调用,你可以调整详细程度:
kubectl --v=8 version
<!--
## Examples
1. Alice can do anything to all resources:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
```
2. The Kubelet can read any pods:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
```
3. The Kubelet can read and write events:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
```
-->
## 例子 {#examples}
1. Alice 可以对所有资源做任何事情:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
```
2. kubelet 可以读取任何 pod
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
```
3. kubelet 可以读写事件:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
```
<!--
4. Bob can just read pods in namespace "projectCaribou":
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
```
5. Anyone can make read-only requests to all non-resource paths:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
```
-->
4. Bob 可以在命名空间 `projectCaribou` 中读取 pod
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
```
5. 任何人都可以对所有非资源路径进行只读请求:
```json
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
```
<!--
[Complete file example](http://releases.k8s.io/{{< param "fullversion" >}}/pkg/auth/authorizer/abac/example_policy_file.jsonl)
## A quick note on service accounts
Every service account has a corresponding ABAC username, and that service account's user name is generated according to the naming convention:
```shell
system:serviceaccount:<namespace>:<serviceaccountname>
```
-->
[完整文件示例](https://releases.k8s.io/{{< param "fullversion" >}}/pkg/auth/authorizer/abac/example_policy_file.jsonl)
## 服务帐户的快速说明
服务帐户自动生成用户。用户名是根据命名约定生成的:
```shell
system:serviceaccount:<namespace>:<serviceaccountname>
```
<!--
Creating a new namespace leads to the creation of a new service account in the following format:
```shell
system:serviceaccount:<namespace>:default
```
For example, if you wanted to grant the default service account (in the `kube-system` namespace) full
privilege to the API using ABAC, you would add this line to your policy file:
```json
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
```
The apiserver will need to be restarted to pickup the new policy lines.
-->
创建新的命名空间也会导致创建一个新的服务帐户:
```shell
system:serviceaccount:<namespace>:default
```
例如,如果要将 API 的 kube-system 完整权限中的默认服务帐户授予,则可以将此行添加到策略文件中:
```json
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
```
需要重新启动 apiserver 以获取新的策略行。
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,455 @@
---
title: 鉴权概述
content_type: concept
weight: 60
---
<!--
reviewers:
- erictune
- lavalamp
- deads2k
- liggitt
title: Authorization Overview
content_type: concept
weight: 60
-->
<!-- overview -->
<!--
Learn more about Kubernetes authorization, including details about creating
policies using the supported authorization modules.
-->
了解有关 Kubernetes 鉴权的更多信息,包括使用支持的鉴权模块创建策略的详细信息。
<!-- body -->
<!--
In Kubernetes, you must be authenticated (logged in) before your request can be
authorized (granted permission to access). For information about authentication,
see [Accessing Control Overview](/docs/concepts/security/controlling-access/).
Kubernetes expects attributes that are common to REST API requests. This means
that Kubernetes authorization works with existing organization-wide or
cloud-provider-wide access control systems which may handle other APIs besides
the Kubernetes API.
-->
在 Kubernetes 中,你必须在鉴权(授予访问权限)之前进行身份验证(登录),有关身份验证的信息,
请参阅[访问控制概述](/zh/docs/concepts/security/controlling-access/).
Kubernetes 期望请求中存在 REST API 常见的属性。
这意味着 Kubernetes 鉴权适用于现有的组织范围或云提供商范围的访问控制系统,
除了 Kubernetes API 之外,它还可以处理其他 API。
<!--
## Determine Whether a Request is Allowed or Denied
Kubernetes authorizes API requests using the API server. It evaluates all of the
request attributes against all policies and allows or denies the request. All
parts of an API request must be allowed by some policy in order to proceed. This
means that permissions are denied by default.
(Although Kubernetes uses the API server, access controls and policies that
depend on specific fields of specific kinds of objects are handled by Admission
Controllers.)
When multiple authorization modules are configured, each is checked in sequence.
If any authorizer approves or denies a request, that decision is immediately
returned and no other authorizer is consulted. If all modules have no opinion on
the request, then the request is denied. A deny returns an HTTP status code 403.
-->
## 确定是允许还是拒绝请求
Kubernetes 使用 API 服务器对 API 请求进行鉴权。
它根据所有策略评估所有请求属性来决定允许或拒绝请求。
一个 API 请求的所有部分都必须被某些策略允许才能继续。
这意味着默认情况下拒绝权限。
(尽管 Kubernetes 使用 API 服务器,但是依赖于特定对象种类的特定字段的访问控制
和策略由准入控制器处理。)
当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。
如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。
如果所有模块对请求没有意见,则拒绝该请求。
被拒绝响应返回 HTTP 状态代码 403。
<!--
## Review Your Request Attributes
Kubernetes reviews only the following API request attributes:
* **user** - The `user` string provided during authentication.
* **group** - The list of group names to which the authenticated user belongs.
* **extra** - A map of arbitrary string keys to string values, provided by the authentication layer.
* **API** - Indicates whether the request is for an API resource.
* **Request path** - Path to miscellaneous non-resource endpoints like `/api` or `/healthz`.
* **API request verb** - API verbs `get`, `list`, `create`, `update`, `patch`, `watch`, `proxy`, `redirect`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see [Determine the request verb](/docs/reference/access-authn-authz/authorization/#determine-whether-a-request-is-allowed-or-denied) below.
* **HTTP request verb** - HTTP verbs `get`, `post`, `put`, and `delete` are used for non-resource requests.
* **Resource** - The ID or name of the resource that is being accessed (for resource requests only) -- For resource requests using `get`, `update`, `patch`, and `delete` verbs, you must provide the resource name.
* **Subresource** - The subresource that is being accessed (for resource requests only).
* **Namespace** - The namespace of the object that is being accessed (for namespaced resource requests only).
* **API group** - The {{< glossary_tooltip text="API Group" term_id="api-group" >}} being accessed (for resource requests only). An empty string designates the _core_ [API group](/docs/reference/using-api/#api-groups).
-->
## 审查你的请求属性
Kubernetes 仅审查以下 API 请求属性:
* **用户** - 身份验证期间提供的 `user` 字符串。
* **组** - 经过身份验证的用户所属的组名列表。
* **额外信息** - 由身份验证层提供的任意字符串键到字符串值的映射。
* **API** - 指示请求是否针对 API 资源。
* **请求路径** - 各种非资源端点的路径,如 `/api``/healthz`
* **API 请求动词** - API 动词 `get``list``create``update``patch``watch`
`proxy``redirect``delete``deletecollection` 用于资源请求。
要确定资源 API 端点的请求动词,请参阅
[确定请求动词](#determine-the-request-verb)。
* **HTTP 请求动词** - HTTP 动词 `get``post``put``delete` 用于非资源请求。
* **Resource** - 正在访问的资源的 ID 或名称(仅限资源请求)-
对于使用 `get``update``patch``delete` 动词的资源请求,你必须提供资源名称。
* **子资源** - 正在访问的子资源(仅限资源请求)。
* **名字空间** - 正在访问的对象的名称空间(仅适用于名字空间资源请求)。
* **API 组** - 正在访问的 {{< glossary_tooltip text="API 组" term_id="api-group" >}}
(仅限资源请求)。空字符串表示[核心 API 组](/zh/docs/reference/using-api/#api-groups)。
<!--
## Determine the Request Verb
**Non-resource requests**
Requests to endpoints other than `/api/v1/...` or `/apis/<group>/<version>/...`
are considered "non-resource requests", and use the lower-cased HTTP method of the request as the verb.
For example, a `GET` request to endpoints like `/api` or `/healthz` would use `get` as the verb.
-->
## 确定请求动词 {#determine-the-request-verb}
**非资源请求**
对于 `/api/v1/...``/apis/<group>/<version>/...` 之外的端点的请求被
视为“非资源请求(Non-Resource Requests)”,并使用该请求的 HTTP 方法的
小写形式作为其请求动词。
例如,对 `/api``/healthz` 这类端点的 `GET` 请求将使用 `get` 作为其动词。
<!--
**Resource requests**
To determine the request verb for a resource API endpoint, review the HTTP verb
used and whether or not the request acts on an individual resource or a
collection of resources:
-->
**资源请求**
要确定对资源 API 端点的请求动词,需要查看所使用的 HTTP 动词以及该请求是针对
单个资源还是一组资源:
<!--
HTTP verb | request verb
----------|---------------
POST | create
GET, HEAD | get (for individual resources), list (for collections)
PUT | update
PATCH | patch
DELETE | delete (for individual resources), deletecollection (for collections)
-->
HTTP 动词 | 请求动词
----------|---------------
POST | create
GET, HEAD | get (针对单个资源)、list(针对集合)
PUT | update
PATCH | patch
DELETE | delete(针对单个资源)、deletecollection(针对集合)
<!--
Kubernetes sometimes checks authorization for additional permissions using specialized verbs. For example:
* [PodSecurityPolicy](/docs/concepts/security/pod-security-policy/)
* `use` verb on `podsecuritypolicies` resources in the `policy` API group.
* [RBAC](/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping)
* `bind` and `escalate` verbs on `roles` and `clusterroles` resources in the `rbac.authorization.k8s.io` API group.
* [Authentication](/docs/reference/access-authn-authz/authentication/)
* `impersonate` verb on `users`, `groups`, and `serviceaccounts` in the core API group, and the `userextras` in the `authentication.k8s.io` API group.
-->
Kubernetes 有时使用专门的动词以对额外的权限进行鉴权。例如:
* [PodSecurityPolicy](/zh/docs/concepts/security/pod-security-policy/)
* `policy` API 组中 `podsecuritypolicies` 资源使用 `use` 动词
* [RBAC](/zh/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping)
*`rbac.authorization.k8s.io` API 组中 `roles``clusterroles` 资源的 `bind`
`escalate` 动词
* [身份认证](/zh/docs/reference/access-authn-authz/authentication/)
* 对核心 API 组中 `users``groups``serviceaccounts` 以及 `authentication.k8s.io`
API 组中的 `userextras` 所使用的 `impersonate` 动词。
<!--
## Authorization Modules {#authorization-modules}
* **Node** - A special-purpose authorizer that grants permissions to kubelets based on the pods they are scheduled to run. To learn more about using the Node authorization mode, see [Node Authorization](/docs/reference/access-authn-authz/node/).
* **ABAC** - Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes, etc). To learn more about using the ABAC mode, see [ABAC Mode](/docs/reference/access-authn-authz/abac/).
* **RBAC** - Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. In this context, access is the ability of an individual user to perform a specific task, such as view, create, or modify a file. To learn more about using the RBAC mode, see [RBAC Mode](/docs/reference/access-authn-authz/rbac/)
* When specified RBAC (Role-Based Access Control) uses the `rbac.authorization.k8s.io` API group to drive authorization decisions, allowing admins to dynamically configure permission policies through the Kubernetes API.
* To enable RBAC, start the apiserver with `--authorization-mode=RBAC`.
* **Webhook** - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen. To learn more about using the Webhook mode, see [Webhook Mode](/docs/reference/access-authn-authz/webhook/).
-->
## 鉴权模块 {#authorization-modules}
* **Node** - 一个专用鉴权组件,根据调度到 kubelet 上运行的 Pod 为 kubelet 授予权限。
了解有关使用节点鉴权模式的更多信息,请参阅[节点鉴权](/zh/docs/reference/access-authn-authz/node/)。
* **ABAC** - 基于属性的访问控制(ABAC)定义了一种访问控制范型,通过使用将属性组合
在一起的策略,将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、
对象,环境属性等)。要了解有关使用 ABAC 模式的更多信息,请参阅
[ABAC 模式](/zh/docs/reference/access-authn-authz/abac/)。
* **RBAC** - 基于角色的访问控制(RBAC)是一种基于企业内个人用户的角色来管理对
计算机或网络资源的访问的方法。在此上下文中,权限是单个用户执行特定任务的能力,
例如查看、创建或修改文件。要了解有关使用 RBAC 模式的更多信息,请参阅
[RBAC 模式](/zh/docs/reference/access-authn-authz/rbac/)。
* 被启用之后,RBAC(基于角色的访问控制)使用 `rbac.authorization.k8s.io` API 组来
驱动鉴权决策,从而允许管理员通过 Kubernetes API 动态配置权限策略。
* 要启用 RBAC,请使用 `--authorization-mode = RBAC` 启动 API 服务器。
* **Webhook** - WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST;
通过 HTTP POST 进行简单的事件通知。实现 WebHook 的 Web 应用程序会在发生某些事情时
将消息发布到 URL。要了解有关使用 Webhook 模式的更多信息,请参阅
[Webhook 模式](/zh/docs/reference/access-authn-authz/webhook/)。
<!--
#### Checking API Access
`kubectl` provides the `auth can-i` subcommand for quickly querying the API authorization layer.
The command uses the `SelfSubjectAccessReview` API to determine if the current user can perform
a given action, and works regardless of the authorization mode used.
-->
#### 检查 API 访问 {#checking-api-access}
`kubectl` 提供 `auth can-i` 子命令,用于快速查询 API 鉴权。
该命令使用 `SelfSubjectAccessReview` API 来确定当前用户是否可以执行给定操作,
无论使用何种鉴权模式该命令都可以工作。
```shell
kubectl auth can-i create deployments --namespace dev
```
<!-- The output is similar to this: -->
输出类似于:
```
yes
```
```shell
kubectl auth can-i create deployments --namespace prod
```
<!-- The output is similar to this: -->
输出类似于:
```
no
```
<!--
Administrators can combine this with [user impersonation](/docs/reference/access-authn-authz/authentication/#user-impersonation)
to determine what action other users can perform.
-->
管理员可以将此与
[用户扮演](/zh/docs/reference/access-authn-authz/authentication/#user-impersonation)
结合使用,以确定其他用户可以执行的操作。
```bash
kubectl auth can-i list secrets --namespace dev --as dave
```
<!-- The output is similar to this: -->
输出类似于:
```
no
```
<!--
Similarly, to check whether a ServiceAccount named `dev-sa` in Namespace `dev`
can list Pods in the Namespace `target`:
-->
类似地,检查名字空间 `dev` 里的 `dev-sa` 服务账号是否可以列举名字空间 `target` 里的 Pod
```bash
kubectl auth can-i list pods \
--namespace target \
--as system:serviceaccount:dev:dev-sa
```
<!-- The output is similar to this: -->
输出类似于:
```
yes
```
<!--
`SelfSubjectAccessReview` is part of the `authorization.k8s.io` API group, which
exposes the API server authorization to external services. Other resources in
this group include:
* `SubjectAccessReview` - Access review for any user, not only the current one. Useful for delegating authorization decisions to the API server. For example, the kubelet and extension API servers use this to determine user access to their own APIs.
* `LocalSubjectAccessReview` - Like `SubjectAccessReview` but restricted to a specific namespace.
* `SelfSubjectRulesReview` - A review which returns the set of actions a user can perform within a namespace. Useful for users to quickly summarize their own access, or for UIs to hide/show actions.
These APIs can be queried by creating normal Kubernetes resources, where the response "status"
field of the returned object is the result of the query.
-->
`SelfSubjectAccessReview``authorization.k8s.io` API 组的一部分,它将 API
服务器鉴权公开给外部服务。该组中的其他资源包括:
* `SubjectAccessReview` - 对任意用户的访问进行评估,而不仅仅是当前用户。
当鉴权决策被委派给 API 服务器时很有用。例如,kubelet 和扩展 API 服务器使用
它来确定用户对自己的 API 的访问权限。
* `LocalSubjectAccessReview` - 与 `SubjectAccessReview` 类似,但仅限于特定的
名字空间。
* `SelfSubjectRulesReview` - 返回用户可在名字空间内执行的操作集的审阅。
用户可以快速汇总自己的访问权限,或者用于 UI 中的隐藏/显示动作。
可以通过创建普通的 Kubernetes 资源来查询这些 API,其中返回对象的响应 "status"
字段是查询的结果。
```bash
kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
resourceAttributes:
group: apps
name: deployments
verb: create
namespace: dev
EOF
```
<!--
The generated `SelfSubjectAccessReview` is:
-->
生成的 `SelfSubjectAccessReview` 为:
```yaml
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
creationTimestamp: null
spec:
resourceAttributes:
group: apps
name: deployments
namespace: dev
verb: create
status:
allowed: true
denied: false
```
<!--
## Using Flags for Your Authorization Module
You must include a flag in your policy to indicate which authorization module
your policies include:
The following flags can be used:
-->
## 为你的鉴权模块设置参数
你必须在策略中包含一个参数标志,以指明你的策略包含哪个鉴权模块:
可以使用的参数有:
<!--
* `--authorization-mode=ABAC` Attribute-Based Access Control (ABAC) mode allows you to configure policies using local files.
* `--authorization-mode=RBAC` Role-based access control (RBAC) mode allows you to create and store policies using the Kubernetes API.
* `--authorization-mode=Webhook` WebHook is an HTTP callback mode that allows you to manage authorization using a remote REST endpoint.
* `--authorization-mode=Node` Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.
* `--authorization-mode=AlwaysDeny` This flag blocks all requests. Use this flag only for testing.
* `--authorization-mode=AlwaysAllow` This flag allows all requests. Use this flag only if you do not require authorization for your API requests.
-->
* `--authorization-mode=ABAC` 基于属性的访问控制(ABAC)模式允许你
使用本地文件配置策略。
* `--authorization-mode=RBAC` 基于角色的访问控制(RBAC)模式允许你使用
Kubernetes API 创建和存储策略。
* `--authorization-mode=Webhook` WebHook 是一种 HTTP 回调模式,允许你使用远程
REST 端点管理鉴权。
* `--authorization-mode=Node` 节点鉴权是一种特殊用途的鉴权模式,专门对
kubelet 发出的 API 请求执行鉴权。
* `--authorization-mode=AlwaysDeny` 该标志阻止所有请求。仅将此标志用于测试。
* `--authorization-mode=AlwaysAllow` 此标志允许所有请求。仅在你不需要 API 请求
的鉴权时才使用此标志。
<!--
You can choose more than one authorization module. Modules are checked in order
so an earlier module has higher priority to allow or deny a request.
-->
你可以选择多个鉴权模块。模块按顺序检查,以便较靠前的模块具有更高的优先级来允许
或拒绝请求。
<!--
## Privilege escalation via workload creation or edits {#privilege-escalation-via-pod-creation}
Users who can create/edit pods in a namespace, either directly or through a [controller](/docs/concepts/architecture/controller/)
such as an operator, could escalate their privileges in that namespace.
-->
## 通过创建或编辑工作负载提升权限 {#privilege-escalation-via-pod-creation}
能够在名字空间中创建或者编辑 Pod 的用户,
无论是直接操作还是通过[控制器](/zh/docs/concepts/architecture/controller/)(例如,一个 Operator)来操作,
都可以提升他们在该名字空间内的权限。
{{< caution >}}
<!--
System administrators, use care when granting access to create or edit workloads.
Details of how these can be misused are documented in [escalation paths](/docs/reference/access-authn-authz/authorization/#escalation-paths)
-->
系统管理员在授予对工作负载的创建或编辑的权限时要小心。
关于这些权限如何被误用的详细信息请参阅
[提升途径](#escalation-paths)
{{< /caution >}}
<!--
### Escalation paths {#escalation-paths}
- Mounting arbitrary secrets in that namespace
- Can be used to access secrets meant for other workloads
- Can be used to obtain a more privileged service account's service account token
- Using arbitrary Service Accounts in that namespace
- Can perform Kubernetes API actions as another workload (impersonation)
- Can perform any privileged actions that Service Account has
- Mounting configmaps meant for other workloads in that namespace
- Can be used to obtain information meant for other workloads, such as DB host names.
- Mounting volumes meant for other workloads in that namespace
- Can be used to obtain information meant for other workloads, and change it.
-->
### 提升途径 {#escalation-paths}
- 挂载该名字空间内的任意 Secret
- 可以用来访问其他工作负载专用的 Secret
- 可以用来获取权限更高的服务账号的令牌
- 使用该名字空间内的任意服务账号
- 可以用另一个工作负载的身份来访问 Kubernetes API(伪装)
- 可以执行该服务账号的任意特权操作
- 挂载该名字空间里其他工作负载专用的 ConfigMap
- 可以用来获取其他工作负载专用的信息,例如数据库主机名。
- 挂载该名字空间里其他工作负载的卷
- 可以用来获取其他工作负载专用的信息,并且更改它。
{{< caution >}}
<!--
System administrators should be cautious when deploying CRDs that
change the above areas. These may open privilege escalations paths.
This should be considered when deciding on your RBAC controls.
-->
系统管理员在部署改变以上部分的 CRD 的时候要小心。
它们可能会打开权限提升的途径。
在决定你的 RBAC 控制时应该考虑这方面的问题。
{{< /caution >}}
## {{% heading "whatsnext" %}}
<!--
* To learn more about Authentication, see **Authentication** in [Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/).
* To learn more about Admission Control, see [Using Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/).
-->
* 要了解有关身份验证的更多信息,请参阅
[控制对 Kubernetes API 的访问](/zh/docs/concepts/security/controlling-access/)
中的 **身份验证** 部分。
* 要了解有关准入控制的更多信息,请参阅
[使用准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/)。
@@ -0,0 +1,308 @@
---
title: 使用启动引导令牌(Bootstrap Tokens)认证
weight: 20
---
<!--
reviewers:
- jbeda
title: Authenticating with Bootstrap Tokens
content_type: concept
weight: 20
-->
<!-- overview -->
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
<!--
Bootstrap tokens are a simple bearer token that is meant to be used when
creating new clusters or joining new nodes to an existing cluster. It was built
to support [kubeadm](/docs/reference/setup-tools/kubeadm/), but can be used in other contexts
for users that wish to start clusters without `kubeadm`. It is also built to
work, via RBAC policy, with the
[Kubelet TLS Bootstrapping](/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/) system.
-->
启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群
或者在现有集群中添加新节点时使用的。
它被设计成能够支持 [`kubeadm`](/zh/docs/reference/setup-tools/kubeadm/)
但是也可以被用在其他的案例中以便用户在不使用 `kubeadm` 的情况下启动集群。
它也被设计成可以通过 RBAC 策略,结合
[Kubelet TLS 启动引导](/zh/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/)
系统进行工作。
<!-- body -->
<!--
## Bootstrap Tokens Overview
Bootstrap Tokens are defined with a specific type
(`bootstrap.kubernetes.io/token`) of secrets that lives in the `kube-system`
namespace. These Secrets are then read by the Bootstrap Authenticator in the
API Server. Expired tokens are removed with the TokenCleaner controller in the
Controller Manager. The tokens are also used to create a signature for a
specific ConfigMap used in a "discovery" process through a BootstrapSigner
controller.
-->
启动引导令牌被定义成一个特定类型的 Secret(`bootstrap.kubernetes.io/token`),
并存在于 `kube-system` 名字空间中。
这些 Secret 会被 API 服务器上的启动引导认证组件(Bootstrap Authenticator)读取。
控制器管理器中的控制器 TokenCleaner 能够删除过期的令牌。
这些令牌也被用来在节点发现的过程中会使用的一个特殊的 ConfigMap 对象。
BootstrapSigner 控制器也会使用这一 ConfigMap。
<!--
## Token Format
Bootstrap Tokens take the form of `abcdef.0123456789abcdef`. More formally,
they must match the regular expression `[a-z0-9]{6}\.[a-z0-9]{16}`.
The first part of the token is the "Token ID" and is considered public
information. It is used when referring to a token without leaking the secret
part used for authentication. The second part is the "Token Secret" and should
only be shared with trusted parties.
-->
## 令牌格式
启动引导令牌使用 `abcdef.0123456789abcdef` 的形式。
更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`
令牌的第一部分是 “Token ID”,它是一种公开信息,用于引用令牌并确保不会
泄露认证所使用的秘密信息。
第二部分是“令牌秘密(Token Secret)”,它应该被共享给受信的第三方。
## 启用启动引导令牌
<!--
## Enabling Bootstrap Token Authentication
The Bootstrap Token authenticator can be enabled using the following flag on the
API server:
-->
## 启用启动引导令牌身份认证 {#enabling-bootstrap-token-authentication}
启动引导令牌认证组件可以通过 API 服务器上的如下标志启用:
```
--enable-bootstrap-token-auth
```
<!--
When enabled, bootstrapping tokens can be used as bearer token credentials to
authenticate requests against the API server.
-->
启动引导令牌被启用后,可以作为持有者令牌的凭据,用于 API 服务器请求的身份认证。
```http
Authorization: Bearer 07401b.f395accd246ae52d
```
<!--
Tokens authenticate as the username `system:bootstrap:<token id>` and are members
of the group `system:bootstrappers`. Additional groups may be specified in the
token's Secret.
Expired tokens can be deleted automatically by enabling the `tokencleaner`
controller on the controller manager.
-->
令牌认证为用户名 `system:bootstrap:<token id>` 并且是组 `system:bootstrappers`
的成员。额外的组信息可以通过令牌的 Secret 来设置。
过期的令牌可以通过启用控制器管理器中的 `tokencleaner` 控制器来删除。
```
--controllers=*,tokencleaner
```
<!--
## Bootstrap Token Secret Format
Each valid token is backed by a secret in the `kube-system` namespace. You can
find the full design doc
[here](https://github.com/kubernetes/design-proposals-archive/blob/main/cluster-lifecycle/bootstrap-discovery.md).
Here is what the secret looks like.
-->
## 启动引导令牌的 Secret 格式 {#bootstrap-token-secret-format}
每个合法的令牌背后对应着 `kube-system` 名字空间中的某个 Secret 对象。
你可以从
[这里](https://github.com/kubernetes/design-proposals-archive/blob/main/cluster-lifecycle/bootstrap-discovery.md)
找到完整设计文档。
这是 Secret 看起来的样子。
```yaml
apiVersion: v1
kind: Secret
metadata:
# name 必须是 "bootstrap-token-<token id>" 格式的
name: bootstrap-token-07401b
namespace: kube-system
# type 必须是 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
# 供人阅读的描述,可选。
description: "The default bootstrap token generated by 'kubeadm init'."
# 令牌 ID 和秘密信息,必需。
token-id: 07401b
token-secret: f395accd246ae52d
# 可选的过期时间字段
expiration: 2017-03-10T03:22:11Z
# 允许的用法
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
# 令牌要认证为的额外组,必须以 "system:bootstrappers:" 开头
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
```
<!--
The type of the secret must be `bootstrap.kubernetes.io/token` and the name must
be `bootstrap-token-<token id>`. It must also exist in the `kube-system`
namespace.
The `usage-bootstrap-*` members indicate what this secret is intended to be used
for. A value must be set to `true` to be enabled.
-->
Secret 的类型必须是 `bootstrap.kubernetes.io/token`,而且名字必须是 `bootstrap-token-<token id>`
令牌必须存在于 `kube-system` 名字空间中。
`usage-bootstrap-*` 成员表明这个 Secret 的用途。启用时,值必须设置为 `true`
<!--
* `usage-bootstrap-authentication` indicates that the token can be used to
authenticate to the API server as a bearer token.
* `usage-bootstrap-signing` indicates that the token may be used to sign the
`cluster-info` ConfigMap as described below.
-->
* `usage-bootstrap-authentication` 表示令牌可以作为持有者令牌用于 API 服务器的身份认证。
* `usage-bootstrap-signing` 表示令牌可被用于 `cluster-info` ConfigMap 的签名,
就像下面描述的那样。
<!--
The `expiration` field controls the expiry of the token. Expired tokens are
rejected when used for authentication and ignored during ConfigMap signing.
The expiry value is encoded as an absolute UTC time using RFC3339. Enable the
`tokencleaner` controller to automatically delete expired tokens.
-->
`expiration` 字段控制令牌的失效期。过期的令牌在用于身份认证时会被拒绝,在用于
ConfigMap 签名时会被忽略。
过期时间值是遵循 RFC3339 进行编码的 UTC 时间。
启用 TokenCleaner 控制器会自动删除过期的令牌。
<!--
## Token Management with kubeadm
You can use the `kubeadm` tool to manage tokens on a running cluster. See the
[kubeadm token docs](/docs/reference/setup-tools/kubeadm/kubeadm-token/) for details.
-->
## 使用 `kubeadm` 管理令牌 {#token-management-with-kubeadm}
你可以使用 `kubeadm` 工具管理运行中集群上的令牌。
参见 [kubeadm token 文档](/zh/docs/reference/setup-tools/kubeadm/kubeadm-token/)
以了解详细信息。
<!--
## ConfigMap Signing
In addition to authentication, the tokens can be used to sign a ConfigMap. This
is used early in a cluster bootstrap process before the client trusts the API
server. The signed ConfigMap can be authenticated by the shared token.
Enable ConfigMap signing by enabling the `bootstrapsigner` controller on the
Controller Manager.
-->
### ConfigMap 签名 {#configmap-signing}
除了身份认证,令牌还可以用于签名 ConfigMap。
这一用法发生在集群启动过程的早期,在客户端信任 API 服务器之前。
被签名的 ConfigMap 可以被共享令牌完成身份认证。
通过在控制器管理器上启用 `bootstrapsigner` 控制器可以启用 ConfigMap 签名特性。
```
--controllers=*,bootstrapsigner
```
<!--
The ConfigMap that is signed is `cluster-info` in the `kube-public` namespace.
The typical flow is that a client reads this ConfigMap while unauthenticated and
ignoring TLS errors. It then validates the payload of the ConfigMap by looking
at a signature embedded in the ConfigMap.
The ConfigMap may look like this:
-->
被签名的 ConfigMap 是 `kube-public` 名字空间中的 `cluster-info`
典型的工作流中,客户端在未经认证和忽略 TLS 报错的状态下读取这个 ConfigMap。
通过检查 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。
ConfigMap 会是这个样子的:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-info
namespace: kube-public
data:
jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
kubeconfig: |
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <非常长的证书数据>
server: https://10.138.0.2:6443
name: ""
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []
```
<!--
The `kubeconfig` member of the ConfigMap is a config file with only the cluster
information filled out. The key thing being communicated here is the
`certificate-authority-data`. This may be expanded in the future.
-->
ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件。
这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。
<!--
The signature is a JWS signature using the "detached" mode. To validate the
signature, the user should encode the `kubeconfig` payload according to JWS
rules (base64 encoded while discarding any trailing `=`). That encoded payload
is then used to form a whole JWS by inserting it between the 2 dots. You can
verify the JWS using the `HS256` scheme (HMAC-SHA256) with the full token (e.g.
`07401b.f395accd246ae52d`) as the shared secret. Users _must_ verify that HS256
is used.
-->
签名是一个使用 “detached” 模式生成的 JWS 签名。
为了检验签名,用户应该按照 JWS 规则(base64 编码且丢掉结尾的 `=`)对
`kubeconfig` 的载荷进行编码。完成编码的载荷会被插入到两个句点中间,形成完整的
JWS。你可以使用完整的令牌(比如 `07401b.f395accd246ae52d`)作为共享密钥,
通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。
用户 _必须_ 确保使用了 HS256。
{{< warning >}}
<!--
Any party with a bootstrapping token can create a valid signature for that
token. When using ConfigMap signing it's discouraged to share the same token with
many clients, since a compromised client can potentially man-in-the middle another
client relying on the signature to bootstrap TLS trust.
-->
任何拥有了启动引导令牌的主体都可以为该令牌生成一个合法的签名。
当使用 ConfigMap 签名时,非常不建议针对很多客户使用相同的令牌,因为某个被攻击的
客户可能对另一个一来签名来开启 TLS 信任的客户发起中间人攻击。
{{< /warning >}}
<!--
Consult the [kubeadm implementation details](/docs/reference/setup-tools/kubeadm/implementation-details/)
section for more information.
-->
参考 [kubeadm 实现细节](/zh/docs/reference/setup-tools/kubeadm/implementation-details/)
了解更多信息。
@@ -0,0 +1,848 @@
---
title: 证书签名请求
content_type: concept
weight: 20
---
<!--
reviewers:
- liggitt
- mikedanese
- munnerz
- enj
title: Certificate Signing Requests
content_type: concept
weight: 20
-->
<!-- overview -->
{{< feature-state for_k8s_version="v1.19" state="stable" >}}
<!--
The Certificates API enables automation of
[X.509](https://www.itu.int/rec/T-REC-X.509) credential provisioning by providing
a programmatic interface for clients of the Kubernetes API to request and obtain
X.509 {{< glossary_tooltip term_id="certificate" text="certificates" >}}
from a Certificate Authority (CA).
A CertificateSigningRequest (CSR) resource is used to request that a certificate be signed
by a denoted signer, after which the request may be approved or denied before
finally being signed.
-->
证书 API 支持
[X.509](https://www.itu.int/rec/T-REC-X.509)
的自动化配置,
它为 Kubernetes API 的客户端提供一个编程接口,
用于从证书颁发机构(CA)请求并获取 X.509
{{< glossary_tooltip term_id="certificate" text="证书" >}}。
CertificateSigningRequestCSR)资源用来向指定的签名者申请证书签名,
在最终签名之前,申请可能被批准,也可能被拒绝。
<!-- body -->
<!--
## Request signing process
The CertificateSigningRequest resource type allows a client to ask for an X.509 certificate
be issued, based on a signing request.
The CertificateSigningRequest object includes a PEM-encoded PKCS#10 signing request in
the `spec.request` field. The CertificateSigningRequest denotes the _signer_ (the
recipient that the request is being made to) using the `spec.signerName` field.
Note that `spec.signerName` is a required key after api version `certificates.k8s.io/v1`.
In Kubernetes v1.22 and later, clients may optionally set the `spec.expirationSeconds`
field to request a particular lifetime for the issued certificate. The minimum valid
value for this field is `600`, i.e. ten minutes.
-->
## 请求签名流程 {#request-signing-process}
CertificateSigningRequest 资源类型允许客户使用它申请发放 X.509 证书。
CertificateSigningRequest 对象 在 `spec.request` 中包含一个 PEM 编码的 PKCS#10 签名请求。
CertificateSigningRequest 使用 `spec.signerName` 字段标示 _签名者_(请求的接收方)。
注意,`spec.signerName``certificates.k8s.io/v1` 之后的 API 版本是必填项。
在 Kubernetes v1.22 和以后的版本,客户可以可选地设置 `spec.expirationSeconds`
字段来为颁发的证书设定一个特定的有效期。该字段的最小有效值是 `600`,也就是 10 分钟。
<!--
Once created, a CertificateSigningRequest must be approved before it can be signed.
Depending on the signer selected, a CertificateSigningRequest may be automatically approved
by a {{< glossary_tooltip text="controller" term_id="controller" >}}.
Otherwise, a CertificateSigningRequest must be manually approved
either via the REST API (or client-go)
or by running `kubectl certificate approve`.
Likewise, a CertificateSigningRequest may also be denied,
which tells the configured signer that it must not sign the request.
-->
创建完成的 CertificateSigningRequest,要先通过批准,然后才能签名。
根据所选的签名者,CertificateSigningRequest 可能会被
{{< glossary_tooltip text="控制器" term_id="controller" >}}自动批准。
否则,就必须人工批准,
人工批准可以使用 REST API(或 go 客户端),也可以执行 `kubectl certificate approve` 命令。
同样,CertificateSigningRequest 也可能被驳回,
这就相当于通知了指定的签名者,这个证书不能签名。
<!--
For certificates that have been approved, the next step is signing.
The relevant signing controller
first validates that the signing conditions are met and then creates a certificate.
The signing controller then updates the CertificateSigningRequest,
storing the new certificate into
the `status.certificate` field of the existing CertificateSigningRequest object. The
`status.certificate` field is either empty or contains a X.509 certificate,
encoded in PEM format.
The CertificateSigningRequest `status.certificate` field is empty until the signer does this.
-->
对于已批准的证书,下一步是签名。
对应的签名控制器首先验证签名条件是否满足,然后才创建证书。
签名控制器然后更新 CertificateSigningRequest
将新证书保存到现有 CertificateSigningRequest 对象的 `status.certificate` 字段中。
此时,字段 `status.certificate` 要么为空,要么包含一个用 PEM 编码的 X.509 证书。
直到签名完成前,CertificateSigningRequest 的字段 `status.certificate` 都为空。
<!--
Once the `status.certificate` field has been populated,
the request has been completed and clients can now
fetch the signed certificate PEM data from the CertificateSigningRequest resource.
The signers can instead deny certificate signing if the approval conditions are not met.
-->
一旦 `status.certificate` 字段完成填充,请求既算完成,
客户端现在可以从 CertificateSigningRequest 资源中获取已签名的证书的 PEM 数据。
当然如果不满足签名条件,签名者可以拒签。
<!--
In order to reduce the number of old CertificateSigningRequest resources left
in a cluster, a garbage collection
controller runs periodically.
The garbage collection removes CertificateSigningRequests that have not changed
state for some duration:
* Approved requests: automatically deleted after 1 hour
* Denied requests: automatically deleted after 1 hour
* Failed requests: automatically deleted after 1 hour
* Pending requests: automatically deleted after 24 hours
* All requests: automatically deleted after the issued certificate has expired
-->
为了减少集群中遗留的过时的 CertificateSigningRequest 资源的数量,
一个垃圾收集控制器将会周期性地运行。
此垃圾收集器会清除在一段时间内没有改变过状态的 CertificateSigningRequests
* 已批准的请求:1小时后自动删除
* 已拒绝的请求:1小时后自动删除
* 已失败的请求:1小时后自动删除
* 挂起的请求:24小时后自动删除
* 所有请求:在颁发的证书过期后自动删除
<!--
## Signers
Custom signerNames can also be specified. All signers should provide information about how they work
so that clients can predict what will happen to their CSRs.
This includes:
-->
## 签名者 {#signers}
也可以指定自定义 signerName。
所有签名者都应该提供自己工作方式的信息,
以便客户端可以预期到他们的 CSR 将发生什么。
此类信息包括:
<!--
1. **Trust distribution**: how trust (CA bundles) are distributed.
2. **Permitted subjects**: any restrictions on and behavior
when a disallowed subject is requested.
3. **Permitted x509 extensions**: including IP subjectAltNames, DNS subjectAltNames,
Email subjectAltNames, URI subjectAltNames etc,
and behavior when a disallowed extension is requested.
4. **Permitted key usages / extended key usages**: any restrictions on and behavior
when usages different than the signer-determined usages are specified in the CSR.
5. **Expiration/certificate lifetime**: whether it is fixed by the signer, configurable by the admin, determined by the CSR `spec.expirationSeconds` field, etc
and the behavior when the signer-determined expiration is different from the CSR `spec.expirationSeconds` field.
6. **CA bit allowed/disallowed**: and behavior if a CSR contains a request
a for a CA certificate when the signer does not permit it.
-->
1. **信任分发**:信任(CA 证书包)是如何分发的。
2. **许可的主体**:当一个受限制的主体(subject)发送请求时,相应的限制和应对手段。
3. **许可的 x509 扩展**:包括 IP subjectAltNames、DNS subjectAltNames、
Email subjectAltNames、URI subjectAltNames 等,请求一个受限制的扩展项时的应对手段。
4. **许可的密钥用途/扩展的密钥用途**:当用途和签名者在 CSR 中指定的用途不同时,
相应的限制和应对手段。
5. **过期时间/证书有效期**:过期时间由签名者确定、由管理员配置、还是由 CSR `spec.expirationSeconds` 字段指定等,
以及签名者决定的过期时间与 CSR `spec.expirationSeconds` 字段不同时的应对手段。
6. **允许/不允许 CA 位**:当 CSR 包含一个签名者并不允许的 CA 证书的请求时,相应的应对手段。
<!--
Commonly, the `status.certificate` field contains a single PEM-encoded X.509
certificate once the CSR is approved and the certificate is issued. Some
signers store multiple certificates into the `status.certificate` field. In
that case, the documentation for the signer should specify the meaning of
additional certificates; for example, this might be the certificate plus
intermediates to be presented during TLS handshakes.
-->
一般来说,当 CSR 被批准通过,且证书被签名后,`status.certificate` 字段
将包含一个 PEM 编码的 X.509 证书。
有些签名者在 `status.certificate` 字段中存储多个证书。
在这种情况下,签名者的说明文档应当指明附加证书的含义。
例如,这是要在 TLS 握手时提供的证书和中继证书。
<!--
The PKCS#10 signing request format does not have a standard mechanism to specify a
certificate expiration or lifetime. The expiration or lifetime therefore has to be set
through the `spec.expirationSeconds` field of the CSR object. The built-in signers
use the `ClusterSigningDuration` configuration option, which defaults to 1 year,
(the `--cluster-signing-duration` command-line flag of the kube-controller-manager)
as the default when no `spec.expirationSeconds` is specified. When `spec.expirationSeconds`
is specified, the minimum of `spec.expirationSeconds` and `ClusterSigningDuration` is
used.
-->
PKCS#10 签名请求格式并没有一种标准的方法去设置证书的过期时间或者生命期。
因此,证书的过期时间或者生命期必须通过 CSR 对象的 `spec.expirationSeconds` 字段来设置。
`spec.expirationSeconds` 没有被指定时,内置的签名者默认使用 `ClusterSigningDuration` 配置选项
kube-controller-manager 的命令行选项 `--cluster-signing-duration`),该选项的默认值设为 1 年。
`spec.expirationSeconds` 被指定时,`spec.expirationSeconds``ClusterSigningDuration`
中的最小值会被使用。
{{< note >}}
<!--
The `spec.expirationSeconds` field was added in Kubernetes v1.22. Earlier versions of Kubernetes do not honor this field.
Kubernetes API servers prior to v1.22 will silently drop this field when the object is created.
-->
`spec.expirationSeconds` 字段是在 Kubernetes v1.22 中加入的。早期的 Kubernetes 版本并不认识该字段。
v1.22 版本之前的 Kubernetes API 服务器会在创建对象的时候忽略该字段。
{{< /note >}}
<!--
### Kubernetes signers
Kubernetes provides built-in signers that each have a well-known `signerName`:
-->
### Kubernetes 签名者 {#kubernetes-signers}
Kubernetes提供了内置的签名者,每个签名者都有一个众所周知的 `signerName`:
<!--
1. `kubernetes.io/kube-apiserver-client`: signs certificates that will be honored as client certificates by the API server.
Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}.
1. Trust distribution: signed certificates must be honored as client-certificates by the kube-apiserver. The CA bundle is not distributed by any other means.
1. Permitted subjects - no subject restrictions, but approvers and signers may choose not to approve or sign.
Certain subjects like cluster-admin level users or groups vary between distributions and installations,
but deserve additional scrutiny before approval and signing.
The `CertificateSubjectRestriction` admission plugin is enabled by default to restrict `system:masters`,
but it is often not the only cluster-admin subject in a cluster.
1. Permitted x509 extensions - honors subjectAltName and key usage extensions and discards other extensions.
1. Permitted key usages - must include `["client auth"]`. Must not include key usages beyond `["digital signature", "key encipherment", "client auth"]`.
1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum
of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object.
1. CA bit allowed/disallowed - not allowed.
-->
1. `kubernetes.io/kube-apiserver-client`:签名的证书将被 API 服务器视为客户证书。
{{< glossary_tooltip term_id="kube-controller-manager" >}} 不会自动批准它。
1. 信任分发:签名的证书将被 API 服务器视为客户端证书。CA 证书包不通过任何其他方式分发。
1. 许可的主体:没有主体限制,但审核人和签名者可以选择不批准或不签署。
某些主体,比如集群管理员级别的用户或组因部署和安装方式不同而不同,
所以批准和签署之前需要进行额外仔细审查。
用来限制 `system:masters` 的 CertificateSubjectRestriction 准入插件默认处于启用状态,
但它通常不是集群中唯一的集群管理员主体。
1. 许可的 x509 扩展:允许 subjectAltName 和 key usage 扩展,弃用其他扩展。
1. 许可的密钥用途:必须包含 `["client auth"]`,但不能包含
`["digital signature", "key encipherment", "client auth"]` 之外的键。
1. 过期时间/证书有效期:对于 kube-controller-manager 实现的签名者,
设置为 `--cluster-signing-duration` 选项和 CSR 对象的 `spec.expirationSeconds` 字段(如有设置该字段)中的最小值。
1. 允许/不允许 CA 位:不允许。
<!--
1. `kubernetes.io/kube-apiserver-client-kubelet`: signs client certificates that will be honored as client certificates by the
API server.
May be auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}.
1. Trust distribution: signed certificates must be honored as client certificates by the API server. The CA bundle
is not distributed by any other means.
1. Permitted subjects - organizations are exactly `["system:nodes"]`, common name starts with "`system:node:`".
1. Permitted x509 extensions - honors key usage extensions, forbids subjectAltName extensions and drops other extensions.
1. Permitted key usages - exactly `["key encipherment", "digital signature", "client auth"]`.
1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum
of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object.
1. CA bit allowed/disallowed - not allowed.
-->
2. `kubernetes.io/kube-apiserver-client-kubelet`: 签名的证书将被 kube-apiserver 视为客户证书。
{{< glossary_tooltip term_id="kube-controller-manager" >}} 可以自动批准它。
1. 信任分发:签名的证书将被 API 服务器视为客户端证书。CA 证书包不通过任何其他方式分发。
1. 许可的主体:组织名必须是 `["system:nodes"]`,用户名以 "`system:node:`" 开头
1. 许可的 x509 扩展:允许 key usage 扩展,禁用 subjectAltName 扩展,并删除其他扩展。
1. 许可的密钥用途:必须是 `["key encipherment", "digital signature", "client auth"]`
1. 过期时间/证书有效期:对于 kube-controller-manager 实现的签名者,
设置为 `--cluster-signing-duration` 选项和 CSR 对象的 `spec.expirationSeconds` 字段(如有设置该字段)中的最小值。
1. 允许/不允许 CA 位:不允许。
<!--
1. `kubernetes.io/kubelet-serving`: signs serving certificates that are honored as a valid kubelet serving certificate
by the API server, but has no other guarantees.
Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}.
1. Trust distribution: signed certificates must be honored by the kube-apiserver as valid to terminate connections to a kubelet. The CA bundle is not distributed by any other means.
1. Permitted subjects - organizations are exactly `["system:nodes"]`, common name starts with "`system:node:`".
1. Permitted x509 extensions - honors key usage and DNSName/IPAddress subjectAltName extensions, forbids EmailAddress and
URI subjectAltName extensions, drops other extensions. At least one DNS or IP subjectAltName must be present.
1. Permitted key usages - exactly `["key encipherment", "digital signature", "server auth"]`.
1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum
of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object.
1. CA bit allowed/disallowed - not allowed.
-->
3. `kubernetes.io/kubelet-serving`: 签名服务证书,该服务证书被 API 服务器视为有效的 kubelet 服务证书,
但没有其他保证。{{< glossary_tooltip term_id="kube-controller-manager" >}} 不会自动批准它。
1. 信任分发:签名的证书必须被 kube-apiserver 认可,可有效的中止 kubelet 连接。CA 证书包不通过任何其他方式分发。
1. 许可的主体:组织名必须是 `["system:nodes"]`,用户名以 "`system:node:`" 开头
1. 许可的 x509 扩展:允许 key usage、DNSName/IPAddress subjectAltName 等扩展,
禁止 EmailAddress、URI subjectAltName 等扩展,并丢弃其他扩展。
至少有一个 DNS 或 IP 的 SubjectAltName 存在。
1. 许可的密钥用途:必须是 `["key encipherment", "digital signature", "server auth"]`
1. 过期时间/证书有效期:对于 kube-controller-manager 实现的签名者,
设置为 `--cluster-signing-duration` 选项和 CSR 对象的 `spec.expirationSeconds` 字段(如有设置该字段)中的最小值。
1. 允许/不允许 CA 位:不允许。
<!--
1. `kubernetes.io/legacy-unknown`: has no guarantees for trust at all. Some third-party distributions of Kubernetes
may honor client certificates signed by it. The stable CertificateSigningRequest API (version `certificates.k8s.io/v1` and later)
does not allow to set the `signerName` as `kubernetes.io/legacy-unknown`.
Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}.
1. Trust distribution: None. There is no standard trust or distribution for this signer in a Kubernetes cluster.
1. Permitted subjects - any
1. Permitted x509 extensions - honors subjectAltName and key usage extensions and discards other extensions.
1. Permitted key usages - any
1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum
of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object.
1. CA bit allowed/disallowed - not allowed.
-->
4. `kubernetes.io/legacy-unknown`: 不保证信任。Kubernetes 的一些第三方发行版可能会使用它签署的客户端证书。
稳定版的 CertificateSigningRequest API`certificates.k8s.io/v1` 以及之后的版本)不允许将
`signerName` 设置为 `kubernetes.io/legacy-unknown`
{{< glossary_tooltip term_id="kube-controller-manager" >}} 不会自动批准这类请求。
1. 信任分发:没有。这个签名者在 Kubernetes 集群中没有标准的信任或分发。
1. 许可的主体:全部。
1. 许可的 x509 扩展:允许 subjectAltName 和 key usage 等扩展,并弃用其他扩展。
1. 许可的密钥用途:全部。
1. 过期时间/证书有效期:对于 kube-controller-manager 实现的签名者,
设置为 `--cluster-signing-duration` 选项和 CSR 对象的 `spec.expirationSeconds` 字段(如有设置该字段)中的最小值。
1. 允许/不允许 CA 位 - 不允许。
{{< note >}}
<!--
Failures for all of these are only reported in kube-controller-manager logs.
-->
注意:所有这些故障仅在 kube-controller-manager 日志中报告。
{{< /note >}}
{{< note >}}
<!--
The `spec.expirationSeconds` field was added in Kubernetes v1.22. Earlier versions of Kubernetes do not honor this field.
Kubernetes API servers prior to v1.22 will silently drop this field when the object is created.
-->
`spec.expirationSeconds` 字段是在 Kubernetes v1.22 中加入的。早期的 Kubernetes 版本并不认识该字段。
v1.22 版本之前的 Kubernetes API 服务器会在创建对象的时候忽略该字段。
{{< /note >}}
<!--
Distribution of trust happens out of band for these signers. Any trust outside of those described above are strictly
coincidental. For instance, some distributions may honor `kubernetes.io/legacy-unknown` as client certificates for the
kube-apiserver, but this is not a standard.
None of these usages are related to ServiceAccount token secrets `.data[ca.crt]` in any way. That CA bundle is only
guaranteed to verify a connection to the API server using the default service (`kubernetes.default.svc`).
-->
对于这些签名者,信任的分发发生在带外(out of band)。上述信任之外的任何信任都是完全巧合的。
例如,一些发行版可能会将 `kubernetes.io/legacy-unknown` 作为 kube-apiserver 的客户端证书,
但这个做法并不标准。
这些用途都没有以任何方式涉及到 ServiceAccount 中的 Secrets `.data[ca.crt]`
此 CA 证书包只保证使用默认的服务(`kubernetes.default.svc`)来验证到 API 服务器的连接。
<!--
## Authorization
To allow creating a CertificateSigningRequest and retrieving any CertificateSigningRequest:
* Verbs: `create`, `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests`
For example:
-->
## 鉴权 {#authorization}
授权创建 CertificateSigningRequest 和检索 CertificateSigningRequest:
* verbs(动词): `create``get``list``watch`,
group(组):`certificates.k8s.io`
resources`certificatesigningrequests`
例如:
{{< codenew file="access/certificate-signing-request/clusterrole-create.yaml" >}}
<!--
To allow approving a CertificateSigningRequest:
* Verbs: `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests`
* Verbs: `update`, group: `certificates.k8s.io`, resource: `certificatesigningrequests/approval`
* Verbs: `approve`, group: `certificates.k8s.io`, resource: `signers`, resourceName: `<signerNameDomain>/<signerNamePath>` or `<signerNameDomain>/*`
For example:
-->
授权批准 CertificateSigningRequest
* verbs(动词): `get``list``watch`
group(组):`certificates.k8s.io`
resources(资源):`certificatesigningrequests`
* verbs(动词): `update`
group(组):`certificates.k8s.io`
resources(资源):`certificatesigningrequests/approval`
* verbs(动词):`approve`
group(组):`certificates.k8s.io`
resources(资源):`signers`
resourceName`<signerNameDomain>/<signerNamePath>``<signerNameDomain>/*`
例如:
{{< codenew file="access/certificate-signing-request/clusterrole-approve.yaml" >}}
<!--
To allow signing a CertificateSigningRequest:
* Verbs: `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests`
* Verbs: `update`, group: `certificates.k8s.io`, resource: `certificatesigningrequests/status`
* Verbs: `sign`, group: `certificates.k8s.io`, resource: `signers`, resourceName: `<signerNameDomain>/<signerNamePath>` or `<signerNameDomain>/*`
-->
授权签名 CertificateSigningRequest
* verbs(动词):`get``list``watch`
group(组):`certificates.k8s.io`
resources(资源):`certificatesigningrequests`
* verbs(动词):`update`
group(组):`certificates.k8s.io`
resources(资源):`certificatesigningrequests/status`
* verbs(动词):`sign`
group(组):`certificates.k8s.io`
resources(资源):`signers`
resourceName`<signerNameDomain>/<signerNamePath>``<signerNameDomain>/*`
{{< codenew file="access/certificate-signing-request/clusterrole-sign.yaml" >}}
<!--
## Normal User
A few steps are required in order to get a normal user to be able to
authenticate and invoke an API. First, this user must have a certificate issued
by the Kubernetes cluster, and then present that certificate to the Kubernetes API.
-->
## 普通用户 {#normal-user}
为了让普通用户能够通过认证并调用 API,需要执行几个步骤。
首先,该用户必须拥有 Kubernetes 集群签发的证书,
然后将该证书提供给 Kubernetes API。
<!--
### Create private key
The following scripts show how to generate PKI private key and CSR. It is
important to set CN and O attribute of the CSR. CN is the name of the user and
O is the group that this user will belong to. You can refer to
[RBAC](/docs/reference/access-authn-authz/rbac/) for standard groups.
-->
### 创建私钥 {#create-private-key}
下面的脚本展示了如何生成 PKI 私钥和 CSR。
设置 CSR 的 CN 和 O 属性很重要。CN 是用户名,O 是该用户归属的组。
你可以参考 [RBAC](/zh/docs/reference/access-authn-authz/rbac/) 了解标准组的信息。
```shell
openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr
```
<!--
### Create CertificateSigningRequest
Create a CertificateSigningRequest and submit it to a Kubernetes Cluster via kubectl.
Below is a script to generate the CertificateSigningRequest.
-->
### 创建 CertificateSigningRequest {#create-certificatesigningrequest}
创建一个 CertificateSigningRequest,并通过 kubectl 将其提交到 Kubernetes 集群。
下面是生成 CertificateSigningRequest 的脚本。
```shell
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
EOF
```
<!--
Some points to note:
- `usages` has to be '`client auth`'
- `expirationSeconds` could be made longer (i.e. `864000` for ten days) or shorter (i.e. `3600` for one hour)
- `request` is the base64 encoded value of the CSR file content.
You can get the content using this command: ```cat myuser.csr | base64 | tr -d "\n"```
-->
需要注意的几点:
- `usage` 字段必须是 '`client auth`'
- `expirationSeconds` 可以设置为更长(例如 `864000` 是十天)或者更短(例如 `3600` 是一个小时)
- `request` 字段是 CSR 文件内容的 base64 编码值。
要得到该值,可以执行命令 `cat myuser.csr | base64 | tr -d "\n"`。
<!--
### Approve certificate signing request
Use kubectl to create a CSR and approve it.
Get the list of CSRs:
-->
### 批准证书签名请求 {#approve-certificate-signing-request}
使用 kubectl 创建 CSR 并批准。
获取 CSR 列表:
```shell
kubectl get csr
```
<!--
Approve the CSR:
-->
批准 CSR
```shell
kubectl certificate approve myuser
```
<!--
### Get the certificate
Retrieve the certificate from the CSR.
-->
### 取得证书 {#get-the-certificate}
从 CSR 取得证书:
```shell
kubectl get csr/myuser -o yaml
```
<!--
The Certificate value is in Base64-encoded format under `status.certificate`.
Export the issued certificate from the CertificateSigningRequest.
-->
证书的内容使用 base64 编码,存放在字段 `status.certificate`。
从 CertificateSigningRequest 导出颁发的证书。
```
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
```
<!--
### Create Role and RoleBinding
With the certificate created it is time to define the Role and RoleBinding for
this user to access Kubernetes cluster resources.
This is a sample command to create a Role for this new user:
-->
### 创建角色和角色绑定 {#create-role-and-role-binding}
创建了证书之后,为了让这个用户能访问 Kubernetes 集群资源,现在就要创建
Role 和 RoleBinding 了。
下面是为这个新用户创建 Role 的示例命令:
```shell
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
```
<!--
This is a sample command to create a RoleBinding for this new user:
-->
下面是为这个新用户创建 RoleBinding 的示例命令:
```shell
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
```
<!--
### Add to kubeconfig
The last step is to add this user into the kubeconfig file.
First, we need to add new credentials:
-->
### 添加到 kubeconfig {#add-to-kubeconfig}
最后一步是将这个用户添加到 kubeconfig 文件。
我们假设私钥和证书文件存放在 “/home/vagrant/work/” 目录中。
首先,我们需要添加新的凭据:
```shell
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
```
<!--
Then, you need to add the context:
-->
然后,你需要添加上下文:
```shell
kubectl config set-context myuser --cluster=kubernetes --user=myuser
```
<!--
To test it, change the context to `myuser`:
-->
来测试一下,把上下文切换为 `myuser`
```shell
kubectl config use-context myuser
```
<!--
## Approval or rejection {#approval-rejection}
### Control plane automated approval {#approval-rejection-control-plane}
The kube-controller-manager ships with a built-in approver for certificates with
a signerName of `kubernetes.io/kube-apiserver-client-kubelet` that delegates various
permissions on CSRs for node credentials to authorization.
The kube-controller-manager POSTs SubjectAccessReview resources to the API server
in order to check authorization for certificate approval.
-->
## 批准和驳回 {#approval-rejection}
### 控制平面的自动化批准 {#approval-rejection-control-plane}
kube-controller-manager 内建了一个证书批准者,其 signerName 为
`kubernetes.io/kube-apiserver-client-kubelet`
该批准者将 CSR 上用于节点凭据的各种权限委托给权威认证机构。
kube-controller-manager 将 SubjectAccessReview 资源发送(POST)到 API 服务器,
以便检验批准证书的授权。
<!--
### Approval or rejection using `kubectl` {#approval-rejection-kubectl}
A Kubernetes administrator (with appropriate permissions) can manually approve
(or deny) CertificateSigningRequests by using the `kubectl certificate
approve` and `kubectl certificate deny` commands.
To approve a CSR with kubectl:
-->
### 使用 `kubectl` 批准或驳回 {#approval-rejection-kubectl}
Kubernetes 管理员(拥有足够的权限)可以手工批准(或驳回)CertificateSigningRequests
此操作使用 `kubectl certificate approve` 和 `kubectl certificate deny` 命令实现。
使用 kubectl 批准一个 CSR
```shell
kubectl certificate approve <certificate-signing-request-name>
```
<!--
Likewise, to deny a CSR:
-->
同样地,驳回一个 CSR
```shell
kubectl certificate deny <certificate-signing-request-name>
```
<!--
### Approval or rejection using the Kubernetes API {#approval-rejection-api-client}
Users of the REST API can approve CSRs by submitting an UPDATE request to the `approval`
subresource of the CSR to be approved. For example, you could write an
{{< glossary_tooltip term_id="operator-pattern" text="operator" >}} that watches for a particular
kind of CSR and then sends an UPDATE to approve them.
When you make an approval or rejection request, set either the `Approved` or `Denied`
status condition based on the state you determine:
For `Approved` CSRs:
-->
### 使用 Kubernetes API 批准或驳回 {#approval-rejection-api-client}
REST API 的用户可以通过向待批准的 CSR 的 `approval` 子资源提交更新请求来批准 CSR。
例如,你可以编写一个
{{< glossary_tooltip term_id="operator-pattern" text="operator" >}}
来监视特定类型的 CSR,然后发送一个更新来批准它。
当你发出批准或驳回的指令时,根据你期望的状态来选择设置 `Approved` 或 `Denied`。
批准(`Approved` 的 CSR
```yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
conditions:
- lastUpdateTime: "2020-02-08T11:37:35Z"
lastTransitionTime: "2020-02-08T11:37:35Z"
message: Approved by my custom approver controller
reason: ApprovedByMyPolicy # You can set this to any string
type: Approved
```
<!--
For `Denied` CSRs:
-->
驳回(`Denied`)的 CSR
```yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
conditions:
- lastUpdateTime: "2020-02-08T11:37:35Z"
lastTransitionTime: "2020-02-08T11:37:35Z"
message: Denied by my custom approver controller
reason: DeniedByMyPolicy # You can set this to any string
type: Denied
```
<!--
It's usual to set `status.conditions.reason` to a machine-friendly reason
code using TitleCase; this is a convention but you can set it to anything
you like. If you want to add a note for human consumption, use the
`status.conditions.message` field.
-->
`status.conditions.reason` 字段通常设置为一个首字母大写的对机器友好的原因码;
这是一个命名约定,但你也可以随你的个人喜好设置。
如果你想添加一个供人类使用的注释,那就用 `status.conditions.message` 字段。
<!--
## Signing
### Control plane signer {#signer-control-plane}
The Kubernetes control plane implements each of the
[Kubernetes signers](/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers),
as part of the kube-controller-manager.
Prior to Kubernetes v1.18, the kube-controller-manager would sign any CSRs that
were marked as approved.
-->
## 签名 {#signing}
### 控制平面签名者 {#signer-control-plane}
Kubernetes 控制平面实现了每一个
[Kubernetes 签名者](/zh/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers)
每个签名者的实现都是 kube-controller-manager 的一部分。
{{< note >}}
在Kubernetes v1.18 之前,
kube-controller-manager 签名所有标记为 approved 的 CSR。
{{< /note >}}
{{< note >}}
<!--
The `spec.expirationSeconds` field was added in Kubernetes v1.22. Earlier versions of Kubernetes do not honor this field.
Kubernetes API servers prior to v1.22 will silently drop this field when the object is created.
-->
`spec.expirationSeconds` 字段是在 Kubernetes v1.22 中加入的。早期的 Kubernetes 版本并不认识该字段。
v1.22 版本之前的 Kubernetes API 服务器会在创建对象的时候忽略该字段。
{{< /note >}}
<!--
### API-based signers {#signer-api}
Users of the REST API can sign CSRs by submitting an UPDATE request to the `status`
subresource of the CSR to be signed.
As part of this request, the `status.certificate` field should be set to contain the
signed certificate. This field contains one or more PEM-encoded certificates.
All PEM blocks must have the "CERTIFICATE" label, contain no headers,
and the encoded data must be a BER-encoded ASN.1 Certificate structure
as described in [section 4 of RFC5280](https://tools.ietf.org/html/rfc5280#section-4.1).
Example certificate content:
-->
### 基于 API 的签名者 {#signer-api}
REST API 的用户可以通过向待签名的 CSR 的 `status` 子资源提交更新请求来对 CSR 进行签名。
作为这个请求的一部分, `status.certificate` 字段应设置为已签名的证书。
此字段可包含一个或多个 PEM 编码的证书。
所有的 PEM 块必须具备 "CERTIFICATE" 标签,且不包含文件头,且编码的数据必须是
[RFC5280 第 4 节](https://tools.ietf.org/html/rfc5280#section-4.1)
中描述的 BER 编码的 ASN.1 证书结构。
```
-----BEGIN CERTIFICATE-----
MIIDgjCCAmqgAwIBAgIUC1N1EJ4Qnsd322BhDPRwmg3b/oAwDQYJKoZIhvcNAQEL
BQAwXDELMAkGA1UEBhMCeHgxCjAIBgNVBAgMAXgxCjAIBgNVBAcMAXgxCjAIBgNV
BAoMAXgxCjAIBgNVBAsMAXgxCzAJBgNVBAMMAmNhMRAwDgYJKoZIhvcNAQkBFgF4
MB4XDTIwMDcwNjIyMDcwMFoXDTI1MDcwNTIyMDcwMFowNzEVMBMGA1UEChMMc3lz
dGVtOm5vZGVzMR4wHAYDVQQDExVzeXN0ZW06bm9kZToxMjcuMC4wLjEwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDne5X2eQ1JcLZkKvhzCR4Hxl9+ZmU3
+e1zfOywLdoQxrPi+o4hVsUH3q0y52BMa7u1yehHDRSaq9u62cmi5ekgXhXHzGmm
kmW5n0itRECv3SFsSm2DSghRKf0mm6iTYHWDHzUXKdm9lPPWoSOxoR5oqOsm3JEh
Q7Et13wrvTJqBMJo1GTwQuF+HYOku0NF/DLqbZIcpI08yQKyrBgYz2uO51/oNp8a
sTCsV4OUfyHhx2BBLUo4g4SptHFySTBwlpRWBnSjZPOhmN74JcpTLB4J5f4iEeA7
2QytZfADckG4wVkhH3C2EJUmRtFIBVirwDn39GXkSGlnvnMgF3uLZ6zNAgMBAAGj
YTBfMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMB
Af8EAjAAMB0GA1UdDgQWBBTREl2hW54lkQBDeVCcd2f2VSlB1DALBgNVHREEBDAC
ggAwDQYJKoZIhvcNAQELBQADggEBABpZjuIKTq8pCaX8dMEGPWtAykgLsTcD2jYr
L0/TCrqmuaaliUa42jQTt2OVsVP/L8ofFunj/KjpQU0bvKJPLMRKtmxbhXuQCQi1
qCRkp8o93mHvEz3mTUN+D1cfQ2fpsBENLnpS0F4G/JyY2Vrh19/X8+mImMEK5eOy
o0BMby7byUj98WmcUvNCiXbC6F45QTmkwEhMqWns0JZQY+/XeDhEcg+lJvz9Eyo2
aGgPsye1o3DpyXnyfJWAWMhOz7cikS5X2adesbgI86PhEHBXPIJ1v13ZdfCExmdd
M1fLPhLyR54fGaY+7/X8P9AZzPefAkwizeXwe9ii6/a08vWoiE4=
-----END CERTIFICATE-----
```
<!--
Non-PEM content may appear before or after the CERTIFICATE PEM blocks and is unvalidated,
to allow for explanatory text as described in section 5.2 of RFC7468.
When encoded in JSON or YAML, this field is base-64 encoded.
A CertificateSigningRequest containing the example certificate above would look like this:
-->
非 PEM 内容可能会出现在证书 PEM 块前后的位置,且未经验证,
以允许使用 RFC7468 第5.2节 中描述的解释性文本。
当使用 JSON 或 YAML 格式时,此字段是 base-64 编码。
包含上述示例证书的 CertificateSigningRequest 如下所示:
```yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JS..."
```
## {{% heading "whatsnext" %}}
<!--
* Read [Manage TLS Certificates in a Cluster](/docs/tasks/tls/managing-tls-in-a-cluster/)
* View the source code for the kube-controller-manager built in [signer](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/signer/cfssl_signer.go)
* View the source code for the kube-controller-manager built in [approver](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/approver/sarapprove.go)
* For details of X.509 itself, refer to [RFC 5280](https://tools.ietf.org/html/rfc5280#section-3.1) section 3.1
* For information on the syntax of PKCS#10 certificate signing requests, refer to [RFC 2986](https://tools.ietf.org/html/rfc2986)
-->
* 参阅 [管理集群中的 TLS 认证](/zh/docs/tasks/tls/managing-tls-in-a-cluster/)
* 查看 kube-controller-manager 中[签名者](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/signer/cfssl_signer.go)部分的源代码
* 查看 kube-controller-manager 中[批准者](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/approver/sarapprove.go)部分的源代码
* 有关 X.509 本身的详细信息,请参阅 [RFC 5280](https://tools.ietf.org/html/rfc5280#section-3.1) 第3.1节
* 有关 PKCS#10 证书签名请求语法的信息,请参阅 [RFC 2986](https://tools.ietf.org/html/rfc2986)
@@ -0,0 +1,177 @@
---
title: Kubelet 认证/鉴权
---
<!--
reviewers:
- liggitt
title: Kubelet authentication/authorization
-->
<!--
## Overview
-->
## 概述
<!--
A kubelet's HTTPS endpoint exposes APIs which give access to data of varying sensitivity,
and allow you to perform operations with varying levels of power on the node and within containers.
-->
kubelet 的 HTTPS 端点公开了 API
这些 API 可以访问敏感度不同的数据,
并允许你在节点上和容器内以不同级别的权限执行操作。
<!--
This document describes how to authenticate and authorize access to the kubelet's HTTPS endpoint.
-->
本文档介绍了如何对 kubelet 的 HTTPS 端点的访问进行认证和鉴权。
<!--
## Kubelet authentication
-->
## Kubelet 身份认证
<!--
By default, requests to the kubelet's HTTPS endpoint that are not rejected by other configured
authentication methods are treated as anonymous requests, and given a username of `system:anonymous`
and a group of `system:unauthenticated`.
-->
默认情况下,未被已配置的其他身份认证方法拒绝的对 kubelet 的 HTTPS 端点的请求会被视为匿名请求,
并被赋予 `system:anonymous` 用户名和 `system:unauthenticated` 组。
<!--
To disable anonymous access and send `401 Unauthorized` responses to unauthenticated requests:
-->
要禁用匿名访问并向未经身份认证的请求发送 `401 Unauthorized` 响应,请执行以下操作:
<!--
* start the kubelet with the `--anonymous-auth=false` flag
-->
* 带 `--anonymous-auth=false` 标志启动 kubelet
<!--
To enable X509 client certificate authentication to the kubelet's HTTPS endpoint:
-->
要对 kubelet 的 HTTPS 端点启用 X509 客户端证书认证:
<!--
* start the kubelet with the `--client-ca-file` flag, providing a CA bundle to verify client certificates with
* start the apiserver with `--kubelet-client-certificate` and `--kubelet-client-key` flags
* see the [apiserver authentication documentation](/docs/reference/access-authn-authz/authentication/#x509-client-certs) for more details
-->
* 带 `--client-ca-file` 标志启动 kubelet,提供一个 CA 证书包以供验证客户端证书
* 带 `--kubelet-client-certificate``--kubelet-client-key` 标志启动 apiserver
* 有关更多详细信息,请参见
[apiserver 身份验证文档](/zh/docs/reference/access-authn-authz/authentication/#x509-client-certs)
<!--
To enable API bearer tokens (including service account tokens) to be used to authenticate to the kubelet's HTTPS endpoint:
-->
要启用 API 持有者令牌(包括服务帐户令牌)以对 kubelet 的 HTTPS 端点进行身份验证,请执行以下操作:
<!--
* ensure the `authentication.k8s.io/v1beta1` API group is enabled in the API server
* start the kubelet with the `--authentication-token-webhook` and the `--kubeconfig` flags
* the kubelet calls the `TokenReview` API on the configured API server to determine user information from bearer tokens
-->
* 确保在 API 服务器中启用了 `authentication.k8s.io/v1beta1` API 组
* 带 `--authentication-token-webhook``--kubeconfig` 标志启动 kubelet
* kubelet 调用已配置的 API 服务器上的 `TokenReview` API,以根据持有者令牌确定用户信息
<!--
## Kubelet authorization
-->
## Kubelet 鉴权
<!--
Any request that is successfully authenticated (including an anonymous request) is then authorized. The default authorization mode is `AlwaysAllow`, which allows all requests.
-->
任何成功通过身份验证的请求(包括匿名请求)之后都会被鉴权。
默认的鉴权模式为 `AlwaysAllow`,它允许所有请求。
<!--
There are many possible reasons to subdivide access to the kubelet API:
-->
细分对 kubelet API 的访问权限可能有多种原因:
<!--
* anonymous auth is enabled, but anonymous users' ability to call the kubelet API should be limited
* bearer token auth is enabled, but arbitrary API users' (like service accounts) ability to call the kubelet API should be limited
* client certificate auth is enabled, but only some of the client certificates signed by the configured CA should be allowed to use the kubelet API
-->
* 启用了匿名身份验证,但是应限制匿名用户调用 kubelet API 的能力
* 启用了持有者令牌认证,但应限制任意 API 用户(如服务帐户)调用 kubelet API 的能力
* 启用了客户端证书身份验证,但仅应允许已配置的 CA 签名的某些客户端证书使用 kubelet API
<!--
To subdivide access to the kubelet API, delegate authorization to the API server:
-->
要细分对 kubelet API 的访问权限,请将鉴权委派给 API 服务器:
<!--
* ensure the `authorization.k8s.io/v1beta1` API group is enabled in the API server
* start the kubelet with the `--authorization-mode=Webhook` and the `--kubeconfig` flags
* the kubelet calls the `SubjectAccessReview` API on the configured API server to determine whether each request is authorized
-->
* 确保在 API 服务器中启用了 `authorization.k8s.io/v1beta1` API 组
* 带 `--authorization-mode=Webhook``--kubeconfig` 标志启动 kubelet
* kubelet 调用已配置的 API 服务器上的 `SubjectAccessReview` API
以确定每个请求是否得到鉴权
<!--
The kubelet authorizes API requests using the same [request attributes](/docs/reference/access-authn-authz/authorization/#review-your-request-attributes) approach as the apiserver.
-->
kubelet 使用与 apiserver 相同的
[请求属性](/zh/docs/reference/access-authn-authz/authorization/#review-your-request-attributes)
方法对 API 请求执行鉴权。
<!--
The verb is determined from the incoming request's HTTP verb:
-->
请求的动词根据传入请求的 HTTP 动词确定:
<!--
HTTP verb | request verb
-->
HTTP 动词 | 请求动词
----------|---------------
POST | create
GET, HEAD | get
PUT | update
PATCH | patch
DELETE | delete
<!--
The resource and subresource is determined from the incoming request's path:
-->
资源和子资源是根据传入请求的路径确定的:
<!--
Kubelet API | resource | subresource
-->
Kubelet API | 资源 | 子资源
-------------|----------|------------
/stats/\* | nodes | stats
/metrics/\* | nodes | metrics
/logs/\* | nodes | log
/spec/\* | nodes | spec
*其它所有* | nodes | proxy
<!--
The namespace and API group attributes are always an empty string, and
the resource name is always the name of the kubelet's `Node` API object.
-->
名字空间和 API 组属性始终是空字符串,
资源名称始终是 kubelet 的 `Node` API 对象的名称。
<!--
When running in this mode, ensure the user identified by the `--kubelet-client-certificate` and `--kubelet-client-key`
flags passed to the apiserver is authorized for the following attributes:
-->
在此模式下运行时,请确保传递给 apiserver 的由 `--kubelet-client-certificate`
`--kubelet-client-key` 标志标识的用户具有以下属性的鉴权:
* verb=\*, resource=nodes, subresource=proxy
* verb=\*, resource=nodes, subresource=stats
* verb=\*, resource=nodes, subresource=log
* verb=\*, resource=nodes, subresource=spec
* verb=\*, resource=nodes, subresource=metrics
@@ -0,0 +1,906 @@
---
title: TLS 启动引导
content_type: concept
---
<!--
reviewers:
- mikedanese
- liggitt
- smarterclayton
- awly
title: TLS bootstrapping
content_type: concept
-->
<!-- overview -->
<!--
In a Kubernetes cluster, the components on the worker nodes - kubelet and kube-proxy - need to communicate with Kubernetes control plane components, specifically kube-apiserver.
In order to ensure that communication is kept private, not interfered with, and ensure that each component of the cluster is talking to another trusted component, we strongly
recommend using client TLS certificates on nodes.
-->
在一个 Kubernetes 集群中,工作节点上的组件(kubelet 和 kube-proxy)需要与
Kubernetes 控制平面组件通信,尤其是 kube-apiserver。
为了确保通信本身是私密的、不被干扰,并且确保集群的每个组件都在与另一个
可信的组件通信,我们强烈建议使用节点上的客户端 TLS 证书。
<!--
The normal process of bootstrapping these components, especially worker nodes that need certificates so they can communicate safely with kube-apiserver,
can be a challenging process as it is often outside of the scope of Kubernetes and requires significant additional work.
This in turn, can make it challenging to initialize or scale a cluster.
-->
启动引导这些组件的正常过程,尤其是需要证书来与 kube-apiserver 安全通信的
工作节点,可能会是一个具有挑战性的过程,因为这一过程通常不受 Kubernetes 控制,
需要不少额外工作。
这也使得初始化或者扩缩一个集群的操作变得具有挑战性。
<!--
In order to simplify the process, beginning in version 1.4, Kubernetes introduced a certificate request and signing API to simplify the process. The proposal can be
found [here](https://github.com/kubernetes/kubernetes/pull/20439).
This document describes the process of node initialization, how to set up TLS client certificate bootstrapping for
kubelets, and how it works.
-->
为了简化这一过程,从 1.4 版本开始,Kubernetes 引入了一个证书请求和签名
API 以便简化此过程。该提案可在
[这里](https://github.com/kubernetes/kubernetes/pull/20439)看到。
本文档描述节点初始化的过程,如何为 kubelet 配置 TLS 客户端证书启动引导,
以及其背后的工作原理。
<!-- body -->
<!--
## Initialization Process
When a worker node starts up, the kubelet does the following:
-->
## 初始化过程 {#initialization-process}
当工作节点启动时,kubelet 执行以下操作:
<!--
1. Look for its `kubeconfig` file
2. Retrieve the URL of the API server and credentials, normally a TLS key and signed certificate from the `kubeconfig` file
3. Attempt to communicate with the API server using the credentials.
-->
1. 寻找自己的 `kubeconfig` 文件
2. 检索 API 服务器的 URL 和凭据,通常是来自 `kubeconfig` 文件中的
TLS 密钥和已签名证书
3. 尝试使用这些凭据来与 API 服务器通信
<!--
Assuming that the kube-apiserver successfully validates the kubelet's credentials, it will treat the kubelet as a valid node, and begin to assign pods to it.
Note that the above process depends upon:
* Existence of a key and certificate on the local host in the `kubeconfig`
* The certificate having been signed by a Certificate Authority (CA) trusted by the kube-apiserver
-->
假定 kube-apiserver 成功地认证了 kubelet 的凭据数据,它会将 kubelet 视为
一个合法的节点并开始将 Pods 分派给该节点。
注意,签名的过程依赖于:
* `kubeconfig` 中包含密钥和本地主机的证书
* 证书被 kube-apiserver 所信任的一个证书机构(CA)所签名
<!--
All of the following are responsibilities of whoever sets up and manages the cluster:
1. Creating the CA key and certificate
2. Distributing the CA certificate to the control plane nodes, where kube-apiserver is running
3. Creating a key and certificate for each kubelet; strongly recommended to have a unique one, with a unique CN, for each kubelet
4. Signing the kubelet certificate using the CA key
5. Distributing the kubelet key and signed certificate to the specific node on which the kubelet is running
The TLS Bootstrapping described in this document is intended to simplify, and partially or even completely automate, steps 3 onwards, as these are the most common when initializing or scaling
a cluster.
-->
负责部署和管理集群的人有以下责任:
1. 创建 CA 密钥和证书
2. 将 CA 证书发布到 kube-apiserver 运行所在的控制平面节点上
3. 为每个 kubelet 创建密钥和证书;强烈建议为每个 kubelet 使用独一无二的、
CN 取值与众不同的密钥和证书
4. 使用 CA 密钥对 kubelet 证书签名
5. 将 kubelet 密钥和签名的证书发布到 kubelet 运行所在的特定节点上
本文中描述的 TLS 启动引导过程有意简化甚至完全自动化上述过程,尤其是
第三步之后的操作,因为这些步骤是初始化或者扩缩集群时最常见的操作。
<!--
### Bootstrap Initialization
In the bootstrap initialization process, the following occurs:
-->
### 启动引导初始化 {#bootstrap-initialization}
在启动引导初始化过程中,会发生以下事情:
<!--
1. kubelet begins
2. kubelet sees that it does _not_ have a `kubeconfig` file
3. kubelet searches for and finds a `bootstrap-kubeconfig` file
4. kubelet reads its bootstrap file, retrieving the URL of the API server and a limited usage "token"
5. kubelet connects to the API server, authenticates using the token
6. kubelet now has limited credentials to create and retrieve a certificate signing request (CSR)
7. kubelet creates a CSR for itself with the signerName set to `kubernetes.io/kube-apiserver-client-kubelet`
8. CSR is approved in one of two ways:
* If configured, kube-controller-manager automatically approves the CSR
* If configured, an outside process, possibly a person, approves the CSR using the Kubernetes API or via `kubectl`
9. Certificate is created for the kubelet
-->
1. kubelet 启动
2. kubelet 看到自己 *没有* 对应的 `kubeconfig` 文件
3. kubelet 搜索并发现 `bootstrap-kubeconfig` 文件
4. kubelet 读取该启动引导文件,从中获得 API 服务器的 URL 和用途有限的
一个“令牌(Token)”
5. kubelet 建立与 API 服务器的连接,使用上述令牌执行身份认证
6. kubelet 现在拥有受限制的凭据来创建和取回证书签名请求(CSR)
7. kubelet 为自己创建一个 CSR,并将其 signerName 设置为 `kubernetes.io/kube-apiserver-client-kubelet`
8. CSR 被以如下两种方式之一批复:
* 如果配置了,kube-controller-manager 会自动批复该 CSR
* 如果配置了,一个外部进程,或者是人,使用 Kubernetes API 或者使用 `kubectl`
来批复该 CSR
9. kubelet 所需要的证书被创建
<!--
10. Certificate is issued to the kubelet
11. kubelet retrieves the certificate
12. kubelet creates a proper `kubeconfig` with the key and signed certificate
13. kubelet begins normal operation
14. Optional: if configured, kubelet automatically requests renewal of the certificate when it is close to expiry
15. The renewed certificate is approved and issued, either automatically or manually, depending on configuration.
-->
10. 证书被发放给 kubelet
11. kubelet 取回该证书
12. kubelet 创建一个合适的 `kubeconfig`,其中包含密钥和已签名的证书
13. kubelet 开始正常操作
14. 可选地,如果配置了,kubelet 在证书接近于过期时自动请求更新证书
15. 更新的证书被批复并发放;取决于配置,这一过程可能是自动的或者手动完成
<!--
The rest of this document describes the necessary steps to configure TLS Bootstrapping, and its limitations.
-->
本文的其余部分描述配置 TLS 启动引导的必要步骤及其局限性。
<!--
## Configuration
To configure for TLS bootstrapping and optional automatic approval, you must configure options on the following components:
* kube-apiserver
* kube-controller-manager
* kubelet
* in-cluster resources: `ClusterRoleBinding` and potentially `ClusterRole`
In addition, you need your Kubernetes Certificate Authority (CA).
-->
## 配置 {#configuration}
要配置 TLS 启动引导及可选的自动批复,你必须配置以下组件的选项:
* kube-apiserver
* kube-controller-manager
* kubelet
* 集群内的资源:`ClusterRoleBinding` 以及可能需要的 `ClusterRole`
此外,你需要有 Kubernetes 证书机构(Certificate AuthorityCA)。
<!--
## Certificate Authority
As without bootstrapping, you will need a Certificate Authority (CA) key and certificate. As without bootstrapping, these will be used
to sign the kubelet certificate. As before, it is your responsibility to distribute them to control plane nodes.
-->
## 证书机构 {#certificate-authority}
就像在没有启动引导的情况下,你会需要证书机构(CA)密钥和证书。
这些数据会被用来对 kubelet 证书进行签名。
如前所述,将证书机构密钥和证书发布到控制平面节点是你的责任。
<!--
For the purposes of this document, we will assume these have been distributed to control plane nodes at `/var/lib/kubernetes/ca.pem` (certificate) and `/var/lib/kubernetes/ca-key.pem` (key).
We will refer to these as "Kubernetes CA certificate and key".
All Kubernetes components that use these certificates - kubelet, kube-apiserver, kube-controller-manager - assume the key and certificate to be PEM-encoded.
-->
就本文而言,我们假定这些数据被发布到控制平面节点上的
`/var/lib/kubernetes/ca.pem`(证书)和
`/var/lib/kubernetes/ca-key.pem`(密钥)文件中。
我们将这两个文件称作“Kubernetes CA 证书和密钥”。
所有 Kubernetes 组件(kubelet、kube-apiserver、kube-controller-manager)都使用
这些凭据,并假定这里的密钥和证书都是 PEM 编码的。
<!--
## kube-apiserver configuration
The kube-apiserver has several requirements to enable TLS bootstrapping:
* Recognizing CA that signs the client certificate
* Authenticating the bootstrapping kubelet to the `system:bootstrappers` group
* Authorize the bootstrapping kubelet to create a certificate signing request (CSR)
-->
## kube-apiserver 配置 {#kube-apiserver-configuration}
启用 TLS 启动引导对 kube-apiserver 有若干需求:
* 能够识别对客户端证书进行签名的 CA
* 能够对启动引导的 kubelet 执行身份认证,并将其置入 `system:bootstrappers`
* 能够对启动引导的 kubelet 执行鉴权操作,允许其创建证书签名请求(CSR)
<!--
### Recognizing client certificates
This is normal for all client certificate authentication.
If not already set, add the `--client-ca-file=FILENAME` flag to the kube-apiserver command to enable
client certificate authentication, referencing a certificate authority bundle
containing the signing certificate, for example
`--client-ca-file=/var/lib/kubernetes/ca.pem`.
-->
### 识别客户证书 {#recognizing-client-certificates}
对于所有客户端证书的认证操作而言,这是很常见的。
如果还没有设置,要为 kube-apiserver 命令添加 `--client-ca-file=FILENAME`
标志来启用客户端证书认证,在标志中引用一个包含用来签名的证书的证书机构包,
例如:`--client-ca-file=/var/lib/kubernetes/ca.pem`
<!--
### Initial bootstrap authentication
In order for the bootstrapping kubelet to connect to kube-apiserver and request a certificate, it must first authenticate to the server.
You can use any [authenticator](/docs/reference/access-authn-authz/authentication/) that can authenticate the kubelet.
-->
### 初始启动引导认证 {#initial-bootstrap-authentication}
为了让启动引导的 kubelet 能够连接到 kube-apiserver 并请求证书,
它必须首先在服务器上认证自身身份。你可以使用任何一种能够对 kubelet 执行身份认证的
[身份认证组件](/zh/docs/reference/access-authn-authz/authentication/)。
<!--
While any authentication strategy can be used for the kubelet's initial
bootstrap credentials, the following two authenticators are recommended for ease
of provisioning.
1. [Bootstrap Tokens](#bootstrap-tokens)
2. [Token authentication file](#token-authentication-file)
-->
尽管所有身份认证策略都可以用来对 kubelet 的初始启动凭据来执行认证,
出于容易准备的因素,建议使用如下两个身份认证组件:
1. [启动引导令牌(Bootstrap Token](#bootstrap-tokens)
2. [令牌认证文件](#token-authentication-file)
<!--
Bootstrap tokens are a simpler and more easily managed method to authenticate kubelets, and do not require any additional flags when starting kube-apiserver.
-->
启动引导令牌是一种对 kubelet 进行身份认证的方法,相对简单且容易管理,
且不需要在启动 kube-apiserver 时设置额外的标志。
<!--
Whichever method you choose, the requirement is that the kubelet be able to authenticate as a user with the rights to:
1. create and retrieve CSRs
2. be automatically approved to request node client certificates, if automatic approval is enabled.
-->
无论选择哪种方法,这里的需求是 kubelet 能够被身份认证为某个具有如下权限的用户:
1. 创建和读取 CSR
2. 在启用了自动批复时,能够在请求节点客户端证书时得到自动批复
<!--
A kubelet authenticating using bootstrap tokens is authenticated as a user in the group `system:bootstrappers`, which is the standard method to use.
-->
使用启动引导令牌执行身份认证的 kubelet 会被认证为 `system:bootstrappers`
组中的用户。这是使用启动引导令牌的一种标准方法。
<!--
As this feature matures, you
should ensure tokens are bound to a Role Based Access Control (RBAC) policy
which limits requests (using the [bootstrap token](/docs/reference/access-authn-authz/bootstrap-tokens/)) strictly to client
requests related to certificate provisioning. With RBAC in place, scoping the
tokens to a group allows for great flexibility. For example, you could disable a
particular bootstrap group's access when you are done provisioning the nodes.
-->
随着这个功能特性的逐渐成熟,你需要确保令牌绑定到某基于角色的的访问控制(RBAC)
策略上,从而严格限制请求(使用[启动引导令牌](/zh/docs/reference/access-authn-authz/bootstrap-tokens/)
仅限于客户端申请提供证书。当 RBAC 被配置启用时,可以将令牌限制到某个组,从而
提高灵活性。例如,你可以在准备节点期间禁止某特定启动引导组的访问。
<!--
#### Bootstrap tokens
Bootstrap tokens are described in detail [here](/docs/reference/access-authn-authz/bootstrap-tokens/). These are tokens that are stored as secrets in the Kubernetes cluster,
and then issued to the individual kubelet. You can use a single token for an entire cluster, or issue one per worker node.
-->
#### 启动引导令牌 {#bootstrap-tokens}
启动引导令牌的细节在[这里](/zh/docs/reference/access-authn-authz/bootstrap-tokens/)
详述。启动引导令牌在 Kubernetes 集群中存储为 Secret 对象,被发放给各个 kubelet。
你可以在整个集群中使用同一个令牌,也可以为每个节点发放单独的令牌。
<!--
The process is two-fold:
1. Create a Kubernetes secret with the token ID, secret and scope(s).
2. Issue the token to the kubelet
-->
这一过程有两个方面:
1. 基于令牌 ID、机密数据和范畴信息创建 Kubernetes Secret
2. 将令牌发放给 kubelet
<!--
From the kubelet's perspective, one token is like another and has no special meaning.
From the kube-apiserver's perspective, however, the bootstrap token is special. Due to its `type`, `namespace` and `name`, kube-apiserver recognizes it as a special token,
and grants anyone authenticating with that token special bootstrap rights, notably treating them as a member of the `system:bootstrappers` group. This fulfills a basic requirement
for TLS bootstrapping.
-->
从 kubelet 的角度,所有令牌看起来都很像,没有特别的含义。
从 kube-apiserver 服务器的角度,启动引导令牌是很特殊的。
根据其 `type``namespace``name`kube-apiserver 能够将认作特殊的令牌,
并授予携带该令牌的任何人特殊的启动引导权限,换言之,将其视为
`system:bootstrappers` 组的成员。这就满足了 TLS 启动引导的基本需求。
<!--
The details for creating the secret are available [here](/docs/reference/access-authn-authz/bootstrap-tokens/).
If you want to use bootstrap tokens, you must enable it on kube-apiserver with the flag:
-->
关于创建 Secret 的进一步细节可访问[这里](/zh/docs/reference/access-authn-authz/bootstrap-tokens/)。
如果你希望使用启动引导令牌,你必须在 kube-apiserver 上使用下面的标志启用之:
```console
--enable-bootstrap-token-auth=true
```
<!--
#### Token authentication file
kube-apiserver has the ability to accept tokens as authentication.
These tokens are arbitrary but should represent at least 128 bits of entropy derived
from a secure random number generator (such as `/dev/urandom` on most modern Linux
systems). There are multiple ways you can generate a token. For example:
-->
#### 令牌认证文件 {#token-authentication-file}
kube-apiserver 能够将令牌视作身份认证依据。
这些令牌可以是任意数据,但必须表示为基于某安全的随机数生成器而得到的
至少 128 位混沌数据。这里的随机数生成器可以是现代 Linux 系统上的
`/dev/urandom`。生成令牌的方式有很多种。例如:
```shell
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
```
<!--
will generate tokens that look like `02b50b05283e98dd0fd71db496ef01e8`.
The token file should look like the following example, where the first three
values can be anything and the quoted group name should be as depicted:
-->
上面的命令会生成类似于 `02b50b05283e98dd0fd71db496ef01e8` 这样的令牌。
令牌文件看起来是下面的例子这样,其中前面三个值可以是任何值,用引号括起来
的组名称则只能用例子中给的值。
```console
02b50b05283e98dd0fd71db496ef01e8,kubelet-bootstrap,10001,"system:bootstrappers"
```
<!--
Add the `--token-auth-file=FILENAME` flag to the kube-apiserver command (in your
systemd unit file perhaps) to enable the token file. See docs
[here](/docs/reference/access-authn-authz/authentication/#static-token-file) for
further details.
-->
向 kube-apiserver 添加 `--token-auth-file=FILENAME` 标志(或许这要对 systemd
的单元文件作修改)以启用令牌文件。参见
[这里](/zh/docs/reference/access-authn-authz/authentication/#static-token-file)
的文档以了解进一步的细节。
<!--
### Authorize kubelet to create CSR
Now that the bootstrapping node is _authenticated_ as part of the
`system:bootstrappers` group, it needs to be _authorized_ to create a
certificate signing request (CSR) as well as retrieve it when done.
Fortunately, Kubernetes ships with a `ClusterRole` with precisely these (and
only these) permissions, `system:node-bootstrapper`.
To do this, you only need to create a `ClusterRoleBinding` that binds the `system:bootstrappers` group to the cluster role `system:node-bootstrapper`.
-->
### 授权 kubelet 创建 CSR {#authorize-kubelet-to-create-csr}
现在启动引导节点被身份认证为 `system:bootstrapping` 组的成员,它需要被 _授权_
创建证书签名请求(CSR)并在证书被签名之后将其取回。
幸运的是,Kubernetes 提供了一个 `ClusterRole`,其中精确地封装了这些许可,
`system:node-bootstrapper`
为了实现这一点,你只需要创建 `ClusterRoleBinding`,将 `system:bootstrappers`
组绑定到集群角色 `system:node-bootstrapper`
```yaml
# 允许启动引导节点创建 CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: create-csrs-for-bootstrapping
subjects:
- kind: Group
name: system:bootstrappers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:node-bootstrapper
apiGroup: rbac.authorization.k8s.io
```
<!--
## kube-controller-manager configuration
While the apiserver receives the requests for certificates from the kubelet and authenticates those requests,
the controller-manager is responsible for issuing actual signed certificates.
-->
## kube-controller-manager 配置 {#kube-controller-manager-configuration}
API 服务器从 kubelet 收到证书请求并对这些请求执行身份认证,但真正负责发放
签名证书的是控制器管理器。
<!--
The controller-manager performs this function via a certificate-issuing control loop.
This takes the form of a
[cfssl](https://blog.cloudflare.com/introducing-cfssl/) local signer using
assets on disk. Currently, all certificates issued have one year validity and a
default set of key usages.
-->
控制器管理器通过一个证书发放的控制回路来执行此操作。该操作的执行方式是使用磁盘上
的文件用 [cfssl](https://blog.cloudflare.com/introducing-cfssl/) 本地签名组件
来完成。目前,所发放的所有证书都有一年的有效期,并设定了默认的一组密钥用法。
<!--
In order for the controller-manager to sign certificates, it needs the following:
* access to the "Kubernetes CA key and certificate" that you created and distributed
* enabling CSR signing
-->
为了让控制器管理器对证书签名,它需要:
* 能够访问你之前所创建并分发的“Kubernetes CA 密钥和证书”
* 启用 CSR 签名
<!--
### Access to key and certificate
As described earlier, you need to create a Kubernetes CA key and certificate, and distribute it to the control plane nodes.
These will be used by the controller-manager to sign the kubelet certificates.
-->
### 访问密钥和证书 {#access-to-key-and-certificate}
如前所述,你需要创建一个 Kubernetes CA 密钥和证书,并将其发布到控制平面节点。
这些数据会被控制器管理器来对 kubelet 证书进行签名。
<!--
Since these signed certificates will, in turn, be used by the kubelet to authenticate as a regular kubelet to kube-apiserver, it is important that the CA
provided to the controller-manager at this stage also be trusted by kube-apiserver for authentication. This is provided to kube-apiserver
with the flag `--client-ca-file=FILENAME` (for example, `--client-ca-file=/var/lib/kubernetes/ca.pem`), as described in the kube-apiserver configuration section.
To provide the Kubernetes CA key and certificate to kube-controller-manager, use the following flags:
-->
由于这些被签名的证书反过来会被 kubelet 用来在 kube-apiserver 执行普通的
kubelet 身份认证,很重要的一点是为控制器管理器所提供的 CA 也被 kube-apiserver
信任用来执行身份认证。CA 密钥和证书是通过 kube-apiserver 的标志
`--client-ca-file=FILENAME`(例如,`--client-ca-file=/var/lib/kubernetes/ca.pem`)
来设定的,正如 kube-apiserver 配置节所述。
要将 Kubernetes CA 密钥和证书提供给 kube-controller-manager,可使用以下标志:
```shell
--cluster-signing-cert-file="/etc/path/to/kubernetes/ca/ca.crt" --cluster-signing-key-file="/etc/path/to/kubernetes/ca/ca.key"
```
<!--
For example:
-->
例如:
```shell
--cluster-signing-cert-file="/var/lib/kubernetes/ca.pem" --cluster-signing-key-file="/var/lib/kubernetes/ca-key.pem"
```
<!--
The validity duration of signed certificates can be configured with flag:
-->
所签名的证书的合法期限可以通过下面的标志来配置:
```shell
--cluster-signing-duration
```
<!--
### Approval
In order to approve CSRs, you need to tell the controller-manager that it is acceptable to approve them. This is done by granting
RBAC permissions to the correct group.
-->
### 批复 {#approval}
为了对 CSR 进行批复,你需要告诉控制器管理器批复这些 CSR 是可接受的。
这是通过将 RBAC 访问权限授予正确的组来实现的。
<!--
There are two distinct sets of permissions:
* `nodeclient`: If a node is creating a new certificate for a node, then it does not have a certificate yet. It is authenticating using one of the tokens listed above, and thus is part of the group `system:bootstrappers`.
* `selfnodeclient`: If a node is renewing its certificate, then it already has a certificate (by definition), which it uses continuously to authenticate as part of the group `system:nodes`.
-->
许可权限有两组:
* `nodeclient`:如果节点在为节点创建新的证书,则该节点还没有证书。该节点
使用前文所列的令牌之一来执行身份认证,因此是组 `system:bootstrappers`
的成员。
* `selfnodeclient`:如果节点在对证书执行续期操作,则该节点已经拥有一个证书。
节点持续使用现有的证书将自己认证为 `system:nodes` 组的成员。
<!--
To enable the kubelet to request and receive a new certificate, create a `ClusterRoleBinding` that binds the group in which the bootstrapping node is a member `system:bootstrappers` to the `ClusterRole` that grants it permission, `system:certificates.k8s.io:certificatesigningrequests:nodeclient`:
-->
要允许 kubelet 请求并接收新的证书,可以创建一个 `ClusterRoleBinding` 将启动
引导节点所处的组 `system:bootstrappers` 绑定到为其赋予访问权限的
`ClusterRole` `system:certificates.k8s.io:certificatesigningrequests:nodeclient`
```yaml
# 批复 "system:bootstrappers" 组的所有 CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: auto-approve-csrs-for-group
subjects:
- kind: Group
name: system:bootstrappers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
apiGroup: rbac.authorization.k8s.io
```
<!--
To enable the kubelet to renew its own client certificate, create a `ClusterRoleBinding` that binds the group in which the fully functioning node is a member `system:nodes` to the `ClusterRole` that
grants it permission, `system:certificates.k8s.io:certificatesigningrequests:selfnodeclient`:
-->
要允许 kubelet 对其客户端证书执行续期操作,可以创建一个 `ClusterRoleBinding`
将正常工作的节点所处的组 `system:nodes` 绑定到为其授予访问许可的 `ClusterRole`
`system:certificates.k8s.io:certificatesigningrequests:selfnodeclient`
```yaml
# 批复 "system:nodes" 组的 CSR 续约请求
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: auto-approve-renewals-for-nodes
subjects:
- kind: Group
name: system:nodes
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
apiGroup: rbac.authorization.k8s.io
```
<!--
The `csrapproving` controller that ships as part of
[kube-controller-manager](/docs/admin/kube-controller-manager/) and is enabled
by default. The controller uses the [`SubjectAccessReview`
API](/docs/reference/access-authn-authz/authorization/#checking-api-access) to
determine if a given user is authorized to request a CSR, then approves based on
the authorization outcome. To prevent conflicts with other approvers, the
builtin approver doesn't explicitly deny CSRs. It only ignores unauthorized
requests. The controller also prunes expired certificates as part of garbage
collection.
-->
作为 [kube-controller-manager](/zh/docs/reference/generated/kube-controller-manager/)
的一部分的 `csrapproving` 控制器是自动被启用的。
该控制器使用 [`SubjectAccessReview` API](/zh/docs/reference/access-authn-authz/authorization/#checking-api-access)
来确定是否某给定用户被授权请求 CSR,之后基于鉴权结果执行批复操作。
为了避免与其它批复组件发生冲突,内置的批复组件不会显式地拒绝任何 CSRs。
该组件仅是忽略未被授权的请求。
控制器也会作为垃圾收集的一部分清除已过期的证书。
<!--
## kubelet configuration
Finally, with the control plane properly set up and all of the necessary authentication and authorization in place, we can configure the kubelet.
-->
## kubelet 配置 {#kubelet-configuration}
最后,当控制平面节点被正确配置并且所有必要的身份认证和鉴权机制都就绪时,
我们可以配置 kubelet。
<!--
The kubelet requires the following configuration to bootstrap:
* A path to store the key and certificate it generates (optional, can use default)
* A path to a `kubeconfig` file that does not yet exist; it will place the bootstrapped config file here
* A path to a bootstrap `kubeconfig` file to provide the URL for the server and bootstrap credentials, e.g. a bootstrap token
* Optional: instructions to rotate certificates
-->
kubelet 需要以下配置来执行启动引导:
* 一个用来存储所生成的密钥和证书的路径(可选,可以使用默认配置)
* 一个用来指向尚不存在的 `kubeconfig` 文件的路径;kubelet 会将启动引导
配置文件放到这个位置
* 一个指向启动引导 `kubeconfig` 文件的路径,用来提供 API 服务器的 URL
和启动引导凭据,例如,启动引导令牌
* 可选的:轮换证书的指令
<!--
The bootstrap `kubeconfig` should be in a path available to the kubelet, for example `/var/lib/kubelet/bootstrap-kubeconfig`.
Its format is identical to a normal `kubeconfig` file. A sample file might look as follows:
-->
启动引导 `kubeconfig` 文件应该放在一个 kubelet 可访问的路径下,例如
`/var/lib/kubelet/bootstrap-kubeconfig`
其格式与普通的 `kubeconfig` 文件完全相同。实例文件可能看起来像这样:
```yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /var/lib/kubernetes/ca.pem
server: https://my.server.example.com:6443
name: bootstrap
contexts:
- context:
cluster: bootstrap
user: kubelet-bootstrap
name: bootstrap
current-context: bootstrap
preferences: {}
users:
- name: kubelet-bootstrap
user:
token: 07401b.f395accd246ae52d
```
<!--
The important elements to note are:
* `certificate-authority`: path to a CA file, used to validate the server certificate presented by kube-apiserver
* `server`: URL to kube-apiserver
* `token`: the token to use
-->
需要额外注意的一些因素有:
* `certificate-authority`:指向 CA 文件的路径,用来对 kube-apiserver 所出示
的服务器证书进行验证
* `server` 用来访问 kube-apiserver 的 URL
* `token`:要使用的令牌
<!--
The format of the token does not matter, as long as it matches what kube-apiserver expects. In the above example, we used a bootstrap token.
As stated earlier, _any_ valid authentication method can be used, not only tokens.
Because the bootstrap `kubeconfig` _is_ a standard `kubeconfig`, you can use `kubectl` to generate it. To create the above example file:
-->
令牌的格式并不重要,只要它与 kube-apiserver 的期望匹配即可。
在上面的例子中,我们使用的是启动引导令牌。
如前所述,任何合法的身份认证方法都可以使用,不限于令牌。
因为启动引导 `kubeconfig` 文件是一个标准的 `kubeconfig` 文件,你可以使用
`kubectl` 来生成该文件。要生成上面的示例文件:
```
kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-cluster bootstrap --server='https://my.server.example.com:6443' --certificate-authority=/var/lib/kubernetes/ca.pem
kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=07401b.f395accd246ae52d
kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap
kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig use-context bootstrap
```
<!--
To indicate to the kubelet to use the bootstrap `kubeconfig`, use the following kubelet flag:
-->
要指示 kubelet 使用启动引导 `kubeconfig` 文件,可以使用下面的 kubelet 标志:
```
--bootstrap-kubeconfig="/var/lib/kubelet/bootstrap-kubeconfig" --kubeconfig="/var/lib/kubelet/kubeconfig"
```
<!--
When starting the kubelet, if the file specified via `--kubeconfig` does not
exist, the bootstrap kubeconfig specified via `--bootstrap-kubeconfig` is used
to request a client certificate from the API server. On approval of the
certificate request and receipt back by the kubelet, a kubeconfig file
referencing the generated key and obtained certificate is written to the path
specified by `--kubeconfig`. The certificate and key file will be placed in the
directory specified by `--cert-dir`.
-->
在启动 kubelet 时,如果 `--kubeconfig` 标志所指定的文件并不存在,会使用通过标志
`--bootstrap-kubeconfig` 所指定的启动引导 kubeconfig 配置来向 API 服务器请求
客户端证书。在证书请求被批复并被 kubelet 收回时,一个引用所生成的密钥和所获得
证书的 kubeconfig 文件会被写入到通过 `--kubeconfig` 所指定的文件路径下。
证书和密钥文件会被放到 `--cert-dir` 所指定的目录中。
<!--
### Client and Serving Certificates
All of the above relate to kubelet _client_ certificates, specifically, the certificates a kubelet
uses to authenticate to kube-apiserver.
-->
### 客户和服务证书 {#client-and-serving-certificates}
前文所述的内容都与 kubelet _客户端_ 证书相关,尤其是 kubelet 用来向
kube-apiserver 认证自身身份的证书。
<!--
A kubelet also can use _serving_ certificates. The kubelet itself exposes an https endpoint for certain features.
To secure these, the kubelet can do one of:
* use provided key and certificate, via the `--tls-private-key-file` and `--tls-cert-file` flags
* create self-signed key and certificate, if a key and certificate are not provided
* request serving certificates from the cluster server, via the CSR API
-->
kubelet 也可以使用 _服务(Serving_ 证书。kubelet 自身向外提供一个
HTTPS 末端,包含若干功能特性。要保证这些末端的安全性,kubelet 可以执行以下操作
之一:
* 使用通过 `--tls-private-key-file``--tls-cert-file` 所设置的密钥和证书
* 如果没有提供密钥和证书,则创建自签名的密钥和证书
* 通过 CSR API 从集群服务器请求服务证书
<!--
The client certificate provided by TLS bootstrapping is signed, by default, for `client auth` only, and thus cannot
be used as serving certificates, or `server auth`.
However, you _can_ enable its server certificate, at least partially, via certificate rotation.
-->
TLS 启动引导所提供的客户端证书默认被签名为仅用于 `client auth`(客户端认证),
因此不能作为提供服务的证书,或者 `server auth`
不过,你可以启用服务器证书,至少可以部分地通过证书轮换来实现这点。
<!--
### Certificate Rotation
Kubernetes v1.8 and higher kubelet implements __beta__ features for enabling
rotation of its client and/or serving certificates. These can be enabled through
the respective `RotateKubeletClientCertificate` and
`RotateKubeletServerCertificate` feature flags on the kubelet and are enabled by
default.
-->
### 证书轮换 {#certificate-rotation}
Kubernetes v1.8 和更高版本的 kubelet 实现了对客户端证书与/或服务证书进行轮换
这一 Beta 特性。这一特性通过 kubelet 对应的 `RotateKubeletClientCertificate`
`RotateKubeletServerCertificate` 特性门控标志来控制,并且是默认启用的。
<!--
`RotateKubeletClientCertificate` causes the kubelet to rotate its client
certificates by creating new CSRs as its existing credentials expire. To enable
this feature pass the following flag to the kubelet:
-->
`RotateKubeletClientCertificate` 会导致 kubelet 在其现有凭据即将过期时通过
创建新的 CSR 来轮换其客户端证书。要启用此功能特性,可将下面的标志传递给
kubelet
```
--rotate-certificates
```
<!--
`RotateKubeletServerCertificate` causes the kubelet **both** to request a serving
certificate after bootstrapping its client credentials **and** to rotate that
certificate. To enable this feature pass the following flag to the kubelet:
-->
`RotateKubeletServerCertificate` 会让 kubelet 在启动引导其客户端凭据之后请求
一个服务证书 **且** 对该服务证书执行轮换操作。要启用此功能特性,将下面的标志
传递给 kubelet
```
--rotate-server-certificates
```
{{< note >}}
<!--
The CSR approving controllers implemented in core Kubernetes do not
approve node _serving_ certificates for [security
reasons](https://github.com/kubernetes/community/pull/1982). To use
`RotateKubeletServerCertificate` operators need to run a custom approving
controller, or manually approve the serving certificate requests.
-->
Kubernetes 核心中所实现的 CSR 批复控制器出于
[安全原因](https://github.com/kubernetes/community/pull/1982)
并不会自动批复节点的 _服务_ 证书。
要使用 `RotateKubeletServerCertificate` 功能特性,集群运维人员需要运行一个
定制的控制器或者手动批复服务证书的请求。
<!--
A deployment-specific approval process for kubelet serving certificates should typically only approve CSRs which:
1. are requested by nodes (ensure the `spec.username` field is of the form
`system:node:<nodeName>` and `spec.groups` contains `system:nodes`)
2. request usages for a serving certificate (ensure `spec.usages` contains `server auth`,
optionally contains `digital signature` and `key encipherment`, and contains no other usages)
3. only have IP and DNS subjectAltNames that belong to the requesting node,
and have no URI and Email subjectAltNames (parse the x509 Certificate Signing Request
in `spec.request` to verify `subjectAltNames`)
-->
对 kubelet 服务证书的批复过程因集群部署而异,通常应该仅批复如下 CSR:
1. 由节点发出的请求(确保 `spec.username` 字段形式为 `system:node:<nodeName>`
`spec.groups` 包含 `system:nodes`
2. 请求中包含服务证书用法(确保 `spec.usages` 中包含 `server auth`,可选地也可
包含 `digital signature``key encipherment`,且不包含其它用法)
3. 仅包含隶属于请求节点的 IP 和 DNS 的 `subjectAltNames`,没有 URI 和 Email
形式的 `subjectAltNames`(解析 `spec.request` 中的 x509 证书签名请求可以
检查 `subjectAltNames`
{{< /note >}}
<!--
## Other authenticating components
All of TLS bootstrapping described in this document relates to the kubelet. However,
other components may need to communicate directly with kube-apiserver. Notable is kube-proxy, which
is part of the Kubernetes control plane and runs on every node, but may also include other components such as monitoring or networking.
-->
## 其它身份认证组件 {#other-authenticating-components}
本文所描述的所有 TLS 启动引导内容都与 kubelet 相关。不过,其它组件也可能需要
直接与 kube-apiserver 直接通信。容易想到的是 kube-proxy,同样隶属于
Kubernetes 的控制面并且运行在所有节点之上,不过也可能包含一些其它负责
监控或者联网的组件。
<!--
Like the kubelet, these other components also require a method of authenticating to kube-apiserver.
You have several options for generating these credentials:
-->
与 kubelet 类似,这些其它组件也需要一种向 kube-apiserver 认证身份的方法。
你可以用几种方法来生成这类凭据:
<!--
* The old way: Create and distribute certificates the same way you did for kubelet before TLS bootstrapping
* DaemonSet: Since the kubelet itself is loaded on each node, and is sufficient to start base services, you can run kube-proxy and other node-specific services not as a standalone process, but rather as a daemonset in the `kube-system` namespace. Since it will be in-cluster, you can give it a proper service account with appropriate permissions to perform its activities. This may be the simplest way to configure such services.
-->
* 较老的方式:和 kubelet 在 TLS 启动引导之前所做的一样,用类似的方式
创建和分发证书
* DaemonSet:由于 kubelet 自身被加载到所有节点之上,并且有足够能力来启动基本服务,
你可以运行将 kube-proxy 和其它特定节点的服务作为 `kube-system` 名字空间中的
DaemonSet 来执行,而不是独立的进程。由于 DaemonSet 位于集群内部,你可以为其
指派一个合适的服务账户,使之具有适当的访问权限来完成其使命。这也许是配置此类
服务的最简单的方法。
<!--
## kubectl approval
CSRs can be approved outside of the approval flows builtin to the controller
manager.
-->
## kubectl 批复 {#kubectl-approval}
CSRs 可以在控制器管理其内置的批复工作流之外被批复。
<!--
The signing controller does not immediately sign all certificate requests.
Instead, it waits until they have been flagged with an "Approved" status by an
appropriately-privileged user. This flow is intended to allow for automated
approval handled by an external approval controller or the approval controller
implemented in the core controller-manager. However cluster administrators can
also manually approve certificate requests using kubectl. An administrator can
list CSRs with `kubectl get csr` and describe one in detail with `kubectl
describe csr <name>`. An administrator can approve or deny a CSR with `kubectl
certificate approve <name>` and `kubectl certificate deny <name>`.
-->
签名控制器并不会立即对所有证书请求执行签名操作。相反,它会等待这些请求被某
具有适当特权的用户标记为 “Approved(已批准)”状态。
这一流程有意允许由外部批复控制器来自动执行的批复,或者由控制器管理器内置的
批复控制器来自动批复。
不过,集群管理员也可以使用 `kubectl` 来手动批准证书请求。
管理员可以通过 `kubectl get csr` 来列举所有的 CSR,使用
`kubectl descsribe csr <name>` 来描述某个 CSR 的细节。
管理员可以使用 `kubectl certificate approve <name` 来批准某 CSR,或者
`kubectl certificate deny <name>` 来拒绝某 CSR。
@@ -0,0 +1,205 @@
---
title: 使用 Node 鉴权
content_type: concept
weight: 90
---
<!--
---
reviewers:
- timstclair
- deads2k
- liggitt
- ericchiang
title: Using Node Authorization
content_type: concept
weight: 90
---
-->
<!-- overview -->
节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求进行鉴权。
<!--
Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.
-->
<!-- body -->
## 概述
<!--
## Overview
-->
节点鉴权器允许 kubelet 执行 API 操作。包括:
<!--
The Node authorizer allows a kubelet to perform API operations. This includes:
-->
读取操作:
<!--
Read operations:
-->
* services
* endpoints
* nodes
* pods
* secrets、configmaps、pvcs 以及绑定到 kubelet 节点的与 pod 相关的持久卷
<!--
* services
* endpoints
* nodes
* pods
* secrets, configmaps, persistent volume claims and persistent volumes related to pods bound to the kubelet's node
-->
写入操作:
<!--
Write operations:
-->
* 节点和节点状态(启用 `NodeRestriction` 准入插件以限制 kubelet 只能修改自己的节点)
* Pod 和 Pod 状态 (启用 `NodeRestriction` 准入插件以限制 kubelet 只能修改绑定到自身的 Pod)
* 事件
<!--
* nodes and node status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify its own node)
* pods and pod status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify pods bound to itself)
* events
-->
鉴权相关操作:
<!--
Auth-related operations:
-->
* 对于基于 TLS 的启动引导过程时使用的
[certificationsigningrequests API](/zh/docs/reference/access-authn-authz/certificate-signing-requests/)
的读/写权限
* 为委派的身份验证/授权检查创建 TokenReview 和 SubjectAccessReview 的能力
<!--
* read/write access to the [CertificateSigningRequests API](/docs/reference/access-authn-authz/certificate-signing-requests/) for TLS bootstrapping
* the ability to create TokenReviews and SubjectAccessReviews for delegated authentication/authorization checks
-->
在将来的版本中,节点鉴权器可能会添加或删除权限,以确保 kubelet 具有正确操作所需的最小权限集。
<!--
In future releases, the node authorizer may add or remove permissions to ensure kubelets
have the minimal set of permissions required to operate correctly.
-->
为了获得节点鉴权器的授权,kubelet 必须使用一个凭证以表示它在 `system:nodes` 组中,用户名为 `system:node:<nodeName>`
上述的组名和用户名格式要与 [kubelet TLS 启动引导](/zh/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/)过程中为每个 kubelet 创建的标识相匹配。
<!--
In order to be authorized by the Node authorizer, kubelets must use a credential that identifies them as
being in the `system:nodes` group, with a username of `system:node:<nodeName>`.
This group and user name format match the identity created for each kubelet as part of
[kubelet TLS bootstrapping](/docs/reference/access-authn-authz/kubelet-tls-bootstrapping/).
-->
要启用节点授权器,请使用 `--authorization-mode = Node` 启动 apiserver。
<!--
To enable the Node authorizer, start the apiserver with `--authorization-mode=Node`.
-->
要限制 kubelet 具有写入权限的 API 对象,请使用 `--enable-admission-plugins=...,NodeRestriction,...` 启动 apiserver,从而启用 [NodeRestriction](/zh/docs/reference/access-authn-authz/admission-controllers#NodeRestriction) 准入插件。
<!--
To limit the API objects kubelets are able to write, enable the [NodeRestriction](/docs/reference/access-authn-authz/admission-controllers#NodeRestriction) admission plugin by starting the apiserver with `--enable-admission-plugins=...,NodeRestriction,...`
-->
## 迁移考虑因素
<!--
## Migration considerations
-->
### 在 `system:nodes` 组之外的 Kubelet
<!--
### Kubelets outside the `system:nodes` group
-->
`system:nodes` 组之外的 kubelet 不会被 `Node` 鉴权模式授权,并且需要继续通过当前授权它们的机制来授权。
节点准入插件不会限制来自这些 kubelet 的请求。
<!--
Kubelets outside the `system:nodes` group would not be authorized by the `Node` authorization mode,
and would need to continue to be authorized via whatever mechanism currently authorizes them.
The node admission plugin would not restrict requests from these kubelets.
-->
### 具有无差别用户名的 Kubelet
<!--
### Kubelets with undifferentiated usernames
-->
在一些部署中,kubelet 具有 `system:nodes` 组的凭证,但是无法给出它们所关联的节点的标识,因为它们没有 `system:node:...` 格式的用户名。
这些 kubelet 不会被 `Node` 授权模式授权,并且需要继续通过当前授权它们的任何机制来授权。
<!--
In some deployments, kubelets have credentials that place them in the `system:nodes` group,
but do not identify the particular node they are associated with,
because they do not have a username in the `system:node:...` format.
These kubelets would not be authorized by the `Node` authorization mode,
and would need to continue to be authorized via whatever mechanism currently authorizes them.
-->
因为默认的节点标识符实现不会把它当作节点身份标识,`NodeRestriction` 准入插件会忽略来自这些 kubelet 的请求。
<!--
The `NodeRestriction` admission plugin would ignore requests from these kubelets,
since the default node identifier implementation would not consider that a node identity.
-->
### 相对于以前使用 RBAC 的版本的更新
<!--
### Upgrades from previous versions using RBAC
-->
升级的 1.7 之前的使用 [RBAC](/zh/docs/reference/access-authn-authz/rbac/) 的集群将继续按原样运行,因为 `system:nodes` 组绑定已经存在。
<!--
Upgraded pre-1.7 clusters using [RBAC](/docs/reference/access-authn-authz/rbac/) will continue functioning as-is because the `system:nodes` group binding will already exist.
-->
如果集群管理员希望开始使用 `Node` 鉴权器和 `NodeRestriction` 准入插件来限制节点对 API 的访问,这一需求可以通过下列操作来完成且不会影响已部署的应用:
<!--
If a cluster admin wishes to start using the `Node` authorizer and `NodeRestriction` admission plugin
to limit node access to the API, that can be done non-disruptively:
-->
1. 启用 `Node` 鉴权模式 (`--authorization-mode=Node,RBAC`) 和 `NodeRestriction` 准入插件
2. 确保所有 kubelet 的凭据符合组/用户名要求
3. 审核 apiserver 日志以确保 `Node` 鉴权器不会拒绝来自 kubelet 的请求(日志中没有持续的 `NODE DENY` 消息)
4. 删除 `system:node` 集群角色绑定
<!--
1. Enable the `Node` authorization mode (`--authorization-mode=Node,RBAC`) and the `NodeRestriction` admission plugin
2. Ensure all kubelets' credentials conform to the group/username requirements
3. Audit apiserver logs to ensure the `Node` authorizer is not rejecting requests from kubelets (no persistent `NODE DENY` messages logged)
4. Delete the `system:node` cluster role binding
-->
### RBAC 节点权限
<!--
### RBAC Node Permissions
-->
在 1.6 版本中,当使用 [RBAC 鉴权模式](/zh/docs/reference/access-authn-authz/rbac/) 时,`system:nodes` 集群角色会被自动绑定到 `system:node` 组。
<!--
In 1.6, the `system:node` cluster role was automatically bound to the `system:nodes` group when using the [RBAC Authorization mode](/docs/reference/access-authn-authz/rbac/).
-->
在 1.7 版本中,不再推荐将 `system:nodes` 组自动绑定到 `system:node` 角色,因为节点鉴权器通过对 secret 和 configmap 访问的额外限制完成了相同的任务。
如果同时启用了 `Node``RBAC` 授权模式,1.7 版本则不会创建 `system:nodes` 组到 `system:node` 角色的自动绑定。
<!--
In 1.7, the automatic binding of the `system:nodes` group to the `system:node` role is deprecated
because the node authorizer accomplishes the same purpose with the benefit of additional restrictions
on secret and configmap access. If the `Node` and `RBAC` authorization modes are both enabled,
the automatic binding of the `system:nodes` group to the `system:node` role is not created in 1.7.
-->
在 1.8 版本中,绑定将根本不会被创建。
<!--
In 1.8, the binding will not be created at all.
-->
使用 RBAC 时,将继续创建 `system:node` 集群角色,以便与将其他用户或组绑定到该角色的部署方法兼容。
<!--
When using RBAC, the `system:node` cluster role will continue to be created,
for compatibility with deployment methods that bind other users or groups to that role.
-->
@@ -0,0 +1,341 @@
---
title: 从 PodSecurityPolicy 映射到 Pod 安全性标准
content_type: concept
weight: 95
---
<!--
reviewers:
- tallclair
- liggitt
title: Mapping PodSecurityPolicies to Pod Security Standards
content_type: concept
weight: 95
-->
<!-- overview -->
<!--
The tables below enumerate the configuration parameters on
[PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/) objects, whether the field mutates
and/or validates pods, and how the configuration values map to the
[Pod Security Standards](/docs/concepts/security/pod-security-standards/).
-->
下面的表格列举了[PodSecurityPolicy](/zh/docs/concepts/policy/pod-security-policy/)
对象上的配置参数,这些字段是否会变更或检查 Pod 配置,以及这些配置值如何映射到
[Pod 安全性标准(Pod Security Standards](/zh/docs/concepts/security/pod-security-standards/)
之上。
<!--
For each applicable parameter, the allowed values for the
[Baseline](/docs/concepts/security/pod-security-standards/#baseline) and
[Restricted](/docs/concepts/security/pod-security-standards/#restricted) profiles are listed.
Anything outside the allowed values for those profiles would fall under the
[Privileged](/docs/concepts/security/pod-security-standards/#privileged) profile. "No opinion"
means all values are allowed under all Pod Security Standards.
-->
对于每个可应用的参数,表格中给出了
[Baseline](/zh/docs/concepts/security/pod-security-standards/#baseline) 和
[Restricted](/zh/docs/concepts/security/pod-security-standards/#restricted)
配置下可接受的取值。
对这两种配置而言不可接受的取值均归入
[Privileged](/zh/docs/concepts/security/pod-security-standards/#privileged)
配置下。“无意见”意味着对所有 Pod 安全性标准而言所有取值都可接受。
<!--
For a step-by-step migration guide, see
[Migrate from PodSecurityPolicy to the Built-In PodSecurity Admission Controller](/docs/tasks/configure-pod-container/migrate-from-psp/).
-->
如果想要了解如何一步步完成迁移,可参阅
[从 PodSecurityPolicy 迁移到内置的 PodSecurity 准入控制器](/zh/docs/tasks/configure-pod-container/migrate-from-psp/)。
<!-- body -->
<!--
## PodSecurityPolicy Spec
-->
## PodSecurityPolicy 规约 {#podsecuritypolicy-spec}
<!--
The fields enumerated in this table are part of the `PodSecurityPolicySpec`, which is specified
under the `.spec` field path.
-->
下面表格中所列举的字段是 `PodSecurityPolicySpec` 的一部分,是通过 `.spec`
字段路径来设置的。
<table class="no-word-break">
<caption style="display:none"><!--Mapping PodSecurityPolicySpec fields to Pod Security Standards-->从 PodSecurityPolicySpec 字段映射到 Pod Security 标准</caption>
<tbody>
<tr>
<th><code>PodSecurityPolicySpec</code></th>
<th><!-- Type -->类型</th>
<th><!--Pod Security Standards Equivalent-->Pod 安全性标准中对应设置</th>
</tr>
<tr>
<td><code>privileged</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b>: <code>false</code> / 未定义 / nil</td>
</tr>
<tr>
<td><code>defaultAddCapabilities</code></td>
<td><!-- Mutating & Validating -->更改性质 & 检查性质</td>
<td><!--Requirements match <code>allowedCapabilities</code> below.-->需求满足下面的 <code>allallowedCapabilities</code></td>
</tr>
<tr>
<td><code>allowedCapabilities</code></td>
<td><!-- Validating -->检查性质</td>
<td>
<!-- p><b>Baseline</b>: subset of</p -->
<p><b>Baseline</b>:下面各项的子集</p>
<ul>
<li><code>AUDIT_WRITE</code></li>
<li><code>CHOWN</code></li>
<li><code>DAC_OVERRIDE</code></li>
<li><code>FOWNER</code></li>
<li><code>FSETID</code></li>
<li><code>KILL</code></li>
<li><code>MKNOD</code></li>
<li><code>NET_BIND_SERVICE</code></li>
<li><code>SETFCAP</code></li>
<li><code>SETGID</code></li>
<li><code>SETPCAP</code></li>
<li><code>SETUID</code></li>
<li><code>SYS_CHROOT</code></li>
</ul>
<!-- p><b>Restricted</b>: empty / undefined / nil OR a list containing <i>only</i> <code>NET_BIND_SERVICE</code -->
<p><b>Restricted</b>:空 / 未定义 / nil 或<i>仅</i>包含 <code>NET_BIND_SERVICE</code> 的列表</p>
</td>
</tr>
<tr>
<td><code>requiredDropCapabilities</code></td>
<td><!--Mutating & Validating-->更改性质 & 检查性质</td>
<td>
<p><b>Baseline</b><!-- : no opinion-->:无意见</p>
<p><b>Restricted</b><!-- : must include-->:必须包含 <code>ALL</code></p>
</td>
</tr>
<tr>
<td><code>volumes</code></td>
<td><!-- Validating -->检查性质</td>
<td>
<p><b>Baseline</b><!--: anything except -->除下列取值之外的任何值</p>
<ul>
<li><code>hostPath</code></li>
<li><code>*</code></li>
</ul>
<p><b>Restricted</b><!-- : subset of-->:下列取值的子集</p>
<ul>
<li><code>configMap</code></li>
<li><code>csi</code></li>
<li><code>downwardAPI</code></li>
<li><code>emptyDir</code></li>
<li><code>ephemeral</code></li>
<li><code>persistentVolumeClaim</code></li>
<li><code>projected</code></li>
<li><code>secret</code></li>
</ul>
</td>
</tr>
<tr>
<td><code>hostNetwork</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b><code>false</code> / 未定义 / nil</td>
</tr>
<tr>
<td><code>hostPorts</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b>:未定义 / nil / 空</td>
</tr>
<tr>
<td><code>hostPID</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b><code>false</code> / 未定义 / nil</td>
</tr>
<tr>
<td><code>hostIPC</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b><code>false</code> / 未定义 / nil</td>
</tr>
<tr>
<td><code>seLinux</code></td>
<td><!-- Mutating & Validating -->更改性质 & 检查性质</td>
<td>
<p><b>Baseline & Restricted</b>
<!-- code>seLinux.rule</code> is <code>MustRunAs</code>, with the following <code>options</code-->
<code>seLinux.rule</code> 为 <code>MustRunAs</code>,且 <code>options</code> 如下:
</p>
<ul>
<!--
<li><code>user</code> is unset (<code>""</code> / undefined / nil)</li>
<li><code>role</code> is unset (<code>""</code> / undefined / nil)</li>
<li><code>type</code> is unset or one of: <code>container_t, container_init_t, container_kvm_t</code></li>
<li><code>level</code> is anything</li>
-->
<li><code>user</code> 未设置(<code>""</code> / 未定义 / nil</li>
<li><code>role</code> 未设置(<code>""</code> / 未定义 / nil</li>
<li><code>type</code> 未设置或者取值为 <code>container_t</code>、<code>container_init_t</code> 或 <code>container_kvm_t</code> 之一</li>
<li><code>level</code> 是任何取值</li>
</ul>
</td>
</tr>
<tr>
<td><code>runAsUser</code></td>
<td><!-- Mutating & Validating -->变更性质 & 检查性质</td>
<td>
<p><b>Baseline</b><!-- : Anything -->:任何取值</p>
<p><b>Restricted</b><!-- : <code>rule</code> is <code>MustRunAsNonRoot</code --><code>rule</code> 是 <code>MustRunAsNonRoot</code></p>
</td>
</tr>
<tr>
<td><code>runAsGroup</code></td>
<td><!-- Mutating (MustRunAs) & Validating-->变更性质(MustRunAs& 检查性质</td>
<td>
<i><!-- No opinion -->无意见</i>
</td>
</tr>
<tr>
<td><code>supplementalGroups</code></td>
<td><!-- Mutating & Validating -->变更性质 & 检查性质</td>
<td>
<i><!-- No opinion -->无意见</i>
</td>
</tr>
<tr>
<td><code>fsGroup</code></td>
<td><!-- Mutating & Validating -->变更性质 & 验证性质</td>
<td>
<i><!-- No opinion -->无意见</i>
</td>
</tr>
<tr>
<td><code>readOnlyRootFilesystem</code></td>
<td><!-- Mutating & Validating -->变更性质 & 检查性质</td>
<td>
<i><!-- No opinion -->无意见</i>
</td>
</tr>
<tr>
<td><code>defaultAllowPrivilegeEscalation</code></td>
<td><!-- Mutating -->变更性质</td>
<td>
<i><!-- No opinion (non-validating) -->无意见(非变更性质)</i>
</td>
</tr>
<tr>
<td><code>allowPrivilegeEscalation</code></td>
<td><!-- Mutating & Validating -->变更性质 & 检查性质</td>
<td>
<!--
<p><i>Only mutating if set to <code>false</code></i></p>
<p><b>Baseline</b>: No opinion</p>
<p><b>Restricted</b>: <code>false</code></p>
-->
<p><i>只有设置为 <code>false</code> 时才执行变更动作</i></p>
<p><b>Baseline</b>:无意见</p>
<p><b>Restricted</b><code>false</code></p>
</td>
</tr>
<tr>
<td><code>allowedHostPaths</code></td>
<td><!-- Validating -->检查性质</td>
<td><i><!-- No opinion (volumes takes precedence)-->无意见(volumes 优先)</i></td>
</tr>
<tr>
<td><code>allowedFlexVolumes</code></td>
<td><!-- Validating -->检查性质</td>
<td><i><!-- No opinion (volumes takes precedence)-->无意见(volumes 优先)</i></td>
</tr>
<tr>
<td><code>allowedCSIDrivers</code></td>
<td><!-- Validating -->检查性质</td>
<td><i><!-- No opinion (volumes takes precedence) -->无意见(volumes 优先)</i></td>
</tr>
<tr>
<td><code>allowedUnsafeSysctls</code></td>
<td><!-- Validating -->检查性质</td>
<td><b>Baseline & Restricted</b>:未定义 / nil / 空</td>
</tr>
<tr>
<td><code>forbiddenSysctls</code></td>
<td><!-- Validating -->检查性质</td>
<td><i><!-- No opinion -->无意见</i></td>
</tr>
<tr>
<td><code>allowedProcMountTypes</code><br><i>(alpha feature)</i></td>
<td><!-- Validating -->检查性质</td>
<!-- td><b>Baseline & Restricted</b>: <code>["Default"]</code> OR undefined / nil / empty</td -->
<td><b>Baseline & Restricted</b><code>["Default"]</code> 或者未定义 / nil / 空</td>
</tr>
<tr>
<td><code>runtimeClass</code><br><code>&nbsp;.defaultRuntimeClassName</code></td>
<td><!-- Mutating -->变更性质</td>
<td><i><!-- No opinion -->无意见</i></td>
</tr>
<tr>
<td><code>runtimeClass</code><br><code>&nbsp;.allowedRuntimeClassNames</code></td>
<td><!-- Validating -->检查性质</td>
<td><i><!-- No opinion -->无意见</i></td>
</tr>
</tbody>
</table>
<!--
## PodSecurityPolicy annotations
-->
## PodSecurityPolicy 注解 {#podsecuritypolicy-annotations}
<!--
The [annotations](/docs/concepts/overview/working-with-objects/annotations/) enumerated in this
table can be specified under `.metadata.annotations` on the PodSecurityPolicy object.
-->
下面表格中所列举的[注解](/zh/docs/concepts/overview/working-with-objects/annotations/)
可以通过 `.metadata.annotations` 设置到 PodSecurityPolicy 对象之上。
<table class="no-word-break">
<caption style="display:none"><!-- Mapping PodSecurityPolicy annotations to Pod Security Standards-->将 PodSecurityPolicy 注解映射到 Pod 安全性标准</caption>
<tbody>
<tr>
<th><code><!--PSP Annotation-->PSP 注解</code></th>
<th><!-- Type -->类型</th>
<th><!-- Pod Security Standards Equivalent-->Pod 安全性标准中对应设置</th>
</tr>
<tr>
<td><code>seccomp.security.alpha.kubernetes.io</code><br><code>/defaultProfileName</code></td>
<td><!-- Mutating -->变更性质</td>
<td><i><!-- No opinion -->无意见</i></td>
</tr>
<tr>
<td><code>seccomp.security.alpha.kubernetes.io</code><br><code>/allowedProfileNames</code></td>
<td><!-- Validating -->检查性质</td>
<td>
<!--
<p><b>Baseline</b>: <code>"runtime/default,"</code> <i>(Trailing comma to allow unset)</i></p>
<p><b>Restricted</b>: <code>"runtime/default"</code> <i>(No trailing comma)</i></p>
<p><i><code>localhost/*</code> values are also permitted for both Baseline & Restricted.</i></p>
-->
<p><b>Baseline</b><code>"runtime/default,"</code> <i>(其中尾部的逗号允许取消设置)</i></p>
<p><b>Restricted</b><code>"runtime/default"</code> <i>(没有尾部逗号)</i></p>
<p><i><code>localhost/*</code> 取值对于 Baseline 和 Restricted 都是可接受的</i></p>
</td>
</tr>
<tr>
<td><code>apparmor.security.beta.kubernetes.io</code><br><code>/defaultProfileName</code></td>
<td><!-- Mutating -->变更性质</td>
<td><i><!-- No opinion -->无意见</i></td>
</tr>
<tr>
<td><code>apparmor.security.beta.kubernetes.io</code><br><code>/allowedProfileNames</code></td>
<td><!-- Validating -->检查性质</td>
<td>
<!--
<p><b>Baseline</b>: <code>"runtime/default,"</code> <i>(Trailing comma to allow unset)</i></p>
<p><b>Restricted</b>: <code>"runtime/default"</code> <i>(No trailing comma)</i></p>
<p><i><code>localhost/*</code> values are also permitted for both Baseline & Restricted.</i></p>
-->
<p><b>Baseline</b><code>"runtime/default,"</code> <i>(其中尾部的逗号允许取消设置)</i></p>
<p><b>Restricted</b><code>"runtime/default"</code> <i>(没有尾部逗号)</i></p>
<p><i><code>localhost/*</code> 取值对于 Baseline 和 Restricted 都是可接受的</i></p>
</td>
</tr>
</tbody>
</table>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,277 @@
---
title: 管理服务账号
content_type: concept
weight: 50
---
<!--
reviewers:
- bprashanth
- davidopp
- lavalamp
- liggitt
title: Managing Service Accounts
content_type: concept
weight: 50
-->
<!-- overview -->
<!--
This is a Cluster Administrator guide to service accounts. You should be familiar with
[configuring Kubernetes service accounts](/docs/tasks/configure-pod-container/configure-service-account/).
Support for authorization and user accounts is planned but incomplete. Sometimes
incomplete features are referred to in order to better describe service accounts.
-->
这是一篇针对服务账号的集群管理员指南。你应该熟悉
[配置 Kubernetes 服务账号](/zh/docs/tasks/configure-pod-container/configure-service-account/)。
对鉴权和用户账号的支持已在规划中,当前并不完备。
为了更好地描述服务账号,有时这些不完善的特性也会被提及。
<!-- body -->
<!--
## User accounts versus service accounts
Kubernetes distinguishes between the concept of a user account and a service account
for a number of reasons:
-->
## 用户账号与服务账号 {#user-accounts-versus-service-accounts}
Kubernetes 区分用户账号和服务账号的概念,主要基于以下原因:
<!--
- User accounts are for humans. Service accounts are for processes, which run
in pods.
- User accounts are intended to be global. Names must be unique across all
namespaces of a cluster. Service accounts are namespaced.
- Typically, a cluster's user accounts might be synced from a corporate
database, where new user account creation requires special privileges and is
tied to complex business processes. Service account creation is intended to be
more lightweight, allowing cluster users to create service accounts for
specific tasks by following the principle of least privilege.
- Auditing considerations for humans and service accounts may differ.
- A config bundle for a complex system may include definition of various service
accounts for components of that system. Because service accounts can be created
without many constraints and have namespaced names, such config is portable.
-->
- 用户账号是针对人而言的。 服务账号是针对运行在 Pod 中的进程而言的。
- 用户账号是全局性的。其名称跨集群中名字空间唯一的。服务账号是名字空间作用域的。
- 通常情况下,集群的用户账号可能会从企业数据库进行同步,其创建需要特殊权限,
并且涉及到复杂的业务流程。
服务账号创建有意做得更轻量,允许集群用户为了具体的任务创建服务账号
以遵从权限最小化原则。
- 对人员和服务账号审计所考虑的因素可能不同。
- 针对复杂系统的配置包可能包含系统组件相关的各种服务账号的定义。因为服务账号
的创建约束不多并且有名字空间域的名称,这种配置是很轻量的。
<!--
## Service account automation
Three separate components cooperate to implement the automation around service accounts:
- A `ServiceAccount` admission controller
- A Token controller
- A `ServiceAccount` controller
-->
## 服务账号的自动化 {#service-account-automation}
三个独立组件协作完成服务账号相关的自动化:
- `ServiceAccount` 准入控制器
- Token 控制器
- `ServiceAccount` 控制器
<!--
### ServiceAccount Admission Controller
The modification of pods is implemented via a plugin
called an [Admission Controller](/docs/reference/access-authn-authz/admission-controllers/).
It is part of the API server.
It acts synchronously to modify pods as they are created or updated. When this plugin is active
(and it is by default on most distributions), then it does the following when a pod is created or modified:
-->
### ServiceAccount 准入控制器 {#serviceaccount-admission-controller}
对 Pod 的改动通过一个被称为
[准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/)
的插件来实现。它是 API 服务器的一部分。
当 Pod 被创建或更新时,它会同步地修改 Pod。
如果该插件处于激活状态(在大多数发行版中都是默认激活的),当 Pod 被创建
或更新时它会进行以下操作:
<!--
1. If the pod does not have a `ServiceAccount` set, it sets the `ServiceAccount` to `default`.
1. It ensures that the `ServiceAccount` referenced by the pod exists, and otherwise rejects it.
1. It adds a `volume` to the pod which contains a token for API access
if neither the ServiceAccount `automountServiceAccountToken` nor the Pod's
`automountServiceAccountToken` is set to `false`.
1. It adds a `volumeSource` to each container of the pod mounted at
`/var/run/secrets/kubernetes.io/serviceaccount`, if the previous step has
created a volume for ServiceAccount token.
1. If the pod does not contain any `ImagePullSecrets`, then `ImagePullSecrets` of the `ServiceAccount` are added to the pod.
-->
1. 如果该 Pod 没有设置 `ServiceAccount`,将其 `ServiceAccount` 设为 `default`
1. 保证 Pod 所引用的 `ServiceAccount` 确实存在,否则拒绝该 Pod。
1. 如果服务账号的 `automountServiceAccountToken` 或 Pod 的
`automountServiceAccountToken` 都未显式设置为 `false`,则为 Pod 创建一个
`volume`,在其中包含用来访问 API 的令牌。
1. 如果前一步中为服务账号令牌创建了卷,则为 Pod 中的每个容器添加一个
`volumeSource`,挂载在其 `/var/run/secrets/kubernetes.io/serviceaccount`
目录下。
1. 如果 Pod 不包含 `imagePullSecrets` 设置,将 `ServiceAccount` 所引用
的服务账号中的 `imagePullSecrets` 信息添加到 Pod 中。
<!--
#### Bound Service Account Token Volume
-->
#### 绑定的服务账号令牌卷 {#bound-service-account-token-volume}
{{< feature-state for_k8s_version="v1.22" state="stable" >}}
<!--
The ServiceAccount admission controller will add the following projected volume instead of a Secret-based volume for the non-expiring service account token created by Token Controller.
-->
ServiceAccount 准入控制器将添加如下投射卷,而不是为令牌控制器
所生成的不过期的服务账号令牌而创建的基于 Secret 的卷。
```yaml
- name: kube-api-access-<随机后缀>
projected:
defaultMode: 420 # 0644
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
```
<!--
This projected volume consists of three sources:
1. A ServiceAccountToken acquired from kube-apiserver via TokenRequest API. It will expire after 1 hour by default or when the pod is deleted. It is bound to the pod and has kube-apiserver as the audience.
1. A ConfigMap containing a CA bundle used for verifying connections to the kube-apiserver. This feature depends on the `RootCAConfigMap` feature gate, which publishes a "kube-root-ca.crt" ConfigMap to every namespace. `RootCAConfigMap` feature gate is graduated to GA in 1.21 and default to true. (This feature will be removed from --feature-gate arg in 1.22).
1. A DownwardAPI that references the namespace of the pod.
-->
此投射卷有三个数据源:
1. 通过 TokenRequest API 从 kube-apiserver 处获得的 ServiceAccountToken。
这一令牌默认会在一个小时之后或者 Pod 被删除时过期。
该令牌绑定到 Pod 实例上,并将 kube-apiserver 作为其受众(audience)。
1. 包含用来验证与 kube-apiserver 连接的 CA 证书包的 ConfigMap 对象。
这一特性依赖于 `RootCAConfigMap` 特性门控。该特性被启用时,
控制面会公开一个名为 `kube-root-ca.crt` 的 ConfigMap 给所有名字空间。
`RootCAConfigMap` 在 1.21 版本中进入 GA 状态,默认被启用,
该特性门控会在 1.22 版本中从 `--feature-gate` 参数中删除。
1. 引用 Pod 名字空间的一个 DownwardAPI。
<!--
See more details about [projected volumes](/docs/tasks/configure-pod-container/configure-projected-volume-storage/).
-->
参阅[投射卷](/zh/docs/tasks/configure-pod-container/configure-projected-volume-storage/)
了解进一步的细节。
<!--
### Token Controller
TokenController runs as part of `kube-controller-manager`. It acts asynchronously. It:
- watches ServiceAccount creation and creates a corresponding
ServiceAccount token Secret to allow API access.
- watches ServiceAccount deletion and deletes all corresponding ServiceAccount
token Secrets.
- watches ServiceAccount token Secret addition, and ensures the referenced
ServiceAccount exists, and adds a token to the Secret if needed.
- watches Secret deletion and removes a reference from the corresponding
ServiceAccount if needed.
-->
### Token 控制器 {#token-controller}
TokenController 作为 `kube-controller-manager` 的一部分运行,以异步的形式工作。
其职责包括:
- 监测 ServiceAccount 的创建并创建相应的服务账号令牌 Secret 以允许访问 API。
- 监测 ServiceAccount 的删除并删除所有相应的服务账号令牌 Secret。
- 监测服务账号令牌 Secret 的添加,保证相应的 ServiceAccount 存在,如有需要,
向 Secret 中添加令牌。
- 监测服务账号令牌 Secret 的删除,如有需要,从相应的 ServiceAccount 中移除引用。
<!--
You must pass a service account private key file to the token controller in
the `kube-controller-manager` using the `--service-account-private-key-file`
flag. The private key is used to sign generated service account tokens.
Similarly, you must pass the corresponding public key to the `kube-apiserver`
using the `--service-account-key-file` flag. The public key will be used to
verify the tokens during authentication.
-->
你必须通过 `--service-account-private-key-file` 标志为 `kube-controller-manager`
的令牌控制器传入一个服务账号私钥文件。该私钥用于为所生成的服务账号令牌签名。
同样地,你需要通过 `--service-account-key-file` 标志将对应的公钥通知给
kube-apiserver。公钥用于在身份认证过程中校验令牌。
<!--
#### To create additional API tokens
A controller loop ensures a Secret with an API token exists for each
ServiceAccount. To create additional API tokens for a ServiceAccount, create a
Secret of type `kubernetes.io/service-account-token` with an annotation
referencing the ServiceAccount, and the controller will update it with a
generated token:
Below is a sample configuration for such a Secret:
-->
#### 创建额外的 API 令牌 {#to-create-additional-api-tokens}
控制器中有专门的循环来保证每个 ServiceAccount 都存在对应的包含 API 令牌的 Secret。
当需要为 ServiceAccount 创建额外的 API 令牌时,可以创建一个类型为
`kubernetes.io/service-account-token` 的 Secret,并在其注解中引用对应的
ServiceAccount。控制器会生成令牌并更新该 Secret:
下面是这种 Secret 的一个示例配置:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecretname
annotations:
kubernetes.io/service-account.name: myserviceaccount
type: kubernetes.io/service-account-token
```
```shell
kubectl create -f ./secret.json
kubectl describe secret mysecretname
```
<!--
#### To delete/invalidate a ServiceAccount token Secret
-->
#### 删除/废止服务账号令牌 Secret
```shell
kubectl delete secret mysecretname
```
<!--
### ServiceAccount controller
A ServiceAccount controller manages the ServiceAccounts inside namespaces, and
ensures a ServiceAccount named "default" exists in every active namespace.
-->
### 服务账号控制器 {#serviceaccount-controller}
服务账号控制器管理各名字空间下的 ServiceAccount 对象,并且保证每个活跃的
名字空间下存在一个名为 "default" 的 ServiceAccount。
@@ -0,0 +1,271 @@
---
title: Webhook 模式
content_type: concept
weight: 95
---
<!--
reviewers:
- erictune
- lavalamp
- deads2k
- liggitt
title: Webhook Mode
content_type: concept
weight: 95
-->
<!-- overview -->
<!--
A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen.
-->
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL。
<!-- body -->
<!--
When specified, mode `Webhook` causes Kubernetes to query an outside REST
service when determining user privileges.
-->
具体来说,当在判断用户权限时,`Webhook` 模式会使 Kubernetes 查询外部的 REST 服务。
<!--
## Configuration File Format
-->
## 配置文件格式 {#configuration-file-format}
<!--
Mode `Webhook` requires a file for HTTP configuration, specify by the
`--authorization-webhook-config-file=SOME_FILENAME` flag.
-->
`Webhook` 模式需要一个 HTTP 配置文件,通过 `--authorization-webhook-config-file=SOME_FILENAME` 的参数声明。
<!--
The configuration file uses the [kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
file format. Within the file "users" refers to the API Server webhook and
"clusters" refers to the remote service.
-->
配置文件的格式使用 [kubeconfig](/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)。
在该文件中,“users” 代表着 API 服务器的 webhook,而 “cluster” 代表着远程服务。
<!--
A configuration example which uses HTTPS client auth:
-->
使用 HTTPS 客户端认证的配置例子:
<!--
```yaml
# Kubernetes API version
apiVersion: v1
# kind of the API object
kind: Config
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authz-service
cluster:
# CA for verifying the remote service.
certificate-authority: /path/to/ca.pem
# URL of remote service to query. Must use 'https'. May not include parameters.
server: https://authz.example.com/authorize
# users refers to the API Server's webhook configuration.
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
client-key: /path/to/key.pem # key matching the cert
# kubeconfig files require a context. Provide one for the API Server.
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authz-service
user: name-of-api-server
name: webhook
```
-->
```yaml
# Kubernetes API 版本
apiVersion: v1
# API 对象种类
kind: Config
# clusters 代表远程服务。
clusters:
- name: name-of-remote-authz-service
cluster:
# 对远程服务进行身份认证的 CA。
certificate-authority: /path/to/ca.pem
# 远程服务的查询 URL。必须使用 'https'。
server: https://authz.example.com/authorize
# users 代表 API 服务器的 webhook 配置
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # webhook plugin 使用 cert
client-key: /path/to/key.pem # cert 所对应的 key
# kubeconfig 文件必须有 context。需要提供一个给 API 服务器。
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authz-service
user: name-of-api-server
name: webhook
```
<!--
## Request Payloads
-->
## 请求载荷 {#request-payloads}
<!--
When faced with an authorization decision, the API Server POSTs a JSON-
serialized `authorization.k8s.io/v1beta1` `SubjectAccessReview` object describing the
action. This object contains fields describing the user attempting to make the
request, and either details about the resource being accessed or requests
attributes.
-->
在做认证决策时,API 服务器会 POST 一个 JSON 序列化的 `authorization.k8s.io/v1beta1` `SubjectAccessReview`
对象来描述这个动作。这个对象包含了描述用户请求的字段,同时也包含了需要被访问资源或请求特征的具体信息。
<!--
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/)
as other Kubernetes API objects. Implementers should be aware of looser
compatibility promises for beta objects and check the "apiVersion" field of the
request to ensure correct deserialization. Additionally, the API Server must
enable the `authorization.k8s.io/v1beta1` API extensions group (`--runtime-config=authorization.k8s.io/v1beta1=true`).
-->
需要注意的是 webhook API 对象与其他 Kubernetes API 对象一样都同样都遵从[版本兼容规则](/zh/docs/concepts/overview/kubernetes-api/)。
实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段能被正确地反序列化。
此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组 (`--runtime-config=authorization.k8s.io/v1beta1=true`)。
<!--
An example request body:
-->
一个请求内容的例子:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "kittensandponies",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
```
<!--
The remote service is expected to fill the `status` field of
the request and respond to either allow or disallow access. The response body's
`spec` field is ignored and may be omitted. A permissive response would return:
-->
期待远程服务填充请求的 `status` 字段并响应允许或禁止访问。响应主体的 `spec` 字段被忽略,可以省略。允许的响应将返回:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": true
}
}
```
<!--
For disallowing access there are two methods.
-->
为了禁止访问,有两种方法。
<!--
The first method is preferred in most cases, and indicates the authorization
webhook does not allow, or has "no opinion" about the request, but if other
authorizers are configured, they are given a chance to allow the request.
If there are no other authorizers, or none of them allow the request, the
request is forbidden. The webhook would return:
-->
在大多数情况下,第一种方法是首选方法,它指示授权 webhook 不允许或对请求 “无意见”。
但是,如果配置了其他授权者,则可以给他们机会允许请求。如果没有其他授权者,或者没有一个授权者,则该请求被禁止。webhook 将返回:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"reason": "user does not have read access to the namespace"
}
}
```
<!--
The second method denies immediately, short-circuiting evaluation by other
configured authorizers. This should only be used by webhooks that have
detailed knowledge of the full authorizer configuration of the cluster.
The webhook would return:
-->
第二种方法立即拒绝其他配置的授权者进行短路评估。仅应由对集群的完整授权者配置有详细了解的 webhook 使用。webhook 将返回:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"denied": true,
"reason": "user does not have read access to the namespace"
}
}
```
<!--
Access to non-resource paths are sent as:
-->
对于非资源的路径访问是这么发送的:
```json
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"nonResourceAttributes": {
"path": "/debug",
"verb": "get"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
```
<!--
Non-resource paths include: `/api`, `/apis`, `/metrics`,
`/logs`, `/debug`, `/healthz`, `/livez`, `/openapi/v2`, `/readyz`, and
`/version.` Clients require access to `/api`, `/api/*`, `/apis`, `/apis/*`,
and `/version` to discover what resources and versions are present on the server.
Access to other non-resource paths can be disallowed without restricting access
to the REST api.
-->
非资源类的路径包括:`/api``/apis``/metrics``/logs``/debug`
`/healthz``/livez``/openapi/v2``/readyz`、和 `/version`
客户端需要访问 `/api``/api/*``/apis``/apis/*``/version` 以便
能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST API 访问限制的情况下拒绝。
<!--
For further documentation refer to the authorization.v1beta1 API objects and
[webhook.go](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
-->
更多信息可以参考 authorization.v1beta1 API 对象和 [webhook.go](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go)。