diff --git a/content/zh/docs/reference/access-authn-authz/authentication.md b/content/zh/docs/reference/access-authn-authz/authentication.md index 4c01f7c08e..030a628860 100644 --- a/content/zh/docs/reference/access-authn-authz/authentication.md +++ b/content/zh/docs/reference/access-authn-authz/authentication.md @@ -66,7 +66,7 @@ for more details about this. 使用证书中的 'subject' 的通用名称(Common Name)字段(例如,"/CN=bob")来 确定用户名。接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。进一步的细节可参阅 -[证书请求](/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user) +[证书请求](/zh/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user) 下普通用户主题。 -### Static Password File - -通过向 API 服务器传递 `--basic-auth-file=SOMEFILE` 选项可以启用基本的 -身份认证。目前,基本身份认证所涉及的凭据信息会长期有效,并且在不重启 API -服务器的情况下无法改变用户的密码。 -要注意的是,对基本身份认证的支持目前仅是出于方便性考虑。 -与此同时我们正在增强前述的、更为安全的模式的易用性。 - - -基本身份认证数据文件是一个 CSV 文件,包含至少 3 列:密码、用户名和用户 ID。 -在 Kuernetes 1.6 及后续版本中,你可以指定一个可选的第 4 列,在其中给出用逗号 -分隔的用户组名。如果用户组名不止一个,你必须将第 4 列的值用双引号括起来。 -参见下面的例子: - -```conf -password,user,uid,"group1,group2,group3" -``` - - -当在 HTTP 客户端使用基本身份认证机制时,API 服务器会期望看到名为 -`Authorization` 的 HTTP 头部,其值形如 `Basic USER:PASSWORD的Base64编码字符串` - ### 服务账号令牌 {#service-account-tokens} @@ -555,7 +516,33 @@ is included in a request. 中的 `id_token`(而非 `access_token`)作为持有者令牌。 关于如何在请求中设置令牌,可参见[前文](#putting-a-bearer-token-in-a-request)。 -![Kubernetes OpenID Connect Flow](/images/docs/admin/k8s_oidc_login.svg) +{{< mermaid >}} +sequenceDiagram + participant user as 用户 + participant idp as 身份提供者 + participant kube as Kubectl + participant api as API 服务器 + + user ->> idp: 1. 登录到 IdP + activate idp + idp -->> user: 2. 提供 access_token,
id_token, 和 refresh_token + deactivate idp + activate user + user ->> kube: 3. 调用 Kubectl 并
设置 --token 为 id_token
或者将令牌添加到 .kube/config + deactivate user + activate kube + kube ->> api: 4. Authorization: Bearer... + deactivate kube + activate api + api ->> api: 5. JWT 签名合法么? + api ->> api: 6. JWT 是否已过期?(iat+exp) + api ->> api: 7. 用户被授权了么? + api -->> kube: 8. 已授权:执行
操作并返回结果 + deactivate api + activate kube + kube --x user: 9. 返回结果 + deactivate kube +{{< /mermaid >}} 关于上述第三条需求,即要求具备 CA 签名的证书,有一些额外的注意事项。 @@ -691,8 +678,11 @@ Or you can use [this similar script](https://raw.githubusercontent.com/TremoloSe 你必须对身份服务的 Web 服务器证书进行签名,签名所用证书的 `CA` 标志要设置为 `TRUE`,即使用的是自签名证书。这是因为 GoLang 的 TLS 客户端实现对证书验证 标准方面有非常严格的要求。如果你手头没有现成的 CA 证书,可以使用 CoreOS -团队所开发的[这个脚本](https://github.com/coreos/dex/blob/1ee5920c54f5926d6468d2607c728b71cfe98092/examples/k8s/gencert.sh)来创建一个简单的 CA 和被签了名的证书与密钥对。 -或者你也可以使用[这个类似的脚本](https://raw.githubusercontent.com/TremoloSecurity/openunison-qs-kubernetes/master/src/main/bash/makessl.sh),生成一个合法期更长、密钥尺寸更大的 SHA256 证书。 +团队所开发的[这个脚本](https://github.com/dexidp/dex/blob/master/examples/k8s/gencert.sh) +来创建一个简单的 CA 和被签了名的证书与密钥对。 +或者你也可以使用 +[这个类似的脚本](https://raw.githubusercontent.com/TremoloSecurity/openunison-qs-kubernetes/master/src/main/bash/makessl.sh), +生成一个合法期更长、密钥尺寸更大的 SHA256 证书。 -title: 授权概述 +title: Authorization Overview content_type: concept weight: 60 ---- +--> - -了解有关 Kubernetes 授权的更多信息,包括使用支持的授权模块创建策略的详细信息。 + +了解有关 Kubernetes 鉴权的更多信息,包括使用支持的鉴权模块创建策略的详细信息。 - +the Kubernetes API. +--> +在 Kubernetes 中,你必须在鉴权(授予访问权限)之前进行身份验证(登录),有关身份验证的信息, +请参阅[访问控制概述](/zh/docs/concepts/security/controlling-access/). -在 Kubernetes 中,您必须在授权(授予访问权限)之前进行身份验证(登录),有关身份验证的信息, -请参阅 [访问控制概述](/zh/docs/reference/access-authn-authz/controlling-access/). - -Kubernetes 期望 REST API 请求中常见的属性。 -这意味着 Kubernetes 授权适用于现有的组织范围或云提供商范围的访问控制系统, +Kubernetes 期望请求中存在 REST API 常见的属性。 +这意味着 Kubernetes 鉴权适用于现有的组织范围或云提供商范围的访问控制系统, 除了 Kubernetes API 之外,它还可以处理其他 API。 - - +the request, then the request is denied. A deny returns an HTTP status code 403. +--> ## 确定是允许还是拒绝请求 -Kubernetes 使用 API ​​服务器授权 API 请求。它根据所有策略评估所有请求属性来决定允许或拒绝请求。 -一个 API 请求的所有部分必须被某些策略允许才能继续。这意味着默认情况下拒绝权限。 -(尽管 Kubernetes 使用 API ​​服务器,但是依赖于特定种类对象的特定字段的访问控制和策略由准入控制器处理。) +Kubernetes 使用 API 服务器对 API 请求进行鉴权。 +它根据所有策略评估所有请求属性来决定允许或拒绝请求。 +一个 API 请求的所有部分都必须被某些策略允许才能继续。 +这意味着默认情况下拒绝权限。 -配置多个授权模块时,将按顺序检查每个模块。 -如果任何授权模块批准或拒绝请求,则立即返回该决定,并且不会与其他授权模块协商。 -如果所有模块对请求没有意见,则拒绝该请求。一个拒绝响应返回 HTTP 状态代码 403 。 +(尽管 Kubernetes 使用 API 服务器,但是依赖于特定对象种类的特定字段的访问控制 +和策略由准入控制器处理。) + +当系统配置了多个鉴权模块时,Kubernetes 将按顺序使用每个模块。 +如果任何鉴权模块批准或拒绝请求,则立即返回该决定,并且不会与其他鉴权模块协商。 +如果所有模块对请求没有意见,则拒绝该请求。 +被拒绝响应返回 HTTP 状态代码 403。 +## 审查你的请求属性 -## 审查您的请求属性 Kubernetes 仅审查以下 API 请求属性: - * **user** - 身份验证期间提供的 `user` 字符串。 - * **group** - 经过身份验证的用户所属的组名列表。 - * **extra** - 由身份验证层提供的任意字符串键到字符串值的映射。 - * **API** - 指示请求是否针对 API 资源。 - * **Request path** - 各种非资源端点的路径,如 `/api` 或 `/healthz`。 - * **API request verb** - API 动词 `get`,`list`,`create`,`update`,`patch`,`watch`,`proxy`,`redirect`,`delete` 和 `deletecollection` 用于资源请求。要确定资源 API 端点的请求动词,请参阅[确定请求动词](/zh/docs/reference/access-authn-authz/authorization/#determine-whether-a-request-is-allowed-or-denied)。 - * **HTTP request verb** - HTTP 动词 `get`,`post`,`put` 和 `delete` 用于非资源请求。 - * **Resource** - 正在访问的资源的 ID 或名称(仅限资源请求) - 对于使用 `get`,`update`,`patch` 和 `delete` 动词的资源请求,您必须提供资源名称。 - * **Subresource** - 正在访问的子资源(仅限资源请求)。 - * **Namespace** - 正在访问的对象的名称空间(仅适用于命名空间资源请求)。 - * **API group** - 正在访问的 API 组(仅限资源请求)。空字符串表示[核心 API 组](/zh/docs/concepts/overview/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} + +**非资源请求** + +对于 `/api/v1/...` 或 `/apis///...` 之外的端点的请求被 +视为“非资源请求(Non-Resource Requests)”,并使用该请求的 HTTP 方法的 +小写形式作为其请求动词。 +例如,对 `/api` 或 `/healthz` 这类端点的 `GET` 请求将使用 `get` 作为其动词。 + + +**资源请求** +要确定对资源 API 端点的请求动词,需要查看所使用的 HTTP 动词以及该请求是针对 +单个资源还是一组资源: + + - -## 确定请求动词 - -要确定资源 API 端点的请求谓词,请检查所使用的 HTTP 动词以及请求是否对单个资源或资源集合起作用: - -HTTP 动词 | request 动词 +HTTP 动词 | 请求动词 ----------|--------------- POST | create -GET, HEAD | get (单个资源),list (资源集合) +GET, HEAD | get (针对单个资源)、list(针对集合) PUT | update PATCH | patch -DELETE | delete (单个资源),deletecollection (资源集合) - -Kubernetes 有时使用专门的动词检查授权以获得额外的权限。例如: - -* [Pod 安全策略](/zh/docs/concepts/policy/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` 动词的授权。 -* [认证](/zh/docs/reference/access-authn-authz/authentication/) layer 检查核心 API 组中 `users`,`groups` 和 `serviceaccounts` 的 `impersonate` 动词的授权,以及 `authentication.k8s.io` API 组中的 `userextras`。 +DELETE | delete(针对单个资源)、deletecollection(针对集合) +Kubernetes 有时使用专门的动词以对额外的权限进行鉴权。例如: + +* [PodSecurityPolicy](/zh/docs/concepts/policy/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} -## 授权模块 - * **Node** - 一个专用授权程序,根据计划运行的 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` 启动 apiserver 。 - * **Webhook** - WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST;通过 HTTP POST 进行简单的事件通知。实现 WebHook 的 Web 应用程序会在发生某些事情时将消息发布到 URL。要了解有关使用 Webhook 模式的更多信息,请参阅 [Webhook 模式](/zh/docs/reference/access-authn-authz/webhook/)。 +* **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/)。 +#### 检查 API 访问 {#checking-api-access} -#### 检查 API 访问 +`kubectl` 提供 `auth can-i` 子命令,用于快速查询 API 鉴权。 +该命令使用 `SelfSubjectAccessReview` API 来确定当前用户是否可以执行给定操作, +无论使用何种鉴权模式该命令都可以工作。 -`kubectl` 提供 `auth can-i` 子命令,用于快速查询 API 授权层。 -该命令使用 `SelfSubjectAccessReview` API 来确定当前用户是否可以执行给定操作,并且无论使用何种授权模式都可以工作。 - -```bash -$ kubectl auth can-i create deployments --namespace dev +```shell +kubectl auth can-i create deployments --namespace dev +``` +``` yes -$ kubectl auth can-i create deployments --namespace prod +``` + +```shell +kubectl auth can-i create deployments --namespace prod +``` +``` no ``` + -管理员可以将此与[用户模拟](/zh/docs/reference/access-authn-authz/authentication/#user-impersonation)结合使用,以确定其他用户可以执行的操作。 +管理员可以将此与 +[用户扮演](/zh/docs/reference/access-authn-authz/authentication/#user-impersonation) +结合使用,以确定其他用户可以执行的操作。 ```bash -$ kubectl auth can-i list secrets --namespace dev --as dave +kubectl auth can-i list secrets --namespace dev --as dave +``` +``` no ``` + +`SelfSubjectAccessReview` 是 `authorization.k8s.io` API 组的一部分,它将 API +服务器鉴权公开给外部服务。该组中的其他资源包括: -`SelfSubjectAccessReview` 是 `authorization.k8s.io` API 组的一部分,它将 API 服务器授权公开给外部服务。 -该组中的其他资源包括: +* `SubjectAccessReview` - 对任意用户的访问进行评估,而不仅仅是当前用户。 + 当鉴权决策被委派给 API 服务器时很有用。例如,kubelet 和扩展 API 服务器使用 + 它来确定用户对自己的 API 的访问权限。 +* `LocalSubjectAccessReview` - 与 `SubjectAccessReview` 类似,但仅限于特定的 + 名字空间。 +* `SelfSubjectRulesReview` - 返回用户可在名字空间内执行的操作集的审阅。 + 用户可以快速汇总自己的访问权限,或者用于 UI 中的隐藏/显示动作。 -* `SubjectAccessReview` - 访问任何用户的 Review ,而不仅仅是当前用户。用于将授权决策委派给 API 服务器。例如,kubelet 和扩展 API 服务器使用它来确定用户对自己的 API 的访问权限。 -* `LocalSubjectAccessReview` - 与 `SubjectAccessReview` 类似,但仅限于特定的命名空间。 -* `SelfSubjectRulesReview` - 返回用户可在命名空间内执行的操作集的审阅。用户可以快速汇总自己的访问权限,或者用于 UI 中的隐藏/显示动作。 - -可以通过创建普通 Kubernetes 资源来查询这些 API ,其中返回对象的响应 “status” 字段是查询的结果。 +可以通过创建普通的 Kubernetes 资源来查询这些 API,其中返回对象的响应 "status" +字段是查询的结果。 ```bash -$ kubectl create -f - -o yaml << EOF +kubectl create -f - -o yaml << EOF apiVersion: authorization.k8s.io/v1 kind: SelfSubjectAccessReview spec: @@ -212,7 +287,14 @@ spec: verb: create namespace: dev EOF +``` + +生成的 `SelfSubjectAccessReview` 为: + +```yaml apiVersion: authorization.k8s.io/v1 kind: SelfSubjectAccessReview metadata: @@ -235,32 +317,39 @@ 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` 基于属性的访问控制(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 请求 + 的鉴权时才使用此标志。 + - -## 为您的授权模块应用参数 - -您必须在策略中包含一个参数标志,以指明您的策略包含哪个授权模块: - -可以使用以下参数: - - * `--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 请求的授权时才使用此标志。 - -您可以选择多个授权模块。模块按顺序检查,以便较早的模块具有更高的优先级来允许或拒绝请求。 +你可以选择多个鉴权模块。模块按顺序检查,以便较靠前的模块具有更高的优先级来允许 +或拒绝请求。 -## 通过 Pod 创建升级权限 +## 通过创建 Pod 提升权限 -能够在命名空间中创建 Pod 的用户可能会升级其在该命名空间内的权限。 -他们可以创建在该命名空间内访问其权限的 Pod 。 -他们可以创建用户无法自己读取 secret 的 Pod ,或者在具有不同/更高权限的服务帐户下运行的 Pod 。 +能够在名字空间中创建 Pod 的用户可能会提升其在该名字空间内的权限。 +他们可以创建在该名字空间内访问其权限的 Pod。 +他们可以创建 Pod 访问用户自己无法读取的 Secret,或者在具有不同/更高权限的 +服务帐户下运行的 Pod 。 {{< caution >}} -**注意:** 系统管理员在授予对 Pod 创建的访问权限时要小心。 -授予在命名空间中创建 Pod(或创建 Pod 的控制器)的权限的用户可以: -读取命名空间中的所有 secret;读取命名空间中的所有 ConfigMap; -并模拟命名空间中的任何服务帐户并执行帐户可以执行的任何操作。 -无论采用何种授权方式,这都适用。 +系统管理员在授予对 Pod 创建的访问权限时要小心。 +被授予在名字空间中创建 Pod(或创建 Pod 的控制器)的权限的用户可以: +读取名字空间中的所有 Secret;读取名字空间中的所有 ConfigMap; +并模拟名字空间中的任意服务账号并执行账号可以执行的任何操作。 +无论采用何种鉴权方式,这都适用。 {{< /caution >}} - ## {{% heading "whatsnext" %}} -* 要了解有关身份验证的更多信息,请参阅 **身份验证** [控制对 Kubernetes API 的访问](/zh/docs/reference/access-authn-authz/controlling-access/)。 -* 要了解有关准入控制的更多信息,请参阅 [使用准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/)。 +* 要了解有关身份验证的更多信息,请参阅 + [控制对 Kubernetes API 的访问](/zh/docs/concepts/security/controlling-access/) + 中的 **身份验证** 部分。 +* 要了解有关准入控制的更多信息,请参阅 + [使用准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/)。 + diff --git a/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md b/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md index c36f1f9bba..23538c8787 100644 --- a/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md +++ b/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md @@ -1,107 +1,238 @@ --- -approvers: -- jbeda title: 使用启动引导令牌(Bootstrap Tokens)认证 +weight: 20 --- -{{< toc >}} + -## 概述 + -启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群或者在现有集群中添加新节点时使用的。 -它被设计成能够支持 [`kubeadm`](/zh/docs/reference/setup-tools/kubeadm/),但是也可以被用在其他的案例中以便用户在 -不使用 `kubeadm` 的情况下启动集群。它也被设计成可以通过 RBAC 策略,结合 [Kubelet TLS -Bootstrapping](/zh/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) 系统进行工作。 +{{< feature-state for_k8s_version="v1.18" state="stable" >}} -启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于 -`kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。 -控制器管理器中的控制器 TokenCleaner 能够删除过期的令牌。在节点发现的过程中 Kubernetes 会使用特殊的 ConfigMap 对象。 -控制器管理器中的 BootstrapSigner 控制器也会使用启动引导令牌为这类对象生成签名信息。 + +启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群 +或者在现有集群中添加新节点时使用的。 +它被设计成能够支持 [`kubeadm`](/zh/docs/reference/setup-tools/kubeadm/), +但是也可以被用在其他的案例中以便用户在不使用 `kubeadm` 的情况下启动集群。 +它也被设计成可以通过 RBAC 策略,结合 +[Kubelet TLS 启动引导](/zh/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) +系统进行工作。 -目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。 + + +启动引导令牌被定义成一个特定类型的 Secret (`bootstrap.kubernetes.io/token`), +并存在于 `kube-system` 名字空间中。 +这些 Secret 会被 API 服务器上的启动引导认证组件(Bootstrap Authenticator)读取。 +控制器管理器中的控制器 TokenCleaner 能够删除过期的令牌。 +这些令牌也被用来在节点发现的过程中会使用的一个特殊的 ConfigMap 对象。 +BootstrapSigner 控制器也会使用这一 ConfigMap。 + + ## 令牌格式 启动引导令牌使用 `abcdef.0123456789abcdef` 的形式。 更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`。 -令牌的第一部分是 "Token ID" ,它是公共信息。用于引用某个令牌,并确保不会泄露认证所使用的秘密信息。 -第二部分是“令牌秘密(Token Secret)”,它应该被共享给收信的第三方。 +令牌的第一部分是 "Token ID",它是一种公开信息,用于引用令牌并确保不会 +泄露认证所使用的秘密信息。 +第二部分是"令牌秘密(Token Secret)",它应该被共享给受信的第三方。 ## 启用启动引导令牌 -所有与启动引导令牌相关的特性在 Kubernetes v1.6 版本中默认都是禁用的。 + +## 启用启动引导令牌身份认证 {#enabling-bootstrap-token-authentication} -HTTPS 调用中的令牌是这样使用的: +启动引导令牌认证组件可以通过 API 服务器上的如下标志启用: + +``` +--enable-bootstrap-token-auth +``` + + +启动引导令牌被启用后,可以作为持有者令牌的凭据,用于 API 服务器请求的身份认证。 ```http Authorization: Bearer 07401b.f395accd246ae52d ``` + +令牌认证为用户名 `system:bootstrap:` 并且是组 `system:bootstrappers` +的成员。额外的组信息可以通过令牌的 Secret 来设置。 -每个合法的令牌背后对应着 `kube-system` 命名空间中的某个 Secret 对象。 -你可以从 [这里](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md) 找到完整设计文档。 +过期的令牌可以通过启用控制器管理器中的 `tokencleaner` 控制器来删除。 -这是 secret 看起来的样子。注意,`base64(string)` 表示应该通过 base64 对值进行编码。 -这里使用的是未解码的版本以便于阅读。 + +## 启动引导令牌的 Secret 格式 {#bootstrap-token-secret-format} + +每个合法的令牌背后对应着 `kube-system` 名字空间中的某个 Secret 对象。 +你可以从 +[这里](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md). +找到完整设计文档。 + +这是 Secret 看起来的样子。 ```yaml apiVersion: v1 kind: Secret metadata: + # name 必须是 "bootstrap-token-" 格式的 name: bootstrap-token-07401b namespace: kube-system + +# type 必须是 'bootstrap.kubernetes.io/token' type: bootstrap.kubernetes.io/token -data: - description: base64(The default bootstrap token generated by 'kubeadm init'.) - token-id: base64(07401b) +stringData: + # 供人阅读的描述,可选。 + description: "The default bootstrap token generated by 'kubeadm init'." + + # 令牌 ID 和秘密信息,必需。 + token-id: 07401b token-secret: base64(f395accd246ae52d) - expiration: base64(2017-03-10T03:22:11Z) - usage-bootstrap-authentication: base64(true) - usage-bootstrap-signing: base64(true) + + # 可选的过期时间字段 + 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 ``` -secret 的类型必须是 `bootstrap.kubernetes.io/token` ,而且名字必须是 `bootstrap-token-`。 -`description` 是人类可读的描述,而不应该是机器可读的信息。令牌 ID 和 Secret 是包含在数据字典中的。 + +Secret 的类型必须是 `bootstrap.kubernetes.io/token`,而且名字必须是 `bootstrap-token-`。 +令牌必须存在于 `kube-system` 名字空间中。 -`usage-bootstrap-authentication` 表示令牌可以用于 API 服务器的认证。认证器会以 -`system:bootstrap:` 认证。它被包含在 `system:bootstrappers` 组中。 -命名和组是故意受限制的,以防止用户在启动引导后再使用这些令牌。 +`usage-bootstrap-*` 成员表明这个 Secret 的用途。启用时,值必须设置为 `true`。 -`usage-bootstrap-signing` 表示令牌应该被用于 `cluster-info` ConfigMap 的签名,就像下面描述的那样。 + +* `usage-bootstrap-authentication` 表示令牌可以作为持有者令牌用于 API 服务器的身份认证。 +* `usage-bootstrap-signing` 表示令牌可被用于 `cluster-info` ConfigMap 的签名, + 就像下面描述的那样。 -`expiration` 数据成员显示了令牌在失效后到现在的时间。这是遵循 RFC3339 进行编码的 UTC 时间。 -TokenCleaner 控制器会删除过期的令牌。 + +`expiration` 字段控制令牌的失效期。过期的令牌在用于身份认证时会被拒绝,在用于 +ConfigMap 签名时会被忽略。 +过期时间值是遵循 RFC3339 进行编码的 UTC 时间。 +启用 TokenCleaner 控制器会自动删除过期的令牌。 -## 使用 `kubeadm` 管理令牌 + +## 使用 `kubeadm` 管理令牌 {#token-management-with-kubeadm} -* `kubeadm token list` 列举了令牌,同时显示了它们的过期时间和用途。 -* `kubeadm token create` 创建一个新令牌。 - * `--description` 设置新令牌的描述。 - * `--ttl duration` 设置令牌从“现在”起到过期时间的差值。 - 默认是 0 ,也就是不过期。 - * `--usages` 设置令牌被使用的方式。默认是 `signing,authentication`。用途在上面已经描述。 -* `kubeadm token delete |.` 删除令牌。 - 令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。 +你可以使用 `kubeadm` 工具管理运行中集群上的令牌。 +参见 [kubeadm token 文档](/zh/docs/reference/setup-tools/kubeadm/kubeadm-token/) +以了解详细信息。 -### ConfigMap 签名 + +### ConfigMap 签名 {#configmap-signing} + +除了身份认证,令牌还可以用于签名 ConfigMap。 +这一用法发生在集群启动过程的早期,在客户端信任 API 服务器之前。 +被签名的 ConfigMap 可以被共享令牌完成身份认证。 + +通过在控制器管理器上启用 `bootstrapsigner` 控制器可以启用 ConfigMap 签名特性。 + +``` +--controllers=*,bootstrapsigner +``` + + +被签名的 ConfigMap 是 `kube-public` 名字空间中的 `cluster-info`。 典型的工作流中,客户端在未经认证和忽略 TLS 报错的状态下读取这个 ConfigMap。 -通过 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。 +通过检查 ConfigMap 中嵌入的签名校验 ConfigMap 的载荷。 ConfigMap 会是这个样子的: @@ -117,7 +248,7 @@ data: apiVersion: v1 clusters: - cluster: - certificate-authority-data: + certificate-authority-data: <非常长的证书数据> server: https://10.138.0.2:6443 name: "" contexts: [] @@ -127,10 +258,46 @@ data: users: [] ``` + ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件。 这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。 -签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则 -(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间 -,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥, -通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。 + +签名是一个使用 "detached" 模式生成的 JWS 签名。 +为了检验签名,用户应该按照 JWS 规则(base64 编码且丢掉结尾的 `=`)对 +`kubeconfig` 的载荷进行编码。完成编码的载荷会被插入到两个句点中间,形成完整的 +JWS。你可以使用完整的令牌(比如 `07401b.f395accd246ae52d`)作为共享密钥, +通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 +用户 _必须_ 确保使用了 HS256。 + +{{< warning >}} + +任何拥有了启动引导令牌的主体都可以为该令牌生成一个合法的签名。 +当使用 ConfigMap 签名时,非常不建议针对很多客户使用相同的令牌,因为某个被攻击的 +客户可能对另一个一来签名来开启 TLS 信任的客户发起中间人攻击。 +{{< /warning >}} + + +参考 [kubeadm 实现细节](/zh/docs/reference/setup-tools/kubeadm/implementation-details/) +了解更多信息。 + diff --git a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md index cb559d0505..82b37c9043 100644 --- a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md +++ b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md @@ -1,76 +1,209 @@ --- -approvers: +title: 管理 Service Accounts +content_type: concept +weight: 50 +--- + + -*这是一篇针对service accounts(服务账户)的集群管理员指南。 它呈现了 [User Guide to Service Accounts](/zh/docs/tasks/configure-pod-container/configure-service-account/)中的信息。* + + +这是一篇针对服务账号的集群管理员指南。你应该熟悉 +[配置 Kubernetes 服务账号](/zh/docs/tasks/configure-pod-container/configure-service-account/)。 -## 用户账户与服务账户 +对鉴权和用户账号的支持已在规划中,当前并不完备。 +为了更好地描述服务账号,有时这些不完善的特性也会被提及。 -Kubernetes 区分用户账户和服务账户的概念主要基于以下原因: + - - 用户账户是针对人而言的。 服务账户是针对运行在 pod 中的进程而言的。 - - 用户账户是全局性的。 其名称在集群各 namespace 中都是全局唯一的,未来的用户资源不会做 namespace 隔离, - 服务账户是 namespace 隔离的。 - - 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 ( 即权限最小化原则 )。 - - 对人员和服务账户审计所考虑的因素可能不同。 - - 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有 namespace 级别的名称,这种配置是很轻量的。 + +## 用户账号与服务账号 {#user-accounts-versus-service-accounts} -三个独立组件协作完成服务账户相关的自动化 : +Kubernetes 区分用户账号和服务账号的概念,主要基于以下原因: - - 服务账户准入控制器(Service account admission controller) - - Token 控制器(Token controller) - - 服务账户控制器(Service account controller) + +- 用户账号是针对人而言的。 服务账号是针对运行在 Pod 中的进程而言的。 +- 用户账号是全局性的。其名称跨集群中名字空间唯一的。服务账号是名字空间作用域的。 +- 通常情况下,集群的用户账号可能会从企业数据库进行同步,其创建需要特殊权限, + 并且涉及到复杂的业务流程。 + 服务账号创建有意做得更轻量,允许集群用户为了具体的任务创建服务账号 + 以遵从权限最小化原则。 +- 对人员和服务账号审计所考虑的因素可能不同。 +- 针对复杂系统的配置包可能包含系统组件相关的各种服务账号的定义。因为服务账号 + 的创建约束不多并且有名字空间域的名称,这种配置是很轻量的。 -### 服务账户准入控制器 + +## 服务账号的自动化 {#service-account-automation} -### Token 管理器 +三个独立组件协作完成服务账号相关的自动化: -Token 管理器是 controller-manager 的一部分。 以异步的形式工作: +- `ServiceAccount` 准入控制器 +- Token 控制器 +- `ServiceAccount` 控制器 -- 检测服务账户的创建,并且创建相应的 Secret 以支持 API 访问。 -- 检测服务账户的删除,并且删除所有相应的服务账户 Token Secret。 -- 检测 Secret 的增加,保证相应的服务账户存在,如有需要,为 Secret 增加 token。 -- 检测 Secret 的删除,如有需要,从相应的服务账户中移除引用。 + +### ServiceAccount 准入控制器 {#serviceaccount-admission-controller} -#### 创建额外的 API tokens +对 Pod 的改动通过一个被称为 +[准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/) +的插件来实现。它是 API 服务器的一部分。 +当 Pod 被创建或更新时,它会同步地修改 Pod。 +如果该插件处于激活状态(在大多数发行版中都是默认激活的),当 Pod 被创建 +或更新时它会进行以下操作: -控制器中有专门的循环来保证每个服务账户中都存在 API token 对应的 Secret。 当需要为服务账户创建额外的 API token 时,创建一个类型为 `ServiceAccountToken` 的 Secret,并在 annotation 中引用服务账户,控制器会生成 token 并更新 : + +1. 如果该 Pod 没有设置 `serviceAccountName`,将其 `serviceAccountName` 设为 + `default`。 +1. 保证 Pod 所引用的 `serviceAccountName` 确实存在,否则拒绝该 Pod。 +1. 如果 Pod 不包含 `imagePullSecrets` 设置,将 `serviceAccountName` 所引用 + 的服务账号中的 `imagePullSecrets` 信息添加到 Pod 中。 +1. 如果服务账号的 `automountServiceAccountToken` 或 Pod 的 + `automountServiceAccountToken` 都为设置为 `false`,则为 Pod 创建一个 + `volume`,在其中包含用来访问 API 的令牌。 +1. 如果前一步中为服务账号令牌创建了卷,则为 Pod 中的每个容器添加一个 + `volumeSource`,挂载在其 `/var/run/secrets/kubernetes.io/serviceaccount` + 目录下。 -secret.json: + +当 `BoundServiceAccountTokenVolume` 特性门控被启用时,你可以将服务账号卷迁移到投射卷。 +服务账号令牌会在 1 小时后或者 Pod 被删除之后过期。 +更多信息可参阅[投射卷](/zh/docs/tasks/configure-pod-container/configure-projected-volume-storage/)。 -```json -{ - "kind": "Secret", - "apiVersion": "v1", - "metadata": { - "name": "mysecretname", - "annotations": { - "kubernetes.io/service-account.name": "myserviceaccount" - } - }, - "type": "kubernetes.io/service-account-token" -} + +### Token 控制器 {#token-controller} + +TokenController 作为 `kube-controller-manager` 的一部分运行,以异步的形式工作。 +其职责包括: + +- 监测 ServiceAccount 的创建并创建相应的服务账号令牌 Secret 以允许访问 API。 +- 监测 ServiceAccount 的删除并删除所有相应的服务账号令牌 Secret。 +- 监测服务账号令牌 Secret 的添加,保证相应的 ServiceAccount 存在,如有需要, + 向 Secret 中添加令牌。 +- 监测服务账号令牌 Secret 的删除,如有需要,从相应的 ServiceAccount 中移除引用。 + + +你必须通过 `--service-account-private-key-file` 标志为 `kube-controller-manager` +的令牌控制器传入一个服务账号私钥文件。该私钥用于为所生成的服务账号令牌签名。 +同样地,你需要通过 `--service-account-key-file` 标志将对应的公钥通知给 +kube-apiserver。公钥用于在身份认证过程中校验令牌。 + + +#### 创建额外的 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 @@ -78,12 +211,23 @@ kubectl create -f ./secret.json kubectl describe secret mysecretname ``` -#### 删除 / 失效 服务账户 token + +#### 删除/废止服务账号令牌 Secret ```shell kubectl delete secret mysecretname ``` -### 服务账户管理器 + +### 服务账号控制器 {#serviceaccount-controller} + +服务账号控制器管理各名字空间下的 ServiceAccount 对象,并且保证每个活跃的 +名字空间下存在一个名为 "default" 的 ServiceAccount。 -服务账户管理器管理各命名空间下的服务账户,并且保证每个活跃的命名空间下存在一个名为 "default" 的服务账户