Kubernetes(k8s)手册 Kubernetes API访问控制

2024-02-25 开发教程 Kubernetes(k8s)手册 匿名 6

用户使用 ​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:

  1. 本地主机端口:
  • 用于测试和引导,以及主节点的其他组件(调度程序、控制器管理器)与 API 对话
  • 没有 TLS
  • 默认为 8080 端口
  • 默认 IP 是 localhost,使用 ​--insecure-bind-address​ 标志进行更改。
  • 请求绕过身份验证和授权模块。
  • 由准入控制模块处理的请求。
  • 受需要拥有主机访问权限的保护
“安全端口”:
  • 尽可能使用
  • 使用 TLS。 使用 ​--tls-cert-file​ 设置证书,使用 ​--tls-private-key-file​ 标志设置密钥。
  • 默认为端口 6443,使用 ​--secure-port​ 标志进行更改。
  • 默认 IP 是第一个非本地主机网络接口,使用 ​--bind-address​ 标志进行更改。
  • 由身份验证和授权模块处理的请求。
  • 由准入控制模块处理的请求。
  • 身份验证和授权模块运行。