Kubernetes 的授权发生在认证之后。通常情况下,发起请求的客户端必须先经过认证(登录)才能允许其请求;不过,Kubernetes 在某些情况下也允许匿名请求。
有关授权在 API 访问控制更大范畴内如何运作的概述,请阅读控制对 Kubernetes API 的访问。
Kubernetes 对 API 请求的授权发生在 API 服务器内部。API 服务器将所有请求属性与所有策略进行对比评估,有时还会咨询外部服务,然后决定允许或拒绝该请求。
API 请求的各个部分都必须获得某种授权机制的许可才能继续。换句话说:默认拒绝访问。
当配置了多个授权模块时,系统会按顺序检查每一个模块。如果任何授权器批准或拒绝了请求,该决定将立即返回,并且不会再咨询其他授权器。如果所有模块对该请求都没有意见,则该请求将被拒绝。总体的拒绝判断意味着 API 服务器拒绝该请求并返回 HTTP 403(禁止)状态码。
Kubernetes 仅审查以下 API 请求属性
user 字符串。/api 或 /healthz)的路径。get、list、create、update、patch、watch、delete 和 deletecollection 等 API 谓词。要确定资源 API 端点的请求谓词,请参阅请求谓词与授权。get、post、put 和 delete。get、update、patch 和 delete 谓词的资源请求,必须提供资源名称。status 或 scale),也可以是用于细粒度授权的合成子资源。对 /api/v1/... 或 /apis/<group>/<version>/... 之外端点的请求被视为非资源请求,并使用请求的小写 HTTP 方法作为谓词。例如,使用 HTTP 对 /api 或 /healthz 等端点进行 GET 请求,将使用 get 作为谓词。
为了确定资源 API 端点的请求谓词,Kubernetes 会映射所使用的 HTTP 谓词,并考虑请求是作用于单个资源还是资源集合。
| HTTP 谓词 | 请求谓词 |
|---|---|
POST | create |
GET, HEAD | get(针对单个资源),list(针对集合,包括完整的对象内容),watch(用于监视单个资源或资源集合) |
PUT | update |
PATCH | patch |
DELETE | delete(针对单个资源),deletecollection(针对集合) |
secrets 执行 list 将暴露任何返回资源的 data 属性。Kubernetes 有时会使用专门的谓词来检查额外权限的授权。例如:
users、groups 和 serviceaccounts 的 impersonate(模拟)谓词,以及 authentication.k8s.io API 组中的 userextras。rbac.authorization.k8s.io API 组中 roles 和 clusterroles 资源的 bind(绑定)和 escalate(提升)谓词。resource.k8s.io API 组中的合成子资源,例如 resourceclaims/binding 和 resourceclaims/driver。resourceclaims/status 更新的节点感知谓词,例如 associated-node:update、associated-node:patch、arbitrary-node:update 和 arbitrary-node:patch。Kubernetes 期望 REST API 请求共有的属性。这意味着 Kubernetes 授权可以与现有的全公司范围或云提供商范围的访问控制系统协同工作,这些系统可能除了处理 Kubernetes API 外还处理其他 API。
Kubernetes API 服务器可以使用多种授权模式之一来授权请求:
AlwaysAllowAlwaysDenyABAC (基于属性的访问控制)RBAC (基于角色的访问控制)rbac.authorization.k8s.io API 组来推动授权决策,允许您通过 Kubernetes API 动态配置权限策略。NodeWebhook启用 AlwaysAllow 模式会绕过授权;请勿在您不信任所有潜在 API 客户端(包括您运行的工作负载)的集群上使用此模式。
授权机制通常返回“拒绝”或“无意见”结果;有关更多信息,请参阅授权判断结果。激活 AlwaysAllow 意味着如果所有其他授权器都返回“无意见”,则请求被允许。例如,--authorization-mode=AlwaysAllow,RBAC 的效果与 --authorization-mode=AlwaysAllow 相同,因为 Kubernetes RBAC 不提供消极(拒绝)的访问规则。
如果 API 服务器可以从公共互联网访问,则不应在 Kubernetes 集群上使用 AlwaysAllow 模式。
system:masters 组是一个内置的 Kubernetes 组,授予对 API 服务器的无限制访问权限。任何分配到此组的用户都拥有完全的集群管理员权限,绕过了 RBAC 或 Webhook 机制施加的任何授权限制。避免向此组添加用户。如果您确实需要授予用户集群管理员权限,可以创建一个指向内置 cluster-admin ClusterRole 的 ClusterRoleBinding。
您可以使用配置文件或命令行参数来配置 Kubernetes API 服务器的授权器链。
您必须在两种配置方法中选择一种;设置 --authorization-config 路径的同时使用 --authorization-mode 和 --authorization-webhook-* 命令行参数配置授权 Webhook 是不允许的。如果您尝试这样做,API 服务器会在启动时报错并立即退出。
Kubernetes v1.32 [稳定](默认启用)Kubernetes 允许您配置可以包含多个 Webhook 的授权链。该链中的授权项可以拥有定义明确的参数,按特定顺序验证请求,从而为您提供细粒度的控制,例如在失败时显式拒绝。
配置文件方法甚至允许您指定 CEL 规则,在请求分发到 Webhook 之前对其进行预过滤,从而帮助您防止不必要的调用。API 服务器在修改配置文件时也会自动重新加载授权器链。
您可以使用 --authorization-config 命令行参数指定授权配置文件的路径。
如果您想使用命令行参数而不是配置文件,这也是一种有效且受支持的方法。某些授权功能(例如:多个 Webhook、Webhook 失败策略和预过滤规则)仅在您使用授权配置文件时才可用。
---
#
# DO NOT USE THE CONFIG AS IS. THIS IS AN EXAMPLE.
#
apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
# Name used to describe the authorizer
# This is explicitly used in monitoring machinery for metrics
# Note:
# - Validation for this field is similar to how K8s labels are validated today.
# Required, with no default
name: webhook
webhook:
# The duration to cache 'authorized' responses from the webhook
# authorizer.
# Same as setting `--authorization-webhook-cache-authorized-ttl` flag
# Default: 5m0s
authorizedTTL: 30s
# If set to false, 'authorized' responses from the webhook are not cached
# and the specified authorizedTTL is ignored/has no effect.
# Same as setting `--authorization-webhook-cache-authorized-ttl` flag to `0`.
# Note: Setting authorizedTTL to `0` results in its default value being used.
# Default: true
cacheAuthorizedRequests: true
# The duration to cache 'unauthorized' responses from the webhook
# authorizer.
# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
# Default: 30s
unauthorizedTTL: 30s
# If set to false, 'unauthorized' responses from the webhook are not cached
# and the specified unauthorizedTTL is ignored/has no effect.
# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag to `0`.
# Note: Setting unauthorizedTTL to `0` results in its default value being used.
# Default: true
cacheUnauthorizedRequests: true
# Timeout for the webhook request
# Maximum allowed is 30s.
# Required, with no default.
timeout: 3s
# The API version of the authorization.k8s.io SubjectAccessReview to
# send to and expect from the webhook.
# Same as setting `--authorization-webhook-version` flag
# Required, with no default
# Valid values: v1beta1, v1
subjectAccessReviewVersion: v1
# MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview
# version the CEL expressions are evaluated against
# Valid values: v1
# Required, no default value
matchConditionSubjectAccessReviewVersion: v1
# Controls the authorization decision when a webhook request fails to
# complete or returns a malformed response or errors evaluating
# matchConditions.
# Valid values:
# - NoOpinion: continue to subsequent authorizers to see if one of
# them allows the request
# - Deny: reject the request without consulting subsequent authorizers
# Required, with no default.
failurePolicy: Deny
connectionInfo:
# Controls how the webhook should communicate with the server.
# Valid values:
# - KubeConfigFile: use the file specified in kubeConfigFile to locate the
# server.
# - InClusterConfig: use the in-cluster configuration to call the
# SubjectAccessReview API hosted by kube-apiserver. This mode is not
# allowed for kube-apiserver.
type: KubeConfigFile
# Path to KubeConfigFile for connection info
# Required, if connectionInfo.Type is KubeConfigFile
kubeConfigFile: /kube-system-authz-webhook.yaml
# matchConditions is a list of conditions that must be met for a request to be sent to this
# webhook. An empty list of matchConditions matches all requests.
# There are a maximum of 64 match conditions allowed.
#
# The exact matching logic is (in order):
# 1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.
# 2. If ALL matchConditions evaluate to TRUE, then the webhook is called.
# 3. If at least one matchCondition evaluates to an error (but none are FALSE):
# - If failurePolicy=Deny, then the webhook rejects the request
# - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped
matchConditions:
# expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
# CEL expressions have access to the contents of the SubjectAccessReview in v1 version.
# If version specified by subjectAccessReviewVersion in the request variable is v1beta1,
# the contents would be converted to the v1 version before evaluating the CEL expression.
#
# Documentation on CEL: https://kubernetes.ac.cn/docs/reference/using-api/cel/
#
# only send resource requests to the webhook
- expression: has(request.resourceAttributes)
# only intercept requests to kube-system
- expression: request.resourceAttributes.namespace == 'kube-system'
# don't intercept requests from kube-system service accounts
- expression: "!('system:serviceaccounts:kube-system' in request.groups)"
- type: Node
name: node
- type: RBAC
name: rbac
- type: Webhook
name: in-cluster-authorizer
webhook:
authorizedTTL: 5m
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
failurePolicy: NoOpinion
connectionInfo:
type: InClusterConfig在使用配置文件配置授权器链时,请确保所有控制平面节点的文件内容相同。在升级/降级集群时,请注意 API 服务器的配置。例如,如果从 Kubernetes 1.35 升级到 Kubernetes 1.36,您需要在升级集群之前确保配置文件采用 Kubernetes 1.36 可以理解的格式。如果您降级到 1.35,则需要相应地设置配置。
当 API 服务器观察到文件发生变化时,它会重新加载授权配置文件;如果没有观察到变化事件,也会按照 60 秒的时间间隔定期重新加载。
您必须确保在重新加载时,文件中所有非 Webhook 类型的授权器保持不变。
重新加载不得添加或删除 Node 或 RBAC 授权器(它们可以重新排序,但不能添加或删除)。
您可以使用以下模式:
--authorization-mode=ABAC(基于属性的访问控制模式)--authorization-mode=RBAC(基于角色的访问控制模式)--authorization-mode=Node(节点授权器)--authorization-mode=Webhook(Webhook 授权模式)--authorization-mode=AlwaysAllow(始终允许请求;带有安全风险)--authorization-mode=AlwaysDeny(始终拒绝请求)您可以选择多种授权模式;例如:--authorization-mode=Node,RBAC,Webhook
Kubernetes 会根据您在 API 服务器命令行中指定的顺序检查授权模块,因此较早的模块对允许或拒绝请求具有更高的优先级。
您不能将 --authorization-mode 命令行参数与用于通过本地文件配置授权的 --authorization-config 命令行参数结合使用。
有关 API 服务器命令行参数的更多信息,请阅读 kube-apiserver 参考。
能够在命名空间中创建/编辑 Pod 的用户(无论是直接创建还是通过支持间接工作负载管理的对象创建)可能能够提升其在该命名空间中的权限。权限提升的潜在途径包括 Kubernetes API 扩展及其关联的控制器。
如果您允许攻击者或不可信用户在命名空间中运行任意 Pod,他们可以通过多种方式在命名空间内获得额外权限:
kubectl 提供了 auth can-i 子命令,用于快速查询 API 授权层。该命令使用 SelfSubjectAccessReview API 来确定当前用户是否可以执行给定操作,无论使用哪种授权模式,它都有效。
kubectl auth can-i create deployments --namespace dev
输出类似于此
yes
kubectl auth can-i create deployments --namespace prod
输出类似于此
no
管理员可以将其与用户模拟结合使用,以确定其他用户可以执行哪些操作。
kubectl auth can-i list secrets --namespace dev --as dave
输出类似于此
no
类似地,要检查名为 dev-sa 的 ServiceAccount(在 dev 命名空间中)是否可以列出 target 命名空间中的 Pod:
kubectl auth can-i list pods \
--namespace target \
--as system:serviceaccount:dev:dev-sa
输出类似于此
yes
SelfSubjectAccessReview 是 authorization.k8s.io API 组的一部分,该组将 API 服务器授权暴露给外部服务。该组中的其他资源包括:
这些 API 可以通过创建普通的 Kubernetes 资源来查询,其中返回对象的 status 字段即为查询结果。例如:
kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
resourceAttributes:
group: apps
resource: deployments
verb: create
namespace: dev
EOF
生成的 SelfSubjectAccessReview 类似于:
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
creationTimestamp: null
spec:
resourceAttributes:
group: apps
resource: deployments
namespace: dev
verb: create
status:
allowed: true
denied: false