website/content/zh/docs/admin/accessing-the-api.md

136 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
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服务器后会经过几个阶段具体说明如图
![Diagram of request handling steps for Kubernetes API request](/images/docs/admin/access-control-overview.svg)
## 传输层安全
在典型的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 TokensBootstrap 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其他厂商的集群设置方法各不相同。