Kubernetes API访问控制
用户使用 kubectl
、客户端库或通过发出 REST 请求来访问 Kubernetes API。 human用户和 Kubernetes 服务帐户都可以被授权访问 API。 当请求到达 API 时,它会经历几个阶段,如下图所示:
运输安全
在典型的 Kubernetes 集群中,API 服务于端口 443,受 TLS 保护。 API 服务器提供一个证书。 该证书可以使用私有证书颁发机构 (CA) 进行签名,也可以基于链接到公认 CA 的公钥基础设施进行签名。
如果您的集群使用私有证书颁发机构,您需要将该 CA 证书的副本配置到客户端的 ~/.kube/config
中,以便您可以信任连接并确信它没有被拦截。
您的客户端可以在此阶段出示 TLS 客户端证书。
验证
建立 TLS 后,HTTP 请求将移至身份验证步骤。这在图中显示为步骤 1。集群创建脚本或集群管理员将 API 服务器配置为运行一个或多个 Authenticator 模块。
身份验证步骤的输入是整个 HTTP 请求;但是,它通常会检查标头和/或客户端证书。
身份验证模块包括客户端证书、密码和普通令牌、引导令牌和 JSON Web 令牌(用于服务帐户)。
可以指定多个认证模块,依次尝试每一个,直到其中一个成功。
如果请求无法通过身份验证,则会以 HTTP 状态代码 401 拒绝该请求。否则,用户将作为特定用户名进行身份验证,并且该用户名可供后续步骤在其决策中使用。一些身份验证器还提供用户的组成员身份,而其他身份验证器不提供。
虽然 Kubernetes 使用用户名进行访问控制决策和请求日志记录,但它没有用户对象,也没有在其 API 中存储用户名或其他有关用户的信息。
授权
在请求被验证为来自特定用户之后,该请求必须被授权。 这在图中显示为步骤 2。
请求必须包含请求者的用户名、请求的操作以及受该操作影响的对象。 如果现有策略声明用户有权完成所请求的操作,则该请求被授权。
例如,如果 Bob 具有以下策略,那么他只能读取命名空间 projectCaribou
中的 pod:
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "bob",
"namespace": "projectCaribou",
"resource": "pods",
"readonly": true
}
}
如果 Bob 发出以下请求,则该请求被授权,因为允许他读取 projectCaribou
命名空间中的对象:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "projectCaribou",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
}
}
}
如果 Bob 请求写入(create
或update
)projectCaribou
命名空间中的对象,他的授权将被拒绝。如果 Bob 请求读取(get
)不同命名空间(例如 projectFish
)中的对象,那么他的授权将被拒绝。
Kubernetes 授权要求您使用通用 REST 属性与现有的组织范围或云提供商范围的访问控制系统进行交互。使用 REST 格式很重要,因为这些控制系统可能会与 Kubernetes API 之外的其他 API 交互。
Kubernetes 支持 ABAC 模式、RBAC 模式、Webhook 模式等多种授权模块。当管理员创建集群时,他们配置应该在 API 服务器中使用的授权模块。如果配置了多个授权模块,Kubernetes 会检查每个模块,如果有任何模块授权请求,则请求可以继续。如果所有模块都拒绝该请求,则该请求被拒绝(HTTP 状态代码 403)。
准入控制
准入控制模块是可以修改或拒绝请求的软件模块。除了授权模块可用的属性外,准入控制模块还可以访问正在创建或修改的对象的内容。
准入控制器对创建、修改、删除或连接(代理)对象的请求进行操作。准入控制器不会对仅读取对象的请求进行操作。配置多个准入控制器时,按顺序调用。
这在图中显示为步骤 3。
与身份验证和授权模块不同,如果任何准入控制器模块拒绝,则请求会立即被拒绝。
除了拒绝对象,准入控制器还可以为字段设置复杂的默认值。
一旦请求通过了所有准入控制器,就会使用相应 API 对象的验证例程对其进行验证,然后将其写入对象存储(如步骤 4 所示)。
Auditing
Kubernetes auditing提供了一组与安全相关的、按时间顺序排列的记录,记录了集群中的操作顺序。 集群审核用户、使用 Kubernetes API 的应用程序以及控制平面本身生成的活动。
API 服务器端口和 IP
前面的讨论适用于发送到 API 服务器安全端口的请求(典型情况)。 API 服务器实际上可以在 2 个端口上服务:
默认情况下,Kubernetes API 服务器在 2 个端口上提供 HTTP:
- 本地主机端口:
- 用于测试和引导,以及主节点的其他组件(调度程序、控制器管理器)与 API 对话
- 没有 TLS
- 默认为 8080 端口
- 默认 IP 是 localhost,使用
--insecure-bind-address
标志进行更改。 - 请求绕过身份验证和授权模块。
- 由准入控制模块处理的请求。
- 受需要拥有主机访问权限的保护
- “安全端口”:
- 尽可能使用
- 使用 TLS。 使用
--tls-cert-file
设置证书,使用 --tls-private-key-file
标志设置密钥。 - 默认为端口 6443,使用
--secure-port
标志进行更改。 - 默认 IP 是第一个非本地主机网络接口,使用
--bind-address
标志进行更改。 - 由身份验证和授权模块处理的请求。
- 由准入控制模块处理的请求。
- 身份验证和授权模块运行。