Merge pull request #5354 from zhangqx2010/upstream
k8smeetup-cn-translation-zhangqx-pr-20170907
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
---
|
||||
assignees:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Webhook Mode
|
||||
---
|
||||
|
||||
{% capture overview %}
|
||||
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。
|
||||
{% endcapture %}
|
||||
|
||||
{% capture body %}
|
||||
具体来说,当在判断用户权限时,`Webhook` 模式会使 Kubernetes 查询外部的 REST 服务。
|
||||
|
||||
## 配置文件格式
|
||||
|
||||
`Webhook` 模式需要一个 HTTP 配置文件,通过 `--authorization-webhook-config-file=SOME_FILENAME` 的参数声明。
|
||||
|
||||
配置文件的格式使用 [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)。
|
||||
在文件中,"users" 代表着 API 服务器的 webhook,而 "cluster" 代表着远程服务。
|
||||
|
||||
使用 HTTPS 客户端认证的配置例子:
|
||||
|
||||
```yaml
|
||||
# clusters 代表远程服务。
|
||||
clusters:
|
||||
- name: name-of-remote-authz-service
|
||||
cluster:
|
||||
certificate-authority: /path/to/ca.pem # 对远程服务进行身份认证的CA。
|
||||
server: https://authz.example.com/authorize # 远程服务的查询 URL. 必须使用 'https'。
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
|
||||
## 请求载荷
|
||||
|
||||
在做认证决策时,API 服务器会 POST 一个 JSON 序列化的 api.authorization.v1beta1.SubjectAccessReview 对象来描述这个动作。这个对象包含了描述用户请求的字段,同时也包含了需要被访问资源或者请求特征的具体信息。
|
||||
|
||||
需要注意的是 webhook API 对象与其他 Kubernetes API 对象一样都同样都服从 [版本兼容规则](/docs/api/) 。
|
||||
实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段以确保能被正确地反序列化。
|
||||
此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组(`--runtime-config=authorization.k8s.io/v1beta1=true`)。
|
||||
|
||||
|
||||
一个请求内容的例子:
|
||||
|
||||
```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"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
远程服务被预期能填写请求和反馈的 SubjectAccessReviewStatus 字段,无论是允许访问还是拒绝访问。
|
||||
反馈内容的 "spec" 字段是被忽略的,也是可以被省略的。当请求是被允许的时候,返回的响应如下例所示:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"status": {
|
||||
"allowed": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
如拒绝,远程服务器会返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"status": {
|
||||
"allowed": false,
|
||||
"reason": "user does not have read access to the namespace"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
对于非资源的路径访问是这么发送的:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"nonResourceAttributes": {
|
||||
"path": "/debug",
|
||||
"verb": "get"
|
||||
},
|
||||
"user": "jane",
|
||||
"group": [
|
||||
"group1",
|
||||
"group2"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
非资源类的路径包括:`/api`, `/apis`, `/metrics`, `/resetMetrics`,
|
||||
`/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and
|
||||
`/version`。 客户端需要访问 `/api`, `/api/*`, `/apis`, `/apis/*`, 和 `/version` 以便
|
||||
能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST API 访问限制的情况下拒绝。
|
||||
|
||||
|
||||
更多信息可以参考 uthorization.v1beta1 API 对象和
|
||||
[webhook.go](https://git.k8s.io/kubernetes/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% include templates/concept.md %}
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
assignees:
|
||||
- jbeda
|
||||
title: 使用启动引导令牌(Bootstrap Tokens)认证
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## 概述
|
||||
|
||||
启动引导令牌是一种简单的持有者令牌(Bearer Token),这种令牌是在新建集群或者在现有集群中添加新节点时使用的。
|
||||
它被设计成能够支持 [`kubeadm`](/docs/admin/kubeadm/),但是也可以被用在其他的案例中以便用户在
|
||||
不使用 `kubeadm` 的情况下启动集群。它也被设计成可以通过 RBAC 策略,结合 [Kubelet TLS
|
||||
Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。
|
||||
|
||||
启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于
|
||||
`kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。
|
||||
控制器管理器中的控制器TokenCleaner能够删除过期的令牌。在节点发现的过程中Kubernetes会使用特殊的ConfigMap对象。
|
||||
控制器管理器中的BootstrapSigner控制器也会使用启动引导令牌为这类对象生成签名信息。
|
||||
|
||||
目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。
|
||||
|
||||
## 令牌格式
|
||||
|
||||
启动引导令牌使用 `abcdef.0123456789abcdef` 的形式。
|
||||
更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`。
|
||||
|
||||
令牌的第一部分是 "Token ID" ,它是公共信息。用于引用某个令牌,并确保不会泄露认证所使用的秘密信息。
|
||||
第二部分是 "令牌秘密(Token Secret)",它应该被共享给收信的第三方。
|
||||
|
||||
## 启用启动引导令牌
|
||||
|
||||
所有与启动引导令牌相关的特性在 Kubernetes v1.6 版本中默认都是禁用的。
|
||||
|
||||
你可以在 API 服务器上通过 `--experimental-bootstrap-token-auth` 参数启用启动引导令牌。
|
||||
你可以设置控制管理器的 `--controllers` 参数来启用启动引导令牌相关的控制器,例如 `--controllers=*,tokencleaner,bootstrapsigner` 。
|
||||
在使用 `kubeadm` 时,这是自动完成的。
|
||||
|
||||
HTTPS 调用中的令牌是这样使用的:
|
||||
|
||||
```http
|
||||
Authorization: Bearer 07401b.f395accd246ae52d
|
||||
```
|
||||
|
||||
## 启动引导令牌的密文格式
|
||||
|
||||
每个合法的令牌背后对应着 `kube-system` 命名空间中的某个 Secret 对象。
|
||||
你可以从 [这里](https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md) 找到完整设计文档。
|
||||
|
||||
这是 secret 看起来的样子。注意,`base64(string)` 表示应该通过 base64 对值进行编码。
|
||||
这里使用的是未解码的版本以便于阅读。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: bootstrap-token-07401b
|
||||
namespace: kube-system
|
||||
type: bootstrap.kubernetes.io/token
|
||||
data:
|
||||
description: base64(The default bootstrap token generated by 'kubeadm init'.)
|
||||
token-id: base64(07401b)
|
||||
token-secret: base64(f395accd246ae52d)
|
||||
expiration: base64(2017-03-10T03:22:11Z)
|
||||
usage-bootstrap-authentication: base64(true)
|
||||
usage-bootstrap-signing: base64(true)
|
||||
```
|
||||
|
||||
secret 的类型必须是 `bootstrap.kubernetes.io/token` ,而且名字必须是 `bootstrap-token-<token id>`。
|
||||
`description` 是人类可读的描述,而不应该是机器可读的信息。令牌 ID 和 Secret 是包含在数据字典中的。
|
||||
|
||||
`usage-bootstrap-*` 成员表示这个 secret 的用途。启用时,值必须设置为 `true`。
|
||||
|
||||
`usage-bootstrap-authentication` 表示令牌可以用于 API 服务器的认证。认证器会以
|
||||
`system:bootstrap:<Token ID>` 认证。它被包含在 `system:bootstrappers` 组中。
|
||||
命名和组是故意受限制的,以防止用户在启动引导后再使用这些令牌。
|
||||
|
||||
`usage-bootstrap-signing` 表示令牌应该被用于 `cluster-info` ConfigMap 的签名,就像下面描述的那样。
|
||||
|
||||
`expiration` 数据成员显示了令牌在失效后到现在的时间。这是遵循 RFC3339 进行编码的 UTC 时间。
|
||||
TokenCleaner 控制器会删除过期的令牌。
|
||||
|
||||
## 使用 `kubeadm` 管理令牌
|
||||
|
||||
你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`)
|
||||
自动抓取默认管理员密码。你可以通过参数 `--kubeconfig` 对下面命令指定一个另外的 kubeconfig 文件抓取密码。
|
||||
|
||||
* `kubeadm token list` 列举了令牌,同时显示了它们的过期时间和用途。
|
||||
* `kubeadm token create` 创建一个新令牌。
|
||||
* `--description` 设置新令牌的描述。
|
||||
* `--ttl duration` 设置令牌从 "现在" 起到过期时间的差值。
|
||||
默认是 0 ,也就是不过期。
|
||||
* `--usages` 设置令牌被使用的方式。默认是 `signing,authentication`。用途在上面已经描述。
|
||||
* `kubeadm token delete <token id>|<token id>.<token secret>` 删除令牌。
|
||||
令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。
|
||||
|
||||
### ConfigMap签名
|
||||
|
||||
除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动过程的早期,在客户端信任 API 服务器之前被使用。
|
||||
被签名的 ConfigMap 可以通过共享令牌被认证。
|
||||
|
||||
被签名的 ConfigMap 是 `cluster-info`,存在于 `kube-public` 命名空间中。
|
||||
典型的工作流中,客户端在未经认证和忽略 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: <really long certificate data>
|
||||
server: https://10.138.0.2:6443
|
||||
name: ""
|
||||
contexts: []
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users: []
|
||||
```
|
||||
|
||||
ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件。
|
||||
这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。
|
||||
|
||||
签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则
|
||||
(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间
|
||||
,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥,
|
||||
通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。
|
||||
Reference in New Issue
Block a user