Convert site to Hugo (#8316)
This commit converts content and layout to use Hugo.
This commit is contained in:
committed by
k8s-ci-robot
parent
7745f0e0c5
commit
7f3b633aa0
@@ -0,0 +1,135 @@
|
||||
---
|
||||
approvers:
|
||||
- bgrant0607
|
||||
- erictune
|
||||
- lavalamp
|
||||
title: Kubernetes API访问控制
|
||||
---
|
||||
|
||||
用户通过 `kubectl`、客户端库或者通过发送REST请求[访问API](/docs/user-guide/accessing-the-cluster)。 用户(自然人)和[Kubernetes服务账户](/docs/tasks/configure-pod-container/configure-service-account/) 都可以被授权进行API访问。
|
||||
请求到达API服务器后会经过几个阶段,具体说明如图:
|
||||
|
||||

|
||||
|
||||
## 传输层安全
|
||||
|
||||
在典型的Kubernetes集群中,API通过443端口提供服务。
|
||||
API服务器会提供一份证书。 该证书一般是自签名的, 所以用户机器上的 `$USER/.kube/config` 目录通常
|
||||
包含该API服务器证书的根证书,用来代替系统默认根证书。 当用户使用 `kube-up.sh` 创建集群时,该证书通常会被自动写入用户的`$USER/.kube/config`。 如果集群中存在多个用户,则创建者需要与其他用户共享证书。
|
||||
|
||||
## 认证
|
||||
|
||||
一旦 TLS 连接建立,HTTP请求就进入到了认证的步骤。即图中的步骤 **1** 。
|
||||
集群创建脚本或集群管理员会为API服务器配置一个或多个认证模块。
|
||||
更具体的认证相关的描述详见 [这里](/docs/admin/authentication/)。
|
||||
|
||||
认证步骤的输入是整个HTTP请求,但这里通常只是检查请求头和/或客户端证书。
|
||||
|
||||
认证模块支持客户端证书,密码和Plain Tokens,
|
||||
Bootstrap Tokens,以及JWT Tokens (用于服务账户)。
|
||||
|
||||
(管理员)可以同时设置多种认证模块,在设置了多个认证模块的情况下,每个模块会依次尝试认证,
|
||||
直到其中一个认证成功。
|
||||
|
||||
在 GCE 平台中,客户端证书,密码和Plain Tokens,Bootstrap Tokens,以及JWT Tokens同时被启用。
|
||||
|
||||
如果请求认证失败,则请求被拒绝,返回401状态码。
|
||||
如果认证成功,则被认证为具体的 `username`,该用户名可供随后的步骤中使用。一些认证模块还提供了用户的组成员关系,另一些则没有。
|
||||
|
||||
尽管Kubernetes使用 "用户名" 来进行访问控制和请求记录,但它实际上并没有 `user` 对象,也不存储用户名称或其他相关信息。
|
||||
|
||||
## 授权
|
||||
|
||||
当请求被认证为来自某个特定的用户后,该请求需要被授权。 即图中的步骤 **2** 。
|
||||
|
||||
请求须包含请求者的用户名,请求动作,以及该动作影响的对象。 如果存在相应策略,声明该用户具有进行相应操作的权限,则该请求会被授权。
|
||||
|
||||
例如,如果Bob有如下策略,那么他只能够读取`projectCaribou`命名空间下的pod资源:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
|
||||
"kind": "Policy",
|
||||
"spec": {
|
||||
"user": "bob",
|
||||
"namespace": "projectCaribou",
|
||||
"resource": "pods",
|
||||
"readonly": true
|
||||
}
|
||||
}
|
||||
```
|
||||
如果Bob发起以下请求,那么请求能够通过授权,因为Bob被允许访问 `projectCaribou` 命名空间下的对象:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"resourceAttributes": {
|
||||
"namespace": "projectCaribou",
|
||||
"verb": "get",
|
||||
"group": "unicorn.example.org",
|
||||
"resource": "pods"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
如果Bob对 `projectCaribou` 命名空间下的对象发起一个写(`create` 或者 `update`)请求,那么它的授权会被拒绝。 如果Bob请求读取(`get`) 其他命名空间,例如 `projectFish`下的对象,其授权也会被拒绝。
|
||||
|
||||
Kubernetes的授权要求使用通用的REST属性与现有的组织或云服务提供商的访问控制系统进行交互。 采用REST格式是必要的,因为除Kubernetes外,这些访问控制系统还可能与其他的API进行交互。
|
||||
|
||||
Kubernetes 支持多种授权模块,例如ABAC模式,RBAC模式和 Webhook模式。 管理员创建集群时,会配置API服务器应用的授权模块。 如果多种授权模式同时被启用,Kubernetes将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。
|
||||
|
||||
要了解更多的Kubernetes授权相关信息,包括使用授权模块创建策略的具体说明等,可参考[授权概述](/docs/admin/authorization)。
|
||||
|
||||
|
||||
## 准入控制
|
||||
|
||||
准入控制模块是能够修改或拒绝请求的软件模块。
|
||||
作为授权模块的补充,准入控制模块会访问被创建或更新的对象的内容。
|
||||
它们作用于对象的创建,删除,更新和连接 (proxy)阶段,但不包括对象的读取。
|
||||
|
||||
可以同时配置多个准入控制器,它们会按顺序依次被调用。
|
||||
|
||||
即图中的步骤 **3** 。
|
||||
|
||||
与认证和授权模块不同的是,如果任一个准入控制器拒绝请求,那么整个请求会立即被拒绝。
|
||||
|
||||
除了拒绝请求外,准入控制器还可以为对象设置复杂的默认值。
|
||||
|
||||
可用的准入控制模块描述 [如下](/docs/admin/admission-controllers/)。
|
||||
|
||||
一旦请求通过所有准入控制器,将使用对应API对象的验证流程对其进行验证,然后写入对象存储 (如步骤 **4**)。
|
||||
|
||||
|
||||
## API的端口和IP
|
||||
|
||||
上述讨论适用于发送请求到API服务器的安全端口(典型情况)。
|
||||
实际上API服务器可以通过两个端口提供服务:
|
||||
|
||||
默认情况下,API服务器在2个端口上提供HTTP服务:
|
||||
|
||||
1. `Localhost Port`:
|
||||
|
||||
- 用于测试和启动,以及管理节点的其他组件
|
||||
(scheduler, controller-manager)与API的交互
|
||||
- 没有TLS
|
||||
- 默认值为8080,可以通过 `--insecure-port` 标记来修改。
|
||||
- 默认的IP地址为localhost, 可以通过 `--insecure-bind-address`标记来修改。
|
||||
- 请求会 **绕过** 认证和鉴权模块。
|
||||
- 请求会被准入控制模块处理。
|
||||
- 其访问需要主机访问的权限。
|
||||
|
||||
2. `Secure Port`:
|
||||
|
||||
- 尽可能使用该端口访问
|
||||
- 应用 TLS。 可以通过 `--tls-cert-file` 设置证书, 通过 `--tls-private-key-file` 设置私钥。
|
||||
- 默认值为6443,可以通过 `--secure-port` 标记来修改。
|
||||
- 默认IP是首个非本地的网络接口地址,可以通过 `--bind-address` 标记来修改。
|
||||
- 请求会经过认证和鉴权模块处理。
|
||||
- 请求会被准入控制模块处理。
|
||||
- 要求认证和授权模块正常运行。
|
||||
|
||||
通过 `kube-up.sh`创建集群时, 对 Google Compute Engine (GCE)
|
||||
和一些其他的云供应商来说, API通过443端口提供服务。 对
|
||||
GCE而言,项目上配置了防火墙规则,允许外部的HTTPS请求访问API,其他(厂商的)集群设置方法各不相同。
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: 概述
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
学习有关 Kubernetes 授权的更多信息,包括有关使用支持的授权模块创建策略的详细信息。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
在 Kubernetes 里,您必须经过身份验证(登录),才能授权您的请求(授予访问权限).。有关认证的信息,请参阅[访问控制概述](/docs/admin/access-the-api/)。
|
||||
|
||||
Kubernetes 提供通用的 REST API 请求。这意味着 Kubernetes 授权可以与现有的组织或云提供商的访问控制系统一起使用,该系统可以处理除 Kubernetes API 之外的其他 API。
|
||||
|
||||
## 确定请求是允许还是被拒绝
|
||||
Kubernetes 使用 API 服务器授权 API 请求。它根据所有策略评估所有请求属性,并允许或拒绝请求。某些策略必须允许 API 请求的所有部分继续进行,这意味着默认情况下是拒绝权限。
|
||||
|
||||
(虽然 Kubernetes 使用 API 服务器,访问控制和依赖特定类型对象的特定领域策略由 Admission 控制器处理。)
|
||||
|
||||
当配置多个授权模块时,按顺序检查每个模块,如果有任何模块授权请求,则可以继续执行该请求。如果所有模块拒绝请求,则拒绝该请求(HTTP状态代码403)。
|
||||
|
||||
## 查看您的请求属性
|
||||
|
||||
Kubernetes 仅查看以下API请求属性:
|
||||
|
||||
* **user** - 验证期间提供的 `user` 字符串
|
||||
* **group** - 认证用户所属的组名列表
|
||||
* **“extra"** - 由认证层提供的任意字符串键到字符串值的映射
|
||||
* **API** - 指示请求是否用于API资源
|
||||
* **Request path** - 诸如`/api`或`/healthz`的其他非资源端点的路径(请参阅[kubectl](#kubectl)).
|
||||
* **API request verb** - API 动词 `get`,`list`,`create`,`update`,`patch`,`watch`,`proxy`,`redirect`,`delete`和`deletecollection`用于资源请求。要确定资源 API 端点的请求动词,请参阅**确定下面的请求动词**.
|
||||
* **HTTP request verb** - HTTP动词`get`,`post`,`put`和`delete`用于非资源请求
|
||||
* **Resource** - 正在访问的资源的ID或名称(仅适用于资源请求)
|
||||
--* 对于使用`get`, `update`, `patch`, 和 `delete`动词的资源请求,您必须提供资源名称。
|
||||
* **Subresource** - 正在访问的子资源(仅用于资源请求)
|
||||
* **Namespace** - 正在被访问的对象的命名空间(仅针对命名空间的资源请求)
|
||||
* **API group** - 正在访问的API组(仅用于资源请求). 一个空字符串指定[核心 API 组](/docs/api/).
|
||||
|
||||
## 确定请求动词
|
||||
|
||||
要确定资源 API 端点的请求动词,请查看所使用的HTTP动词以及请求是否对单个资源或资源集合进行操作:
|
||||
|
||||
HTTP动词| 请求动词
|
||||
---------- | ---------------
|
||||
POST | 创建
|
||||
GET,HEAD | 获取(个人资源),列表(集合)
|
||||
PUT | 更新
|
||||
PATCH | 补丁
|
||||
DELETE| 删除(个人资源),删除(收藏)
|
||||
|
||||
Kubernetes 有时会使用专门的动词检查授权以获得额外的权限。例如:
|
||||
|
||||
* [PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/)在`extensions` API组中的`podsecuritypolicies`资源上检查`use`动词的授权。
|
||||
* [RBAC](/docs/admin/authorization/rbac/#privilege-escalation-prevention-and-bootstrapping) 在`rbac.authorization.k8s.io` API组中的`roles`和`clusterroles`资源上检查`bind`动词的授权。
|
||||
* [认证](/docs/admin/authentication/) 在核心API组中的`users`,`groups`和`serviceaccounts`上的`impersonate`动词的授权以及`authentication.k8s.io` API组中的`userextras`进行层次检查。
|
||||
|
||||
## 授权模块
|
||||
* **ABAC模式** - 基于属性的访问控制(ABAC)定义了访问控制范例,通过使用将属性组合在一起的策略来授予用户访问权限。策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。要了解有关使用ABAC模式的更多信息,请参阅[ABAC模式](/docs/admin/authorization/abac/)
|
||||
* **RBAC模式** - 基于角色的访问控制(RBAC)是一种根据企业内个人用户的角色来调整对计算机或网络资源的访问的方法。在这种情况下,访问是单个用户执行特定任务(例如查看,创建或修改文件)的能力。要了解有关使用RBAC模式的更多信息,请参阅[RBAC模式](/docs/admin/authorization/rbac/)
|
||||
*当指定 "RBAC"(基于角色的访问控制)使用 "rbac.authorization.k8s.io" API组来驱动授权决定时,允许管理员通过Kubernetes API动态配置权限策略.
|
||||
.. *截至1.6 RBAC模式是测试版.
|
||||
.. *要启用RBAC,请使用 `--authorization-mode=RBAC` 启动 apiserver.
|
||||
* **Webhook模式** - WebHook 是HTTP回调:发生事件时发生的HTTP POST; 通过HTTP POST简单的事件通知. 实施 WebHooks 的 Web 应用程序将在某些事情发生时向URL发送消息. 要了解有关使用Webhook模式的更多信息,请参阅[Webhook模式](/docs/admin/authorization/webhook/)
|
||||
* **自定义模块** - 您可以创建使用Kubernetes的自定义模块. 要了解更多信息,请参阅下面的**自定义模块**。
|
||||
|
||||
### 自定义模块
|
||||
可以相当容易地开发其他实现,APIserver 调用 Authorizer 接口:
|
||||
|
||||
```go
|
||||
type Authorizer interface {
|
||||
Authorize(a Attributes) error
|
||||
}
|
||||
```
|
||||
|
||||
以确定是否允许每个API操作.
|
||||
|
||||
授权插件是实现此接口的模块.授权插件代码位于 `pkg/auth/authorizer/$MODULENAME` 中。
|
||||
|
||||
授权模块可以完全实现,也可以拨出远程授权服务。 授权模块可以实现自己的缓存,以减少具有相同或相似参数的重复授权调用的成本。 开发人员应该考虑缓存和撤销权限之间的交互。
|
||||
|
||||
#### 检查API访问
|
||||
|
||||
Kubernetes 将 `subjectaccessreviews.v1.authorization.k8s.io` 资源公开为允许外部访问API授权者决策的普通资源。 无论您选择使用哪个授权器,您都可以使用`SubjectAccessReview`发出一个`POST`,就像webhook授权器的`apis/authorization.k8s.io/v1/subjectaccessreviews` 端点一样,并回复一个响应。 例如:
|
||||
|
||||
|
||||
```bash
|
||||
kubectl create --v=8 -f - << __EOF__
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"resourceAttributes": {
|
||||
"namespace": "kittensandponies",
|
||||
"verb": "get",
|
||||
"group": "unicorn.example.org",
|
||||
"resource": "pods"
|
||||
},
|
||||
"user": "jane",
|
||||
"group": [
|
||||
"group1",
|
||||
"group2"
|
||||
],
|
||||
"extra": {
|
||||
"scopes": [
|
||||
"openid",
|
||||
"profile"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
__EOF__
|
||||
|
||||
--- snip lots of output ---
|
||||
|
||||
I0913 08:12:31.362873 27425 request.go:908] Response Body: {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"resourceAttributes":{"namespace":"kittensandponies","verb":"GET","group":"unicorn.example.org","resource":"pods"},"user":"jane","group":["group1","group2"],"extra":{"scopes":["openid","profile"]}},"status":{"allowed":true}}
|
||||
subjectaccessreview "" created
|
||||
```
|
||||
|
||||
这对于调试访问问题非常有用,因为您可以使用此资源来确定授权者授予哪些访问权限。
|
||||
|
||||
## 为您的授权模块使用标志
|
||||
|
||||
您的策略中必须包含一个标志,以指出您的策略包含哪个授权模块:
|
||||
|
||||
可以使用以下标志:
|
||||
- `--authorization-mode=ABAC` 基于属性的访问控制(ABAC)模式允许您使用本地文件配置策略。
|
||||
- `--authorization-mode=RBAC` 基于角色的访问控制(RBAC)模式允许您使用Kubernetes API创建和存储策略.
|
||||
- `--authorization-mode=Webhook` WebHook是一种HTTP回调模式,允许您使用远程REST管理授权。
|
||||
- `--authorization-mode=AlwaysDeny` 此标志阻止所有请求. 仅使用此标志进行测试。
|
||||
- `--authorization-mode=AlwaysAllow` 此标志允许所有请求. 只有在您不需要API请求授权的情况下才能使用此标志。
|
||||
|
||||
您可以选择多个授权模块. 如果其中一种模式为 `AlwaysAllow`,则覆盖其他模式,并允许所有API请求。
|
||||
|
||||
## 版本控制
|
||||
|
||||
对于版本 1.2,配置了 kube-up.sh 创建的集群,以便任何请求都不需要授权。
|
||||
|
||||
从版本 1.3 开始,配置由 kube-up.sh 创建的集群,使得 ABAC 授权模块处于启用状态。但是,其输入文件最初设置为允许所有用户执行所有操作,集群管理员需要编辑该文件,或者配置不同的授权器来限制用户可以执行的操作。
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* 要学习有关身份验证的更多信息,请参阅**身份验证**[控制访问 Kubernetes API](docs/admin/access-the-api/)。
|
||||
* 要了解有关入学管理的更多信息,请参阅[使用 Admission 控制器](docs/admin/admission-controllers/)。
|
||||
*
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: ABAC 模式
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
基于属性的访问控制(Attribute-based access control - ABAC)定义了访问控制范例,其中通过使用将属性组合在一起的策略来向用户授予访问权限。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 策略文件格式
|
||||
|
||||
基于 `ABAC` 模式,可以这样指定策略文件 `--authorization-policy-file=SOME_FILENAME`。
|
||||
|
||||
此文件是 JSON 格式[每行都是一个JSON对象](http://jsonlines.org/),不应存在封闭的列表或映射,每行只有一个映射。
|
||||
|
||||
每一行都是一个 "策略对象",策略对象是具有以下映射的属性:
|
||||
|
||||
- 版本控制属性:
|
||||
- `apiVersion`,字符串类型: 有效值为"abac.authorization.kubernetes.io/v1beta1",允许版本控制和转换策略格式。
|
||||
- `kind`,字符串类型: 有效值为 "Policy",允许版本控制和转换策略格式。
|
||||
- `spec` 配置为具有以下映射的属性:
|
||||
- 匹配属性:
|
||||
- `user`,字符串类型; 来自 `--token-auth-file` 的用户字符串,如果你指定`user`,它必须与验证用户的用户名匹配。
|
||||
- `group`,字符串类型; 如果指定`group`,它必须与经过身份验证的用户的一个组匹配,`system:authenticated`匹配所有经过身份验证的请求。`system:unauthenticated`匹配所有未经过身份验证的请求。
|
||||
- 资源匹配属性:
|
||||
- `apiGroup`,字符串类型; 一个 API 组。
|
||||
- 例: `extensions`
|
||||
- 通配符: `*`匹配所有 API 组。
|
||||
- `namespace`,字符串类型; 一个命名空间。
|
||||
- 例如: `kube-system`
|
||||
- 通配符: `*` 匹配所有资源请求。
|
||||
- `resource`,字符串类型; 资源类型。
|
||||
- 例:`pods`
|
||||
- 通配符: `*`匹配所有资源请求。
|
||||
- 非资源匹配属性:
|
||||
- `nonResourcePath`,字符串类型; 非资源请求路径。
|
||||
- 例如:`/version`或`/apis`
|
||||
- 通配符:
|
||||
- `*` 匹配所有非资源请求。
|
||||
- `/foo/*` 匹配`/foo/`的所有子路径。
|
||||
- `readonly`,键入 boolean,如果为 true,则表示该策略仅适用于 get,list 和 watch 操作。
|
||||
|
||||
**注意:** 未设置的属性与类型设置为零值的属性相同(例如空字符串,0、false),然而未知的应该可读性优先。
|
||||
|
||||
在将来,策略可能以 JSON 格式表示,并通过 REST 界面进行管理。
|
||||
|
||||
## 授权算法
|
||||
|
||||
请求具有与策略对象的属性对应的属性。
|
||||
|
||||
当接收到请求时,确定属性。 未知属性设置为其类型的零值(例如: 空字符串,0,false)。
|
||||
|
||||
设置为`“*"`的属性将匹配相应属性的任何值。
|
||||
|
||||
检查属性的元组,以匹配策略文件中的每个策略。 如果至少有一行匹配请求属性,则请求被授权(但可能会在稍后验证失败)。
|
||||
|
||||
要允许任何经过身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authenticated“`。
|
||||
|
||||
要允许任何未经身份验证的用户执行某些操作,请将策略组属性设置为`"system:authentication“`。
|
||||
|
||||
要允许用户执行任何操作,请使用 apiGroup,命名空间,
|
||||
资源和 nonResourcePath 属性设置为 `“*"`的策略.
|
||||
|
||||
要允许用户执行任何操作,请使用设置为`“*”` 的 apiGroup,namespace,resource 和 nonResourcePath 属性编写策略。
|
||||
|
||||
## Kubectl
|
||||
|
||||
Kubectl 使用 api-server 的 `/api` 和 `/apis` 端点进行协商客户端/服务器版本。 通过创建/更新来验证发送到API的对象操作,kubectl 查询某些 swagger 资源。 对于API版本"v1", 那就是`/swaggerapi/api/v1` & `/swaggerapi/ experimental/v1`。
|
||||
|
||||
当使用 ABAC 授权时,这些特殊资源必须明确通过策略中的 `nonResourcePath` 属性暴露出来(参见下面的[例子](#examples)):
|
||||
|
||||
* `/api`,`/api/*`,`/apis`和`/apis/*` 用于 API 版本协商.
|
||||
* `/version` 通过 `kubectl version` 检索服务器版本.
|
||||
* `/swaggerapi/*` 用于创建/更新操作.
|
||||
|
||||
要检查涉及到特定kubectl操作的HTTP调用,您可以调整详细程度:
|
||||
|
||||
kubectl --v=8 version
|
||||
|
||||
## 例子
|
||||
|
||||
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 可以在命名空间“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": "*"}}
|
||||
```
|
||||
|
||||
[完整文件示例](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/auth/authorizer/abac/example_policy_file.jsonl)
|
||||
|
||||
## 服务帐户的快速说明
|
||||
|
||||
服务帐户自动生成用户。 用户名是根据命名约定生成的:
|
||||
|
||||
```shell
|
||||
system:serviceaccount:<namespace>:<serviceaccountname>
|
||||
```
|
||||
创建新的命名空间也会导致创建一个新的服务帐户:
|
||||
|
||||
```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 以获取新的策略行.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
approvers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Webhook Mode
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL 。
|
||||
{{% /capture %}}
|
||||
|
||||
{{% 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).
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
approvers:
|
||||
- jbeda
|
||||
title: 使用启动引导令牌(Bootstrap Tokens)认证
|
||||
---
|
||||
|
||||
{{< 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。
|
||||
@@ -0,0 +1,122 @@
|
||||
---
|
||||
approvers:
|
||||
- davidopp
|
||||
- lavalamp
|
||||
title: 创建大规模集群
|
||||
---
|
||||
|
||||
## 支持规格
|
||||
|
||||
在 {{< param "version" >}},Kubernetes支持最多5000节点规模的集群。 更具体地说,我们支持满足以下 *所有* 标准的配置:
|
||||
|
||||
* 不超过5000节点
|
||||
* 总共不超过15000个pod
|
||||
* 总共不超过300000个容器
|
||||
* 每个节点不超过100个pod
|
||||
|
||||
<br>
|
||||
|
||||
* TOC
|
||||
{{< toc >}}
|
||||
|
||||
## 创建
|
||||
|
||||
集群是一组运行Kubernetes代理组件的节点(物理或虚拟机),它们被 "master" (集群管理平面)所管理。
|
||||
|
||||
一般来说,集群的节点数量通过平台相关的 `config-default.sh` 文件中的 `NUM_NODES` 值来控制,(例如,详见 [GCE's `config-default.sh`](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/gce/config-default.sh))。
|
||||
|
||||
对很多云提供商来说,单纯地修改`NUM_NODES` 为一个非常大的值,可能会导致集群的创建脚本失败。 例如,在GCE中部署时,会因配额不足,导致集群启动失败。
|
||||
|
||||
当建立一个大型的Kubernetes集群,以下几个问题必须考虑。
|
||||
|
||||
### 配额问题
|
||||
|
||||
为了避免出现配额问题,当创建包含大量节点的集群时,考虑:
|
||||
|
||||
* 提高相关配额,如CPU,IP等。
|
||||
* 如,在 [GCE](https://cloud.google.com/compute/docs/resource-quotas)中,你可能需要提高以下资源的配额:
|
||||
* CPU
|
||||
* 虚机实例
|
||||
* 磁盘
|
||||
* 使用的IP地址
|
||||
* 防火墙规则
|
||||
* 转发规则
|
||||
* 路由
|
||||
* 对象池
|
||||
* 设置创建脚本,使其以较小的规模分批次拉起新的节点,并在其间设置一定的等待时间,因为一些云供应商可能对虚机的创建速率进行了限制。
|
||||
|
||||
### Etcd存储
|
||||
|
||||
为了提升大规模集群的性能,我们将事件对象存储到独立的etcd实例中。
|
||||
|
||||
创建集群时,当前的salt脚本:
|
||||
|
||||
* 启动并配置额外的etcd实例
|
||||
* 配置api-server,将该etcd实例用于事件对象的存储
|
||||
|
||||
### 管理节点和组件的规格
|
||||
|
||||
在 GCE/Google Kubernetes Engine 或 AWS平台中, `kube-up` 会根据集群的节点规模合理地设置管理节点的规格。 在其他云平台上,用户需要手动配置。 作为参考,GCE使用的规格为:
|
||||
|
||||
* 1-5 节点: n1-standard-1
|
||||
* 6-10 节点: n1-standard-2
|
||||
* 11-100 节点: n1-standard-4
|
||||
* 101-250 节点: n1-standard-8
|
||||
* 251-500 节点: n1-standard-16
|
||||
* 500节点以上: n1-standard-32
|
||||
|
||||
AWS使用的规格为:
|
||||
|
||||
* 1-5 节点: m3.medium
|
||||
* 6-10 节点: m3.large
|
||||
* 11-100 节点: m3.xlarge
|
||||
* 101-250 节点: m3.2xlarge
|
||||
* 251-500 节点: c4.4xlarge
|
||||
* 500节点以上: c4.8xlarge
|
||||
|
||||
注意,管理节点的规格只会在集群创建时进行设置,后续集群规模发生变化 (如 手动增删节点或集群自动扩缩容)后不会再调整。
|
||||
|
||||
### 插件的资源占用
|
||||
|
||||
为防止 [集群插件](https://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons) 耗尽节点资源引起内存泄漏或其他资源问题, Kubernetes 设置了插件容器资源的上限,来限制其对CPU和内存资源的占用 (参考 PR [#10653](http://pr.k8s.io/10653/files) 和 [#10778](http://pr.k8s.io/10778/files))。
|
||||
|
||||
例如:
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
- name: fluentd-cloud-logging
|
||||
image: k8s.gcr.io/fluentd-gcp:1.16
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
```
|
||||
|
||||
除 Heapster 外,这些限制是静态的,基于4个节点规模的集群上运行的插件所采集的数据 (详见 [#10335](http://issue.k8s.io/10335#issuecomment-117861225))。 而实际大规模集群中插件所消耗的资源要多得多 (详见 [#5880](http://issue.k8s.io/5880#issuecomment-113984085))。 所以如果部署大规模集群时不对这些值进行调整,插件可能会因为资源占用达到上限而不断被杀死。
|
||||
|
||||
为了避免集群插件的资源问题,创建多节点的集群时,考虑以下几点:
|
||||
|
||||
* 当扩大集群规模时,如果涉及,相应扩大以下插件的内存和CPU限制 (通过一个实例处理整个集群,因此其内存和CPU使用量往往与集群的大小/负载成比例增长):
|
||||
* [InfluxDB 和 Grafana](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/cluster-monitoring/influxdb/influxdb-grafana-controller.yaml)
|
||||
* [kubedns, dnsmasq, 和 sidecar](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kubedns-controller.yaml.in)
|
||||
* [Kibana](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/kibana-controller.yaml)
|
||||
* 当扩大集群规模时,如果涉及,相应扩大以下插件副本数 (每个组件有多个副本,因此增加副本将有助于处理增加的负载,但是,由于每个副本的负载也略有增加,也应考虑提高CPU /内存上限):
|
||||
* [elasticsearch](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/es-controller.yaml)
|
||||
* 当扩大集群规模时,如果涉及,略微扩大以下插件的内存和CPU限制 (每个节点一个副本, 但是CPU/内存使用随集群的大小/负载增长变化不明显):
|
||||
* [FluentD with ElasticSearch Plugin](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml)
|
||||
* [FluentD with GCP Plugin](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/fluentd-gcp/fluentd-gcp-ds.yaml)
|
||||
|
||||
Heapster的资源限制是基于集群的初始规模动态设置的 (参考 [#16185](http://issue.k8s.io/16185)
|
||||
和 [#22940](http://issue.k8s.io/22940))。 当发现Heapster资源耗尽,应考虑调整计算Heapster内存请求的公式 (参考上述PR)。
|
||||
|
||||
关于如何检测插件是否达到资源上限 参考 [计算资源的故障排除章节](/docs/concepts/configuration/manage-compute-resources-container/#troubleshooting)。
|
||||
|
||||
[将来](http://issue.k8s.io/13048),我们期望基于集群规模来设置集群插件的资源限制,并且在集群规模增长或缩小时能够动态调整。
|
||||
欢迎提出PR来实现这些特性。
|
||||
|
||||
### 启动时允许部分失败
|
||||
|
||||
因为种种原因 (详见 [#18969](https://github.com/kubernetes/kubernetes/issues/18969)),在 `NUM_NODES` 值很大的情况下执行
|
||||
`kube-up.sh`, 可能因为其中一小部分节点没有正常启动而失败。
|
||||
这时我们有两种选择:重启集群 (`kube-down.sh` 然后再 `kube-up.sh`),或者在执行 `kube-up.sh`之前,
|
||||
将环境变量 `ALLOWED_NOTREADY_NODES` 设置为合适的值。 这将允许 `kube-up.sh` 以少于 `NUM_NODES` 的节点数量启动集群。 依据失败的具体原因,另外的节点可能在后面加入集群,或者集群节点数量将保持在 `NUM_NODES - ALLOWED_NOTREADY_NODES`。
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: prometheus-node-exporter
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: prometheus-node-exporter
|
||||
labels:
|
||||
daemon: prom-node-exp
|
||||
spec:
|
||||
containers:
|
||||
- name: c
|
||||
image: prom/prometheus
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
hostPort: 9090
|
||||
name: serverport
|
||||
@@ -0,0 +1,214 @@
|
||||
---
|
||||
title: 构建高可用集群
|
||||
---
|
||||
|
||||
|
||||
## 简介
|
||||
|
||||
|
||||
本文描述了如何构建一个高可用(high-availability, HA)的Kubernetes集群。这是一个非常高级的主题。
|
||||
|
||||
对于仅希望使用Kubernetes进行试验的用户,推荐使用更简单的配置工具进行搭建,例如:
|
||||
[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) 来运行Kubernetes。
|
||||
|
||||
此外,当前在我们的端到端(e2e)测试环境中,没有对Kubernetes高可用的支持进行连续测试。我们将会增加这个连续测试项,但当前对单节点master的安装测试得更加严格。
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 概览
|
||||
|
||||
|
||||
搭建一个正真可靠,高度可用的分布式系统需要若干步骤。这类似于穿上内衣,裤子,皮带,背带,另一套内衣和另一套裤子。我们会详细介绍每一个步骤,但先在这里给出一个总结来帮助指导用户。
|
||||
|
||||
|
||||
相关步骤如下:
|
||||
|
||||
* [创建可靠的组成节点,共同形成我们的高可用主节点实现。](#可靠的节点)
|
||||
* [使用etcd集群,搭建一个冗余的,可靠的存储层。](#建立一个冗余的,可靠的存储层)
|
||||
* [启动具有备份和负载均衡能力的Kubernetes API 服务](#复制的API服务)
|
||||
* [搭建运行master选举的Kubernetes scheduler和controller-manager守护程序](#进行master选举的组件)
|
||||
|
||||
系统完成时看起来应该像这样:
|
||||
|
||||

|
||||
|
||||
|
||||
## 初始配置
|
||||
|
||||
|
||||
本文假设你正在搭建一个3节点的主节点集群,每个节点上都运行者某种Linux系统。
|
||||
|
||||
指南中的示例使用Debian发行版,但它们应该可以被轻松移植到其他发行版上。
|
||||
|
||||
同样的,不管在公有云还是私有云亦或是裸机上,这个配置都应该可以运行。
|
||||
|
||||
|
||||
从一个现成的单主节点集群开始是实现一个高可用Kubernetes集群的最简单的方法。这篇指导 [https://get.k8s.io](https://get.k8s.io) 描述了在多种平台上方便的安装一个单主节点集群的方法。
|
||||
|
||||
## 可靠的节点
|
||||
|
||||
|
||||
我们在每个主节点上都将运行数个实现Kubernetes API的进程。使他们可靠的第一步是保证在发生故障时,每一个进程都可以自动重启。为了实现这个目标,我们需要安装一个进程监视器。我们选择了在每个工作者节点上都会运行的`kubelet`进程。这会带来便利性,因为我们使用了容器来分发我们的二进制文件,所以我们能够为每一个守护程序建立资源限制并省查它们的资源消耗。当然,我们也需要一些手段来监控kubelete本身(在此监测监控者本身是一个有趣的话题)。对于Debian系统我们选择了monit,但也有许多可替代的工具。例如在基于systemd的系统上(如RHEL, CentOS),你可以运行 'systemctl enable kubelet'。
|
||||
|
||||
|
||||
如果你是从标准的Kubernetes安装扩展而来,那么`kubelet`二进制文件应该已经存在于你的系统中。你可以运行`which kubelet`来判断是否确实安装了这个二进制文件。如果没有安装的话,你应该手动安装 [kubelet binary](https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet),
|
||||
[kubelet init file](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/saltbase/salt/kubelet/initd) 和 [default-kubelet](/docs/admin/high-availability/default-kubelet)脚本。
|
||||
|
||||
如果使用monit,你还需要安装monit守护程序(`apt-get install monit`)以及[monit-kubelet](/docs/admin/high-availability/monit-kubelet) 和
|
||||
[monit-docker](/docs/admin/high-availability/monit-docker) 配置。
|
||||
|
||||
在使用systemd的系统上,你可以执行 `systemctl enable kubelet` 和 `systemctl enable docker`。
|
||||
|
||||
|
||||
## 建立一个冗余的,可靠的存储层
|
||||
|
||||
|
||||
高可用方案的中心基础是一个冗余的,可靠的存储层。高可用的头条规则是保护数据。不管发生了什么,不管什么着了火,只要还有数据,你就可以重建。如果丢掉了数据,你就完了。
|
||||
|
||||
|
||||
集群化的etcd已经把你存储的数据复制到了你集群中的所有主节点实例上。这意味着如果要想丢失数据,三个节点的物理(或虚拟)硬盘需要全部同时故障。这种情况发生的概率是比较低的,所以对于许多人来说,运行一个复制的etcd集群可能已经足够的可靠了。你可以将集群数量从3个增大到5个来增加集群的可靠性。如果那样还不够,你可以添加[更多的可靠性到你的存储层](#更加可靠的存储)。
|
||||
|
||||
|
||||
### 集群化etcd
|
||||
|
||||
|
||||
集群化etcd的完整细节超出了本文范围,你可以在[etcd clustering page](https://github.com/coreos/etcd/blob/master/Documentation/op-guide/clustering.md)找到许多详细内容。这个例子仅走查一个简单的集群建立过程,使用etcd内置的发现功能来构建我们的集群。
|
||||
|
||||
|
||||
首先,调用etcd发现服务来创建一个新令牌:
|
||||
|
||||
```shell
|
||||
curl https://discovery.etcd.io/new?size=3
|
||||
```
|
||||
|
||||
|
||||
在每个节点上,拷贝 [etcd.yaml](/docs/admin/high-availability/etcd.yaml) 文件到`/etc/kubernetes/manifests/etcd.yaml`。
|
||||
|
||||
|
||||
每个节点上的kubelet会动态的监控这个文件夹的内容,并且会按照`etcd.yaml`里对pod的定义创建一个`etcd`服务的实例。
|
||||
|
||||
|
||||
请注意,你应该使用上文中获取的令牌URL替换全部三个节点上`etcd.yaml`中的`${DISCOVERY_TOKEN}`项。同时还应该将每个节点上的 `${NODE_NAME}`替换为一个不同的名字(例如:`node-1`),并将 `${NODE_IP}`替换为正确的IP地址。
|
||||
|
||||
|
||||
#### 验证你的集群
|
||||
|
||||
|
||||
如果已经将这个文件拷贝到所有三个节点,你应该已经搭建起了一个集群化的etcd。你可以在主节点上进行验证:
|
||||
```shell
|
||||
kubectl exec < pod_name > etcdctl member list
|
||||
```
|
||||
|
||||
和
|
||||
|
||||
```shell
|
||||
kubectl exec < pod_name > etcdctl cluster-health
|
||||
```
|
||||
|
||||
|
||||
你也可以在一个节点上运行 `etcdctl set foo bar`,在另一个节点上运行`etcdctl get foo`来验证集群是否工作正常。
|
||||
|
||||
|
||||
### 更加可靠的存储
|
||||
|
||||
|
||||
当然,如果你对增加数据的可靠性感兴趣,这里还有一些更深入的选项可以使etcd把它的数据存放在比常规硬盘更可靠的地方(裤带和背带,ftw!)。
|
||||
|
||||
|
||||
如果你使用云服务,那么你的提供商通常会为你提供这个特性,例如Google Cloud Platform上的 [Persistent Disk](https://cloud.google.com/compute/docs/disks/persistent-disks) 。它们是可以挂载到你的虚拟机中的块设备持久化存储。其他的云服务提供商提供了类似的解决方案。
|
||||
|
||||
|
||||
如果运行于物理机之上,你仍然可以使用iSCSI或者NFS接口通过网络来连接冗余存储。
|
||||
此外,你还可以运行一个集群文件系统,比如Gluster或者Ceph。最后,你还可以在你的每个物理机器上运行RAID矩阵。
|
||||
|
||||
|
||||
不管你选择如何实现,如果已经选择了使用其中的一个选项,那么你应该保证你的存储被挂载到了每一台机器上。如果你的存储在集群中的三个主节点之间共享,那么你应该在存储上为每一个节点创建一个不同的文件夹。对于所有的这些指导,我们都假设这个存储被挂载到你机器上的`/var/etcd/data`路径。
|
||||
|
||||
|
||||
## 复制的API服务
|
||||
|
||||
|
||||
在正确搭建复制的etcd之后,我们还需要使用kubelet安装apiserver。
|
||||
|
||||
|
||||
|
||||
|
||||
首先,你需要创建初始的日志文件,这样Docker才会挂载一个文件而不是一个文件夹:
|
||||
```shell
|
||||
touch /var/log/kube-apiserver.log
|
||||
```
|
||||
|
||||
接下来,你需要在每个节点上创建一个`/srv/kubernetes/`文件夹。这个文件夹包含:
|
||||
|
||||
* basic_auth.csv - 基本认证的用户名和密码
|
||||
* ca.crt - CA证书
|
||||
* known_tokens.csv - 实体(例如kubelet)用来和apiserver通信的令牌
|
||||
* kubecfg.crt - 客户端证书,公钥
|
||||
* kubecfg.key - 客户端证书,私钥
|
||||
* server.cert - 服务端证书,公钥
|
||||
* server.key - 服务端证书,私钥
|
||||
|
||||
|
||||
创建这个文件夹最简单的方法可以是从一个工作正常的集群的主节点拷贝,或者你也可以手动生成它们。
|
||||
|
||||
|
||||
### 启动API服务
|
||||
|
||||
|
||||
一旦这些文件已经存在了,拷贝 [kube-apiserver.yaml](/docs/admin/high-availability/kube-apiserver.yaml) 到每个主节点的 `/etc/kubernetes/manifests/`文件夹。
|
||||
|
||||
|
||||
kubelet会监控这个文件夹,并且会按照文件里对pod的定义创建一个`kube-apiserver`容器。
|
||||
|
||||
|
||||
### 负载均衡
|
||||
|
||||
|
||||
现在,你应该有3个全部正常工作的apiserver了。如果搭建了网络负载均衡器,你应该能够通过那个负载均衡器访问你的集群,并且看到负载在apiserver实例间分发。设置负载均衡器依赖于你的平台的实际情况,例如对于Google Cloud Platform的指导可以在[这里](https://cloud.google.com/compute/docs/load-balancing/)找到。
|
||||
|
||||
|
||||
请注意,如果使用了身份认证,你可能需要重新生成你的证书,除每个节点的IP地址外额外包含负载均衡器的IP地址。
|
||||
|
||||
|
||||
对于部署在集群中的pods, `kubernetes`服务/dns名称应该自动的为主节点提供了负载均衡的endpoint。
|
||||
|
||||
|
||||
对于使用API的外部用户(如命令行运行的`kubectl`,持续集成管道或其他客户端)你会希望将他们配置成为访问外部负载均衡器的地址。
|
||||
|
||||
|
||||
## 进行Master选举的组件
|
||||
|
||||
|
||||
到目前为止,我们已经搭建了状态存储,也搭建好了API服务,但我们还没有运行任何真正改变集群状态的服务,比如controller manager和scheduler。为了可靠的实现这个目标,我们希望在同一时间只有一个参与者在修改集群状态。但是我们希望复制这些参与者的实例以防某个机器宕机。要做到这一点,我们打算在API中使用一个lease-lock来执行master选举。我们会对每一个scheduler和controller-manager使用`--leader-elect`标志,从而在API中使用一个租约来保证同一时间只有一个scheduler和controller-manager的实例正在运行。
|
||||
|
||||
|
||||
scheduler和controller-manager可以配置为只和位于它们相同节点(即127.0.0.1)上的API服务通信,也可以配置为使用API服务的负载均衡器的IP地址。不管它们如何配置,当使用`--leader-elect` 时scheduler和controller-manager都将完成上文提到的leader选举过程。
|
||||
|
||||
|
||||
为了防止访问API服务失败,选举出的leader不能通过更新租约来选举一个新的leader。当scheduler和controller-manager通过127.0.0.1访问API服务,而相同节点上的API服务不可用时,这一点相当重要。
|
||||
|
||||
|
||||
### 安装配置文件
|
||||
|
||||
|
||||
首先,在每个节点上创建空白日志文件,这样Docker就会挂载这些文件而不是创建一个新文件夹:
|
||||
|
||||
```shell
|
||||
touch /var/log/kube-scheduler.log
|
||||
touch /var/log/kube-controller-manager.log
|
||||
```
|
||||
|
||||
|
||||
接下来,在每个节点上配置scheduler和controller manager pods的描述文件。拷贝 [kube-scheduler.yaml](/docs/admin/high-availability/kube-scheduler.yaml) 和 [kube-controller-manager.yaml](/docs/admin/high-availability/kube-controller-manager.yaml) 到`/etc/kubernetes/manifests/` 文件夹。
|
||||
|
||||
|
||||
## 结尾
|
||||
|
||||
|
||||
此时,你已经完成了master组件的配置(耶!),但你还需要添加工作者节点(噗!)。
|
||||
|
||||
|
||||
如果你有一个现成的集群,你只需要在每个节点上简单的重新配置你的kubeletes连接到负载均衡的endpoint并重启它们。
|
||||
|
||||
|
||||
如果你搭建的是一个全新的集群,你将需要在每个工作节点上安装kubelet和kube-proxy,并设置 `--apiserver`指向复制的endpoint。
|
||||
@@ -0,0 +1,233 @@
|
||||
---
|
||||
title: kube-apiserver
|
||||
notitle: true
|
||||
---
|
||||
## kube-apiserver
|
||||
|
||||
|
||||
|
||||
### 概要
|
||||
|
||||
|
||||
Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、 replicationcontrollers和其它 api 对象。API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。
|
||||
|
||||
```
|
||||
kube-apiserver
|
||||
```
|
||||
|
||||
### 选项
|
||||
```
|
||||
|
||||
--admission-control stringSlice 控制资源进入集群的准入控制插件的顺序列表。逗号分隔的NamespaceLifecycle列表。(默认值[AlwaysAdmit])
|
||||
|
||||
--admission-control-config-file string 包含准入控制配置的文件。
|
||||
|
||||
--advertise-address ip 向集群成员通知apiserver消息的IP地址。这个地址必须能够被集群中其他成员访问。如果IP地址为空,将会使用--bind-address,如果未指定--bind-address,将会使用主机的默认接口地址。
|
||||
|
||||
--allow-privileged 如果为true, 将允许特权容器.
|
||||
|
||||
--anonymous-auth 启用到API server的安全端口的匿名请求。未被其他认证方法拒绝的请求被当做匿名请求。匿名请求的用户名为system:anonymous,用户组名为system:unauthenticated。(默认值true)
|
||||
|
||||
--apiserver-count int 集群中运行的apiserver数量,必须为正数。(默认值1)
|
||||
|
||||
--audit-log-maxage int 基于文件名中的时间戳,旧审计日志文件的最长保留天数。
|
||||
|
||||
--audit-log-maxbackup int 旧审计日志文件的最大保留个数.
|
||||
|
||||
--audit-log-maxsize int 审计日志被轮转前的最大兆字节数。
|
||||
|
||||
--audit-log-path string 如果设置该值,所有到apiserver的请求都将会被记录到这个文件。'-'表示记录到标准输出。
|
||||
|
||||
--audit-policy-file string 定义审计策略配置的文件的路径。需要打开'AdvancedAuditing'特性开关。AdvancedAuditing需要一个配置来启用审计功能。
|
||||
|
||||
--audit-webhook-config-file string 一个具有kubeconfig格式文件的路径,该文件定义了审计的webhook配置。需要打开'AdvancedAuditing'特性开关。
|
||||
|
||||
--audit-webhook-mode string 发送审计事件的策略。 Blocking模式表示正在发送事件时应该阻塞服务器的响应。 Batch模式使webhook异步缓存和发送事件。 Known模式为batch,blocking。 (默认值"batch")
|
||||
|
||||
--authentication-token-webhook-cache-ttl duration 从webhook令牌认证者获取的响应的缓存时长。(默认值2m0s)
|
||||
|
||||
--authentication-token-webhook-config-file string 包含webhook配置的文件,用于令牌认证,具有kubeconfig格式。API server将查询远程服务来决定对bearer令牌的认证。
|
||||
|
||||
--authorization-mode string 在安全端口上进行权限验证的插件的顺序列表。以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值"AlwaysAllow")
|
||||
|
||||
--authorization-policy-file string 包含权限验证策略的csv文件,和--authorization-mode=ABAC一起使用,作用在安全端口上。
|
||||
|
||||
--authorization-webhook-cache-authorized-ttl duration 从webhook授权者获得的'authorized'响应的缓存时长。(默认值5m0s)
|
||||
|
||||
--authorization-webhook-cache-unauthorized-ttl duration 从webhook授权者获得的'unauthorized'响应的缓存时长。(默认值30s)
|
||||
|
||||
--authorization-webhook-config-file string 包含webhook配置的kubeconfig格式文件,和--authorization-mode=Webhook一起使用。API server将查询远程服务来决定对API server安全端口的访问。
|
||||
|
||||
--azure-container-registry-config string 包含Azure容器注册表配置信息的文件的路径。
|
||||
|
||||
--basic-auth-file string 如果设置该值,这个文件将会被用于准许通过http基本认证到API server安全端口的请求。
|
||||
|
||||
--bind-address ip 监听--seure-port的IP地址。被关联的接口必须能够被集群其它节点和CLI/web客户端访问。如果为空,则将使用所有接口(0.0.0.0)。(默认值0.0.0.0)
|
||||
|
||||
--cert-dir string 存放TLS证书的目录。如果提供了--tls-cert-file和--tls-private-key-file选项,该标志将被忽略。(默认值 "/var/run/kubernetes")
|
||||
|
||||
--client-ca-file string 如果设置此标志,对于任何请求,如果存包含client-ca-file中的authorities签名的客户端证书,将会使用客户端证书中的CommonName对应的身份进行认证。
|
||||
|
||||
--cloud-config string 云服务提供商配置文件路径。空字符串表示无配置文件.
|
||||
|
||||
--cloud-provider string 云服务提供商,空字符串表示无提供商。
|
||||
|
||||
--contention-profiling 如果已经启用profiling,则启用锁竞争profiling。
|
||||
|
||||
--cors-allowed-origins stringSlice CORS的域列表,以逗号分隔。合法的域可以是一个匹配子域名的正则表达式。如果这个列表为空则不会启用CORS.
|
||||
|
||||
--delete-collection-workers int 用于DeleteCollection调用的工作者数量。这被用于加速namespace的清理。(默认值1)
|
||||
|
||||
--deserialization-cache-size int 在内存中缓存的反序列化json对象的数量。
|
||||
|
||||
--enable-aggregator-routing 打开到endpoints IP的aggregator路由请求,替换cluster IP。
|
||||
|
||||
--enable-garbage-collector 启用通用垃圾回收器. 必须与kube-controller-manager对应的标志保持同步。 (默认值true)
|
||||
|
||||
--enable-logs-handler 如果为true,则为apiserver日志功能安装一个/logs处理器。(默认值true)
|
||||
|
||||
--enable-swagger-ui 在apiserver的/swagger-ui路径启用swagger ui。
|
||||
|
||||
--etcd-cafile string 用于保护etcd通信的SSL CA文件。
|
||||
|
||||
--etcd-certfile string 用于保护etcd通信的的SSL证书文件。
|
||||
|
||||
--etcd-keyfile string 用于保护etcd通信的SSL密钥文件.
|
||||
|
||||
--etcd-prefix string 附加到所有etcd中资源路径的前缀。 (默认值"/registry")
|
||||
|
||||
--etcd-quorum-read 如果为true, 启用quorum读。
|
||||
|
||||
--etcd-servers stringSlice 连接的etcd服务器列表,形式为(scheme://ip:port),使用逗号分隔。
|
||||
|
||||
--etcd-servers-overrides stringSlice 针对单个资源的etcd服务器覆盖配置, 以逗号分隔。 单个配置覆盖格式为: group/resource#servers, 其中servers形式为http://ip:port, 以分号分隔。
|
||||
|
||||
--event-ttl duration 事件驻留时间。(默认值1h0m0s)
|
||||
|
||||
--experimental-bootstrap-token-auth 启用此选项以允许'kube-system'命名空间中的'bootstrap.kubernetes.io/token'类型密钥可以被用于TLS的启动认证。
|
||||
|
||||
--experimental-encryption-provider-config string 包含加密提供程序的配置的文件,该加密提供程序被用于在etcd中保存密钥。
|
||||
|
||||
--experimental-keystone-ca-file string 如果设置该值,将会使用experimental-keystone-ca-file中的一个authority对Keystone服务的证书进行验证,否则将会使用主机的根CA进行验证。
|
||||
|
||||
--experimental-keystone-url string 如果设置了该值,将启用keystone认证插件。
|
||||
|
||||
--external-hostname string 为此master生成外部URL时使用的主机名(例如Swagger API文档)。
|
||||
|
||||
--feature-gates mapStringBool 一个描述alpha/experimental特性开关的键值对列表。 选项包括:
|
||||
Accelerators=true|false (ALPHA - default=false)
|
||||
AdvancedAuditing=true|false (ALPHA - default=false)
|
||||
AffinityInAnnotations=true|false (ALPHA - default=false)
|
||||
AllAlpha=true|false (ALPHA - default=false)
|
||||
AllowExtTrafficLocalEndpoints=true|false (default=true)
|
||||
AppArmor=true|false (BETA - default=true)
|
||||
DynamicKubeletConfig=true|false (ALPHA - default=false)
|
||||
DynamicVolumeProvisioning=true|false (ALPHA - default=true)
|
||||
ExperimentalCriticalPodAnnotation=true|false (ALPHA - default=false)
|
||||
ExperimentalHostUserNamespaceDefaulting=true|false (BETA - default=false)
|
||||
LocalStorageCapacityIsolation=true|false (ALPHA - default=false)
|
||||
PersistentLocalVolumes=true|false (ALPHA - default=false)
|
||||
RotateKubeletClientCertificate=true|false (ALPHA - default=false)
|
||||
RotateKubeletServerCertificate=true|false (ALPHA - default=false)
|
||||
StreamingProxyRedirects=true|false (BETA - default=true)
|
||||
TaintBasedEvictions=true|false (ALPHA - default=false)
|
||||
|
||||
--google-json-key string 用于认证的Google Cloud Platform服务账号的JSON密钥。
|
||||
|
||||
--insecure-allow-any-token username/group1,group2 如果设置该值, 你的服务将处于非安全状态。任何令牌都将会被允许,并将从令牌中把用户信息解析成为username/group1,group2。
|
||||
|
||||
--insecure-bind-address ip 用于监听--insecure-port的IP地址 (设置成0.0.0.0表示监听所有接口)。(默认值127.0.0.1)
|
||||
|
||||
--insecure-port int 用于监听不安全和为认证访问的端口。这个配置假设你已经设置了防火墙规则,使得这个端口不能从集群外访问。对集群的公共地址的443端口的访问将被代理到这个端口。默认设置中使用nginx实现。(默认值8080)
|
||||
|
||||
--kubelet-certificate-authority string 证书authority的文件路径。
|
||||
|
||||
--kubelet-client-certificate string 用于TLS的客户端证书文件路径。
|
||||
|
||||
--kubelet-client-key string 用于TLS的客户端证书密钥文件路径.
|
||||
|
||||
--kubelet-https 为kubelet启用https。 (默认值true)
|
||||
|
||||
--kubelet-preferred-address-types stringSlice 用于kubelet连接的首选NodeAddressTypes列表。 (默认值[Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP])
|
||||
|
||||
--kubelet-read-only-port uint 已废弃: kubelet端口. (默认值10255)
|
||||
|
||||
--kubelet-timeout duration kubelet操作超时时间。(默认值
|
||||
5s)
|
||||
|
||||
--kubernetes-service-node-port int 如果不为0,Kubernetes master服务(用于创建/管理apiserver)将会使用NodePort类型,并将这个值作为端口号。如果为0,Kubernetes master服务将会使用ClusterIP类型。
|
||||
|
||||
--master-service-namespace string 已废弃: 注入到pod中的kubernetes master服务的命名空间。(默认值"default")
|
||||
|
||||
--max-connection-bytes-per-sec int 如果不为0,每个用户连接将会被限速为该值(bytes/sec)。当前只应用于长时间运行的请求。
|
||||
|
||||
--max-mutating-requests-inflight int 在给定时间内进行中可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值200)
|
||||
|
||||
--max-requests-inflight int 在给定时间内进行中不可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值400)
|
||||
|
||||
--min-request-timeout int 一个可选字段,表示一个handler在一个请求超时前,必须保持它处于打开状态的最小秒数。当前只对监听请求handler有效,它基于这个值选择一个随机数作为连接超时值,以达到分散负载的目的(默认值1800)。
|
||||
|
||||
--oidc-ca-file string 如果设置该值,将会使用oidc-ca-file中的任意一个authority对OpenID服务的证书进行验证,否则将会使用主机的根CA对其进行验证。
|
||||
|
||||
--oidc-client-id string 使用OpenID连接的客户端的ID,如果设置了oidc-issuer-url,则必须设置这个值。
|
||||
|
||||
--oidc-groups-claim string 如果提供该值,这个自定义OpenID连接名将指定给特定的用户组。该声明值需要是一个字符串或字符串数组。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。
|
||||
|
||||
--oidc-issuer-url string OpenID颁发者URL,只接受HTTPS方案。如果设置该值,它将被用于验证OIDC JSON Web Token(JWT)。
|
||||
|
||||
--oidc-username-claim string 用作用户名的OpenID声明值。注意,不保证除默认 ('sub')外的其他声明值的唯一性和不变性。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。
|
||||
|
||||
--profiling 在web接口host:port/debug/pprof/上启用profiling。(默认值true)
|
||||
|
||||
--proxy-client-cert-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。它期望这个证书包含一个来自于CA中的--requestheader-client-ca-file标记的签名。该CA在kube-system命名空间的'extension-apiserver-authentication' configmap中发布。从Kube-aggregator收到调用的组件应该使用该CA进行他们部分的双向TLS验证。
|
||||
|
||||
--proxy-client-key-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书密钥。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。
|
||||
|
||||
--repair-malformed-updates 如果为true,服务将会尽力修复更新请求以通过验证,例如:将更新请求UID的当前值设置为空。在我们修复了所有发送错误格式请求的客户端后,可以关闭这个标志。
|
||||
|
||||
--requestheader-allowed-names stringSlice 使用--requestheader-username-headers指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过--requestheader-client-ca-file中authorities验证的客户端证书都是被允许的。
|
||||
|
||||
--requestheader-client-ca-file string 在信任请求头中以--requestheader-username-headers指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。
|
||||
|
||||
--requestheader-extra-headers-prefix stringSlice 用于检查的请求头的前缀列表。建议使用X-Remote-Extra-。
|
||||
|
||||
--requestheader-group-headers stringSlice 用于检查群组的请求头列表。建议使用X-Remote-Group.
|
||||
|
||||
--requestheader-username-headers stringSlice 用于检查用户名的请求头列表。建议使用X-Remote-User。
|
||||
|
||||
--runtime-config mapStringString 传递给apiserver用于描述运行时配置的键值对集合。 apis/<groupVersion>键可以被用来打开/关闭特定的api版本。apis/<groupVersion>/<resource>键被用来打开/关闭特定的资源. api/all和api/legacy键分别用于控制所有的和遗留的api版本.
|
||||
|
||||
--secure-port int 用于监听具有认证授权功能的HTTPS协议的端口。如果为0,则不会监听HTTPS协议。 (默认值6443)
|
||||
|
||||
--service-account-key-file stringArray 包含PEM加密的x509 RSA或ECDSA私钥或公钥的文件,用于验证ServiceAccount令牌。如果设置该值,--tls-private-key-file将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。
|
||||
|
||||
--service-cluster-ip-range ipNet CIDR表示的IP范围,服务的cluster ip将从中分配。 一定不要和分配给nodes和pods的IP范围产生重叠。
|
||||
|
||||
--ssh-keyfile string 如果不为空,在使用安全的SSH代理访问节点时,将这个文件作为用户密钥文件。
|
||||
|
||||
--storage-backend string 持久化存储后端。 选项为: 'etcd3' (默认), 'etcd2'.
|
||||
|
||||
--storage-media-type string 在存储中保存对象的媒体类型。某些资源或者存储后端可能仅支持特定的媒体类型,并且忽略该配置项。(默认值 "application/vnd.kubernetes.protobuf")
|
||||
|
||||
--storage-versions string 按组划分资源存储的版本。 以"group1/version1,group2/version2,..."的格式指定。当对象从一组移动到另一组时, 你可以指定"group1=group2/v1beta1,group3/v1beta1,..."的格式。你只需要传入你希望从结果中改变的组的列表。默认为从KUBE_API_VERSIONS环境变量集成而来,所有注册组的首选版本列表。 (默认值"admission.k8s.io/v1alpha1,admissionregistration.k8s.io/v1alpha1,apps/v1beta1,authentication.k8s.io/v1,authorization.k8s.io/v1,autoscaling/v1,batch/v1,certificates.k8s.io/v1beta1,componentconfig/v1alpha1,extensions/v1beta1,federation/v1beta1,imagepolicy.k8s.io/v1alpha1,networking.k8s.io/v1,policy/v1beta1,rbac.authorization.k8s.io/v1beta1,settings.k8s.io/v1alpha1,storage.k8s.io/v1,v1")
|
||||
|
||||
--target-ram-mb int apiserver内存限制,单位为MB(用于配置缓存大小等)。
|
||||
|
||||
--tls-ca-file string 如果设置该值,这个证书authority将会被用于从Admission Controllers过来的安全访问。它必须是一个PEM加密的合法CA捆绑包。此外, 该证书authority可以被添加到以--tls-cert-file提供的证书文件中.
|
||||
|
||||
--tls-cert-file string 包含用于HTTPS的默认x509证书的文件。(如果有CA证书,则附加于server证书之后)。如果启用了HTTPS服务,并且没有提供--tls-cert-file和--tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于/var/run/kubernetes目录。
|
||||
|
||||
--tls-private-key-file string 包含匹配--tls-cert-file的x509证书私钥的文件。
|
||||
|
||||
--tls-sni-cert-key namedCertKey 一对x509证书和私钥的文件路径, 可以使用符合正式域名的域形式作为后缀。 如果没有提供域形式后缀, 则将提取证书名。 非通配符版本优先于通配符版本, 显示的域形式优先于证书中提取的名字。 对于多个密钥/证书对, 请多次使用--tls-sni-cert-key。例如: "example.crt,example.key" or "foo.crt,foo.key:*.foo.com,foo.com". (默认值[])
|
||||
|
||||
--token-auth-file string 如果设置该值,这个文件将被用于通过令牌认证来保护API服务的安全端口。
|
||||
|
||||
--version version[=true] 打印版本信息并退出。
|
||||
|
||||
--watch-cache 启用apiserver的监视缓存。(默认值true)
|
||||
|
||||
--watch-cache-sizes stringSlice 每种资源(pods, nodes等)的监视缓存大小列表,以逗号分隔。每个缓存配置的形式为:resource#size,size是一个数字。在watch-cache启用时生效。
|
||||
```
|
||||
|
||||
###### Auto generated by spf13/cobra on 11-Jul-2017
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
approvers:
|
||||
- liggitt
|
||||
title: Kubelet authentication/authorization
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 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.
|
||||
|
||||
This document describes how to authenticate and authorize access to the kubelet's HTTPS endpoint.
|
||||
|
||||
## Kubelet authentication
|
||||
|
||||
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`.
|
||||
|
||||
To disable anonymous access and send `401 Unauthorized` responses to unauthenticated requests:
|
||||
|
||||
* start the kubelet with the `--anonymous-auth=false` flag
|
||||
|
||||
To enable X509 client certificate authentication to the kubelet's HTTPS endpoint:
|
||||
|
||||
* 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/admin/authentication/#x509-client-certs) for more details
|
||||
|
||||
To enable API bearer tokens (including service account tokens) to be used to authenticate to the kubelet's HTTPS endpoint:
|
||||
|
||||
* 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
|
||||
|
||||
## Kubelet authorization
|
||||
|
||||
Any request that is successfully authenticated (including an anonymous request) is then authorized. The default authorization mode is `AlwaysAllow`, which allows all requests.
|
||||
|
||||
There are many possible reasons to subdivide access to the 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
|
||||
|
||||
To subdivide access to the kubelet API, delegate authorization to the API server:
|
||||
|
||||
* 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
|
||||
|
||||
The kubelet authorizes API requests using the same [request attributes](/docs/admin/authorization/#request-attributes) approach as the apiserver.
|
||||
|
||||
The verb is determined from the incoming request's HTTP verb:
|
||||
|
||||
HTTP verb | request verb
|
||||
----------|---------------
|
||||
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
|
||||
-------------|----------|------------
|
||||
/stats/\* | nodes | stats
|
||||
/metrics/\* | nodes | metrics
|
||||
/logs/\* | nodes | log
|
||||
/spec/\* | nodes | spec
|
||||
*all others* | 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.
|
||||
|
||||
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:
|
||||
|
||||
* 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,214 @@
|
||||
---
|
||||
approvers:
|
||||
- ericchiang
|
||||
- mikedanese
|
||||
- jcbsmpsn
|
||||
title: TLS bootstrapping
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes how to set up TLS client certificate bootstrapping for kubelets.
|
||||
Kubernetes 1.4 introduced an API for requesting certificates from a cluster-level Certificate Authority (CA). The original intent of this API is to enable provisioning of TLS client certificates for kubelets. The proposal can be found [here](https://github.com/kubernetes/kubernetes/pull/20439)
|
||||
and progress on the feature is being tracked as [feature #43](https://github.com/kubernetes/features/issues/43).
|
||||
|
||||
## kube-apiserver configuration
|
||||
|
||||
The API server should be configured with an [authenticator](/docs/admin/authentication/) that can authenticate tokens as a user in the `system:bootstrappers` group.
|
||||
|
||||
This group will later be used in the controller-manager configuration to scope approvals in the default approval
|
||||
controller. 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) strictly to client requests related to certificate provisioning. With RBAC in place, scoping the tokens to a group allows for great flexibility (e.g. you could disable a particular bootstrap group's access when you are done provisioning the nodes).
|
||||
|
||||
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](/docs/admin/bootstrap-tokens/) - __alpha__
|
||||
2. [Token authentication file](###token-authentication-file)
|
||||
|
||||
Using bootstrap tokens is currently __alpha__ and will simplify the management of bootstrap token management especially in a HA scenario.
|
||||
|
||||
### Token authentication file
|
||||
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 systems). There are multiple ways you can generate a token. For example:
|
||||
|
||||
`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,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/admin/authentication/#static-token-file) for further details.
|
||||
|
||||
### Client certificate CA bundle
|
||||
|
||||
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 (e.g. `--client-ca-file=/var/lib/kubernetes/ca.pem`).
|
||||
|
||||
## kube-controller-manager configuration
|
||||
The API for requesting certificates adds a certificate-issuing control loop to the Kubernetes Controller Manager. 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.
|
||||
|
||||
### Signing assets
|
||||
You must provide a Certificate Authority in order to provide the cryptographic materials necessary to issue certificates.
|
||||
This CA should be trusted by kube-apiserver for authentication with the `--client-ca-file=FILENAME` flag. The management
|
||||
of the CA is beyond the scope of this document but it is recommended that you generate a dedicated CA for Kubernetes.
|
||||
Both certificate and key are assumed to be PEM-encoded.
|
||||
|
||||
The kube-controller-manager flags are:
|
||||
|
||||
```
|
||||
--cluster-signing-cert-file="/etc/path/to/kubernetes/ca/ca.crt" --cluster-signing-key-file="/etc/path/to/kubernetes/ca/ca.key"
|
||||
```
|
||||
|
||||
### Approval controller
|
||||
|
||||
In 1.7 the experimental "group auto approver" controller is dropped in favor of the new `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/admin/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, only ignoring unauthorized requests.
|
||||
|
||||
The controller categorizes CSRs into three subresources:
|
||||
|
||||
1. `nodeclient` - a request by a user for a client certificate with `O=system:nodes` and `CN=system:node:(node name)`.
|
||||
2. `selfnodeclient` - a node renewing a client certificate with the same `O` and `CN`.
|
||||
3. `selfnodeserver` - a node renewing a serving certificate. (ALPHA, requires feature gate)
|
||||
|
||||
The checks to determine if a CSR is a `selfnodeserver` request is currently tied to the kubelet's credential rotation
|
||||
implementation, an __alpha__ feature. As such, the definition of `selfnodeserver` will likely change in a future and
|
||||
requires the `RotateKubeletServerCertificate` feature gate on the controller manager. The feature progress can be
|
||||
tracked at [kubernetes/features#267](https://github.com/kubernetes/features/issues/267).
|
||||
|
||||
```
|
||||
--feature-gates=RotateKubeletServerCertificate=true
|
||||
```
|
||||
|
||||
The following RBAC `ClusterRoles` represent the `nodeclient`, `selfnodeclient`, and `selfnodeserver` capabilities. Similar roles
|
||||
may be automatically created in future releases.
|
||||
|
||||
```yml
|
||||
# A ClusterRole which instructs the CSR approver to approve a user requesting
|
||||
# node client credentials.
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: approve-node-client-csr
|
||||
rules:
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests/nodeclient"]
|
||||
verbs: ["create"]
|
||||
---
|
||||
# A ClusterRole which instructs the CSR approver to approve a node renewing its
|
||||
# own client credentials.
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: approve-node-client-renewal-csr
|
||||
rules:
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests/selfnodeclient"]
|
||||
verbs: ["create"]
|
||||
---
|
||||
# A ClusterRole which instructs the CSR approver to approve a node requesting a
|
||||
# serving cert matching its client cert.
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: approve-node-server-renewal-csr
|
||||
rules:
|
||||
- apiGroups: ["certificates.k8s.io"]
|
||||
resources: ["certificatesigningrequests/selfnodeserver"]
|
||||
verbs: ["create"]
|
||||
```
|
||||
|
||||
These powers can be granted to credentials, such as bootstrapping tokens. For example, to replicate the behavior
|
||||
provided by the removed auto-approval flag, of approving all CSRs by a single group:
|
||||
|
||||
```
|
||||
# REMOVED: This flag no longer works as of 1.7.
|
||||
--insecure-experimental-approve-all-kubelet-csrs-for-group="system:bootstrappers"
|
||||
```
|
||||
|
||||
An admin would create a `ClusterRoleBinding` targeting that group.
|
||||
|
||||
```yml
|
||||
# Approve all CSRs for the group "system:bootstrappers"
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: auto-approve-csrs-for-group
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:bootstrappers
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: approve-node-client-csr
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
To let a node renew its own credentials, an admin can construct a `ClusterRoleBinding` targeting
|
||||
that node's credentials:
|
||||
|
||||
```yml
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: node1-client-cert-renewal
|
||||
subjects:
|
||||
- kind: User
|
||||
name: system:node:node-1 # Let "node-1" renew its client certificate.
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: approve-node-client-renewal-csr
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
Deleting the binding will prevent the node from renewing its client credentials, effectively
|
||||
removing it from the cluster once its certificate expires.
|
||||
|
||||
## kubelet configuration
|
||||
To request a client certificate from kube-apiserver, the kubelet first needs a path to a kubeconfig file that contains the
|
||||
bootstrap authentication token. You can use `kubectl config set-cluster`, `set-credentials`, and `set-context` to build this kubeconfig. Provide the name `kubelet-bootstrap` to `kubectl config set-credentials` and include `--token=<token-value>` as follows:
|
||||
|
||||
```
|
||||
kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=bootstrap.kubeconfig
|
||||
```
|
||||
|
||||
When starting the kubelet, if the file specified by `--kubeconfig` does not exist, the 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`.
|
||||
|
||||
**Note:** The following flags are required to enable this bootstrapping when starting the kubelet:
|
||||
|
||||
```
|
||||
--bootstrap-kubeconfig="/path/to/bootstrap/kubeconfig"
|
||||
```
|
||||
|
||||
Additionally, in 1.7 the kubelet implements __alpha__ features for enabling rotation of both its client and/or serving certs.
|
||||
These can be enabled through the respective `RotateKubeletClientCertificate` and `RotateKubeletServerCertificate` feature
|
||||
flags on the kubelet, but may change in backward incompatible ways in future releases.
|
||||
|
||||
```
|
||||
--feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true
|
||||
```
|
||||
|
||||
`RotateKubeletClientCertificate` causes the kubelet to rotate its client certificates by creating new CSRs as its existing
|
||||
credentials expire. `RotateKubeletServerCertificate` causes the kubelet to both request a serving certificate after
|
||||
bootstrapping its client credentials and rotate the certificate. The serving cert currently does not request DNS or IP
|
||||
SANs.
|
||||
|
||||
## kubectl approval
|
||||
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 is intended to eventually be an automated process handled by an external
|
||||
approval controller, but for the alpha version of the API it can be done manually by a cluster administrator using kubectl.
|
||||
An administrator can list CSRs with `kubectl get csr` and describe one in detail with `kubectl describe csr <name>`. Before the 1.6 release there were
|
||||
[no direct approve/deny commands](https://github.com/kubernetes/kubernetes/issues/30163) so an approver had to update
|
||||
the Status field directly ([rough how-to](https://github.com/gtank/csrctl)). Later versions of Kubernetes offer `kubectl certificate approve <name>` and `kubectl certificate deny <name>` commands.
|
||||
@@ -0,0 +1,291 @@
|
||||
---
|
||||
approvers:
|
||||
- jlowdermilk
|
||||
- justinsb
|
||||
- quinton-hoole
|
||||
title: 多区域运行
|
||||
---
|
||||
|
||||
## 介绍
|
||||
|
||||
Kubernetes 从v1.2开始支持将集群运行在多个故障域中。
|
||||
(GCE 中称其为 "区(Zones)", AWS 中称其为 "可用区(Availability Zones)",这里我们也称其为 "区")。
|
||||
它是广泛意义上的集群联邦特性的轻量级版本 (之前被称为 ["Ubernetes"](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md))。
|
||||
完整的集群联邦能够将多个分别运行在不同区或云供应商(或本地数据中心)的集群集中管理。
|
||||
然而,很多用户只是希望通过将单一云供应商上的Kubernetes集群运行在多个区域,来提高集群的可用性,
|
||||
这就是1.2版本中提供的对多区域的支持。
|
||||
(之前被称为 "Ubernetes Lite")。
|
||||
|
||||
多区域的支持是有明确限制的: Kubernetes集群能够运行在多个区,但必须在同一个地域内 (云供应商也须一致)。
|
||||
目前只有GCE和AWS自动支持 (尽管在其他云甚至裸机上,也很容易通过为节点和卷添加合适的标签来实现类似的支持)。
|
||||
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## 功能
|
||||
|
||||
节点启动时,Kubelet自动为其添加区信息的标签。
|
||||
|
||||
在单一区域的集群中,Kubernetes 会自动将副本管理器或服务的pod分布到各节点上 (以减轻单实例故障的影响)。
|
||||
在多区域的集群中,这种分布的行为扩展到了区域级别
|
||||
(以减少区域故障对整体的影响)。 (通过 `SelectorSpreadPriority` 来实现)。
|
||||
这种分发是尽力而为(best-effort)的,所以如果集群在各个区之间是异构的
|
||||
(比如,各区间的节点数量不同、节点类型不同、pod的资源需求不同等)可能导致pod无法完全均匀地分布。
|
||||
如果需要的话,用户可以使用同质的区(节点数量和节点类型相同)来减少区域之间分配不均匀的可能。
|
||||
|
||||
当卷被创建时, `PersistentVolumeLabel`准入控制器会自动为其添加区域的标签。
|
||||
调度器 (通过 `VolumeZonePredicate` 断言) 会确申领该卷的pod被调度到该卷对应的区域,
|
||||
因为卷是不支持跨区挂载的。
|
||||
|
||||
## 限制
|
||||
|
||||
对多区的支持有一些重要的限制:
|
||||
|
||||
* 我们假设不同的区域间在网络上离得很近,所以我们不做任何的区域感知路由。 特别是,通过服务的网络访问可能跨区域 (即使该服务后端pod的其中一些运行在与客户端相同的区域中),这可能导致额外的延迟和损耗。
|
||||
|
||||
* 卷的区域亲和性只对 `PersistentVolume`有效。 例如,如果你在pod的spec中直接指定一个EBS的卷,则不会生效。
|
||||
|
||||
* 集群不支持跨云平台或地域 (这些功能需要完整的集群联邦特性支持)。
|
||||
|
||||
* 尽管节点位于多区域,目前默认情况下 kube-up 创建的管理节点是单实例的。 所以尽管服务是高可用的,并且能够容忍跨区域的性能损耗,管理平面还是单区域的。 需要高可用的管理平面的用户可以按照 [高可用](/docs/admin/high-availability) 指导来操作。
|
||||
|
||||
* 目前StatefulSet的卷动态创建时的跨区域分配,与pod的亲和性/反亲和性不兼容。
|
||||
|
||||
* StatefulSet的名称包含破折号 ("-")时,可能影响到卷在区域间的均匀分布。
|
||||
|
||||
* 为deployment或pod指定多个PVC时,要求其StorageClass处于同一区域内,否则,相应的PV卷需要在一个区域中静态配置。 另一种方式是使用StatefulSet,这可以确保同一副本所挂载的卷位于同一区内。
|
||||
|
||||
|
||||
## 演练
|
||||
|
||||
接下来我们将介绍如何同时在 GCE 和 AWS 上创建和使用多区域的集群。 为此,你需要创建一个完整的集群
|
||||
(指定 `MULTIZONE=true`),然后再次执行 `kube-up`(指定 `KUBE_USE_EXISTING_MASTER=true`)来添加其他区域的节点。
|
||||
|
||||
### 创建集群
|
||||
|
||||
按正常方式创建集群,但是传入 MULTIZONE 来通知集群对多区域进行管理。 在 us-central1-a 区域创建节点。
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a NUM_NODES=3 bash
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a NUM_NODES=3 bash
|
||||
```
|
||||
|
||||
该步骤按正常方式创建了集群,仍然运行在单个区域中。
|
||||
但 `MULTIZONE=true` 已经开启了多区域的能力。
|
||||
|
||||
### 标记节点
|
||||
|
||||
查看节点,你可以发现节点上打了区域信息的标签。
|
||||
节点位于 `us-central1-a` (GCE) 或者 `us-west-2a` (AWS)。 标签 `failure-domain.beta.kubernetes.io/region` 用于区分地域,
|
||||
标签 `failure-domain.beta.kubernetes.io/zone` 用于区分区域。
|
||||
|
||||
```shell
|
||||
> kubectl get nodes --show-labels
|
||||
|
||||
|
||||
NAME STATUS AGE VERSION LABELS
|
||||
kubernetes-master Ready,SchedulingDisabled 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
|
||||
kubernetes-minion-87j9 Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
|
||||
kubernetes-minion-9vlv Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-a12q Ready 6m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
|
||||
```
|
||||
|
||||
### 添加其它区中的节点
|
||||
|
||||
接下来我们复用已有的管理节点,添加运行于其它区域 (us-central1-b或us-west-2b)中的节点。
|
||||
再次执行 kube-up, 通过指定 `KUBE_USE_EXISTING_MASTER=true`,
|
||||
kube-up 不会创建新的管理节点,而是会复用之前创建的。
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-b NUM_NODES=3 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
在 AWS 中我们还需要为新增的子网指定网络CIDR,还有管理节点的内部IP地址。
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2b NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.1.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
|
||||
再次查看节点,3个新增的节点已经启动,并被标记为us-central1-b:
|
||||
|
||||
```shell
|
||||
> kubectl get nodes --show-labels
|
||||
|
||||
NAME STATUS AGE VERSION LABELS
|
||||
kubernetes-master Ready,SchedulingDisabled 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
|
||||
kubernetes-minion-281d Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
|
||||
kubernetes-minion-87j9 Ready 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
|
||||
kubernetes-minion-9vlv Ready 16m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-a12q Ready 17m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
|
||||
kubernetes-minion-pp2f Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
|
||||
kubernetes-minion-wf8i Ready 2m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
|
||||
```
|
||||
|
||||
### 卷的亲和性
|
||||
|
||||
使用动态创建卷的功能创建一个卷 (只有PV持久卷才支持区域亲和性):
|
||||
|
||||
```json
|
||||
kubectl create -f - <<EOF
|
||||
{
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "claim1",
|
||||
"annotations": {
|
||||
"volume.alpha.kubernetes.io/storage-class": "foo"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "5Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**注意:** Kubernetes 1.3以上的版本中可以将PVC分发到多个已配置的区域中,在1.2版本中, 动态卷只能创建在管理节点所在的区域内(即这里的 us-central1-a / us-west-2a);相关issue
|
||||
([#23330](https://github.com/kubernetes/kubernetes/issues/23330))
|
||||
在1.3后续的版本中已解决。
|
||||
|
||||
现在我们验证一下 Kubernetes 自动为创建的PV打上了所在地域和区域的标签。
|
||||
|
||||
```shell
|
||||
> kubectl get pv --show-labels
|
||||
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE LABELS
|
||||
pv-gce-mj4gm 5Gi RWO Bound default/claim1 46s failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a
|
||||
```
|
||||
|
||||
现在我们将创建使用这些PVC的pod。
|
||||
因为 GCE 的PD存储 / AWS 的EBS 卷 不支持跨区域挂载,
|
||||
这意味着相应的pod只能创建在卷所在的区域中。
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mypod
|
||||
spec:
|
||||
containers:
|
||||
- name: myfrontend
|
||||
image: nginx
|
||||
volumeMounts:
|
||||
- mountPath: "/var/www/html"
|
||||
name: mypd
|
||||
volumes:
|
||||
- name: mypd
|
||||
persistentVolumeClaim:
|
||||
claimName: claim1
|
||||
EOF
|
||||
```
|
||||
|
||||
注意pod被自动创建在了卷所在的区域中,因为云供应商通常不支持卷的跨区域挂载(attach)。
|
||||
|
||||
```shell
|
||||
> kubectl describe pod mypod | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
> kubectl get node kubernetes-minion-9vlv --show-labels
|
||||
NAME STATUS AGE VERSION LABELS
|
||||
kubernetes-minion-9vlv Ready 22m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
```
|
||||
|
||||
### Pod的跨区域分布
|
||||
|
||||
副本管理器或服务的pod被自动创建在了不同的区域。 首先,在第三个区域内启动节点:
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-f NUM_NODES=3 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2c NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.2.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
|
||||
```
|
||||
|
||||
验证你现在在3个区域内拥有节点:
|
||||
|
||||
```shell
|
||||
kubectl get nodes --show-labels
|
||||
```
|
||||
|
||||
创建 guestbook-go 示例应用, 它包含一个副本数为3的RC,运行一个简单的网络应用:
|
||||
|
||||
```shell
|
||||
find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl create -f {}
|
||||
```
|
||||
|
||||
Pod应该分布在全部3个区域上:
|
||||
|
||||
```shell
|
||||
> kubectl describe pod -l app=guestbook | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
Node: kubernetes-minion-281d/10.240.0.8
|
||||
Node: kubernetes-minion-olsh/10.240.0.11
|
||||
|
||||
> kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
|
||||
NAME STATUS AGE VERSION LABELS
|
||||
kubernetes-minion-9vlv Ready 34m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
kubernetes-minion-281d Ready 20m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
|
||||
kubernetes-minion-olsh Ready 3m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
|
||||
```
|
||||
|
||||
|
||||
负载平衡器覆盖集群中的所有区域; guestbook-go 示例包含一个
|
||||
负载均衡服务的例子:
|
||||
|
||||
```shell
|
||||
> kubectl describe service guestbook | grep LoadBalancer.Ingress
|
||||
LoadBalancer Ingress: 130.211.126.21
|
||||
|
||||
> ip=130.211.126.21
|
||||
|
||||
> curl -s http://${ip}:3000/env | grep HOSTNAME
|
||||
"HOSTNAME": "guestbook-44sep",
|
||||
|
||||
> (for i in `seq 20`; do curl -s http://${ip}:3000/env | grep HOSTNAME; done) | sort | uniq
|
||||
"HOSTNAME": "guestbook-44sep",
|
||||
"HOSTNAME": "guestbook-hum5n",
|
||||
"HOSTNAME": "guestbook-ppm40",
|
||||
```
|
||||
|
||||
负载平衡器正确指向了所有的pod,即使它们位于不同的区域内。
|
||||
|
||||
### 停止集群
|
||||
|
||||
使用完成后,进行清理:
|
||||
|
||||
GCE:
|
||||
|
||||
```shell
|
||||
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-f kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-b kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a kubernetes/cluster/kube-down.sh
|
||||
```
|
||||
|
||||
AWS:
|
||||
|
||||
```shell
|
||||
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh
|
||||
KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
approvers:
|
||||
- Random-Liu
|
||||
title: 节点设置校验
|
||||
---
|
||||
|
||||
* TOC
|
||||
{{< toc >}}
|
||||
|
||||
## 节点合规性测试
|
||||
|
||||
*节点合规性测试* 是一个容器化的测试框架,提供了针对节点的系统验证和功能测试。 该测试主要检测节点是否满足 Kubernetes 的最低要求,通过检测的节点有资格加入 Kubernetes 集群。
|
||||
|
||||
## 限制
|
||||
|
||||
在 Kubernetes 1.5版本中,节点合规性测试存在以下限制:
|
||||
|
||||
* 节点合规性测试只支持 Docker 作为容器运行时环境。
|
||||
|
||||
## 节点的前提条件
|
||||
|
||||
为运行节点合规性测试,节点必须满足与标准的 Kubernetes 节点同样的前提条件。最基本地, 节点应安装以下组件:
|
||||
|
||||
* 容器运行时 (Docker)
|
||||
* Kubelet
|
||||
|
||||
## 运行节点合规性测试
|
||||
|
||||
执行以下步骤来运行节点合规性测试:
|
||||
|
||||
1. 因为测试框架会启动一个本地的 master 来测试 Kubelet,
|
||||
所以将 Kubelet 指向本机 `--api-servers="http://localhost:8080"。 还有一些其他 Kubelet 参数可能需要注意:
|
||||
* `--pod-cidr`: 如果使用 `kubenet`, 需要为 Kubelet 任意指定一个 CIDR, 例如 `--pod-cidr=10.180.0.0/24`。
|
||||
* `--cloud-provider`: 如果使用 `--cloud-provider=gce`,需要移除这个参数来运行测试。
|
||||
|
||||
2. 执行以下命令来运行节点合规性测试:
|
||||
|
||||
```shell
|
||||
# $CONFIG_DIR 是 Kubelet 的 manifest 文件路径。
|
||||
# $LOG_DIR 是测试结果输出的路径。
|
||||
sudo docker run -it --rm --privileged --net=host \
|
||||
-v /:/rootfs -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
|
||||
k8s.gcr.io/node-test:0.2
|
||||
```
|
||||
|
||||
## 针对其他硬件体系结构运行节点合规性测试
|
||||
|
||||
Kubernetes 也为其他硬件体系结构的系统提供了节点合规性测试的 Docker 镜像:
|
||||
|
||||
Arch | Image |
|
||||
--------|:-----------------:|
|
||||
amd64 | node-test-amd64 |
|
||||
arm | node-test-arm |
|
||||
arm64 | node-test-arm64 |
|
||||
|
||||
## 运行选定的测试
|
||||
|
||||
为运行指定的测试,用正则表达式来描述将要运行的测试,并重载 `FOCUS` 环境变量。
|
||||
|
||||
```shell
|
||||
sudo docker run -it --rm --privileged --net=host \
|
||||
-v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
|
||||
-e FOCUS=MirrorPod \ # 只运行MirrorPod测试
|
||||
k8s.gcr.io/node-test:0.2
|
||||
```
|
||||
|
||||
为跳过指定的测试,用正则表达式来描述将要跳过的测试,并重载 `SKIP` 环境变量。
|
||||
|
||||
```shell
|
||||
sudo docker run -it --rm --privileged --net=host \
|
||||
-v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
|
||||
-e SKIP=MirrorPod \ # 运行除MirrorPod外的所有测试
|
||||
k8s.gcr.io/node-test:0.2
|
||||
```
|
||||
|
||||
节点合规性测试是[节点端到端测试](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/devel/e2e-node-tests.md)的一个容器化的版本。
|
||||
默认情况下, 它会运行所有的合规性测试用例。
|
||||
|
||||
理论上,只要合理地配置容器和挂载所需的卷,就可以运行任何的节点端到端测试用例。 但是这里 **强烈建议只运行合规性测试**,因为运行非合规性测试需要很多复杂的配置。
|
||||
|
||||
## 注意事项
|
||||
|
||||
* 测试会在节点上遗留一些Docker镜像, 包括节点合规性测试本身的镜像,和功能测试相关的镜像。
|
||||
* 测试会在节点上遗留一些死的容器。这些容器是在功能测试的过程中创建的。
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
approvers:
|
||||
- thockin
|
||||
title: Kubernetes OpenVSwitch GRE/VxLAN 网络
|
||||
---
|
||||
|
||||
本文档介绍了如何使用OpenVSwitch,在跨nodes的pods之间设置网络。
|
||||
隧道类型可以是GRE或者是VxLAN。如需在网络内执行大规模隔离时,最好使用VxLAN。
|
||||
|
||||

|
||||
|
||||
Kubernetes中Vagrant的设置如下:
|
||||
|
||||
docker网桥被brctl生成的Linux网桥(kbr0)所代替,kbr0是具有256个地址空间的子网。总的来说,node会得到10.244.x.0/24的子网,docker上配置使用的网桥会代替默认docker0的网桥。
|
||||
|
||||
另外,OVS网桥创建(obr0),并将其作为端口添加到kbr0的网桥中。所有OVS网桥通过GRE隧道连接所有的nodes。因此,每个node都有一个到其他nodes的出站GRE隧道。这个隧道没有必要是一个完整的网状物,但是越像网状结构越好。在网桥上开启STP(生成树)模式以防止环路的发生。
|
||||
|
||||
路由规则允许任何10.244.0.0/16通过与隧道相连的OVS网桥到达目标。
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
approvers:
|
||||
- bprashanth
|
||||
- davidopp
|
||||
- lavalamp
|
||||
- liggitt
|
||||
title: 管理Service Accounts
|
||||
---
|
||||
|
||||
*这是一篇针对service accounts(服务账户)的集群管理员指南。 它呈现了 [User Guide to Service Accounts](/docs/user-guide/service-accounts)中的信息。*
|
||||
|
||||
*对授权和用户账户的支持已在规划中,当前并不完备,为了更好地描述service accounts,有时这些不完善的特性也会被提及。*
|
||||
|
||||
## 用户账户与服务账户
|
||||
|
||||
Kubernetes 区分用户账户和服务账户的概念主要基于以下原因:
|
||||
|
||||
- 用户账户是针对人而言的。 服务账户是针对运行在pod中的进程而言的。
|
||||
- 用户账户是全局性的。 其名称在集群各namespace中都是全局唯一的,未来的用户资源不会做namespace隔离,
|
||||
服务账户是namespace隔离的。
|
||||
- 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 (即权限最小化原则)。
|
||||
- 对人员和服务账户审计所考虑的因素可能不同。
|
||||
- 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有namespace级别的名称,这种配置是很轻量的。
|
||||
|
||||
## 服务账户的自动化
|
||||
|
||||
三个独立组件协作完成服务账户相关的自动化:
|
||||
|
||||
- 服务账户准入控制器(Service account admission controller)
|
||||
- Token控制器(Token controller)
|
||||
- 服务账户控制器(Service account controller)
|
||||
|
||||
### 服务账户准入控制器
|
||||
|
||||
对pod的改动通过一个被称为[Admission Controller](/docs/admin/admission-controllers)的插件来实现。它是apiserver的一部分。
|
||||
当pod被创建或更新时,它会同步地修改pod。 当该插件处于激活状态(在大多数发行版中都是默认的),当pod被创建或更新时它会进行以下动作:
|
||||
|
||||
1. 如果该pod没有 `ServiceAccount` 设置,将其 `ServiceAccount` 设为 `default`。
|
||||
2. 保证pod所关联的 `ServiceAccount` 存在,否则拒绝该pod。
|
||||
4. 如果pod不包含 `ImagePullSecrets`设置,那么 将 `ServiceAccount`中的`ImagePullSecrets` 信息添加到pod中。
|
||||
5. 将一个包含用于API访问的token的 `volume` 添加到pod中。
|
||||
6. 将挂载于 `/var/run/secrets/kubernetes.io/serviceaccount` 的 `volumeSource`添加到pod下的每个容器中。
|
||||
|
||||
### Token管理器
|
||||
|
||||
Token管理器是controller-manager的一部分。 以异步的形式工作:
|
||||
|
||||
- 检测服务账户的创建,并且创建相应的Secret以支持API访问。
|
||||
- 检测服务账户的删除,并且删除所有相应的服务账户Token Secret。
|
||||
- 检测Secret的增加,保证相应的服务账户存在,如有需要,为Secret增加token。
|
||||
- 检测Secret的删除,如有需要,从相应的服务账户中移除引用。
|
||||
|
||||
你需要通过 `--service-account-private-key-file` 参数项传入一个服务账户私钥文件至Token管理器。 私钥用于为生成的服务账户token签名。
|
||||
同样地,你需要通过 `--service-account-key-file` 参数将对应的公钥传入kube-apiserver。 公钥用于认证过程中的token校验。
|
||||
|
||||
#### 创建额外的 API tokens
|
||||
|
||||
控制器中有专门的循环来保证每个服务账户中都存在API token对应的Secret。 当需要为服务账户创建额外的API token时,创建一个类型为 `ServiceAccountToken` 的Secret,并在annotation中引用服务账户,控制器会生成token并更新:
|
||||
|
||||
secret.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
"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
|
||||
```
|
||||
|
||||
#### 删除/失效 服务账户token
|
||||
|
||||
```shell
|
||||
kubectl delete secret mysecretname
|
||||
```
|
||||
|
||||
### 服务账户管理器
|
||||
|
||||
服务账户管理器管理各命名空间下的服务账户,并且保证每个活跃的命名空间下存在一个名为 "default" 的服务账户
|
||||
Reference in New Issue
Block a user