Webhook 模式
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL。
具体来说,当在判断用户权限时,Webhook
模式会使 Kubernetes 查询外部的 REST 服务。
配置文件格式
Webhook
模式需要一个 HTTP 配置文件,通过
--authorization-webhook-config-file=SOME_FILENAME
的参数声明。
配置文件的格式使用 kubeconfig。 在该文件中,“users” 代表着 API 服务器的 Webhook,而 “cluster” 代表着远程服务。
使用 HTTPS 客户端认证的配置例子:
# Kubernetes API 版本
apiVersion: v1
# API 对象种类
kind: Config
# clusters 代表远程服务
clusters:
- name: name-of-remote-authz-service
cluster:
# 对远程服务进行身份认证的 CA
certificate-authority: /path/to/ca.pem
# 远程服务的查询 URL。必须使用 'https'。不可以包含参数。
server: https://authz.example.com/authorize
# users 代表 API 服务器的 webhook 配置
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # 要使用的 webhook 插件的证书
client-key: /path/to/key.pem # 与证书匹配的密钥
# kubeconfig 文件必须有 context。需要提供一个给 API 服务器。
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authz-service
user: name-of-api-server
name: webhook
请求载荷
在做认证决策时,API 服务器会 POST 一个 JSON 序列化的 authorization.k8s.io/v1beta1
SubjectAccessReview
对象来描述这个动作。这个对象包含了描述用户请求的字段,同时也包含了需要被访问资源或请求特征的具体信息。
需要注意的是 webhook API 对象与其他 Kubernetes API
对象一样都同样都遵从版本兼容规则。
实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段能被正确地反序列化。
此外,API 服务器还必须启用 authorization.k8s.io/v1beta1
API
扩展组 (--runtime-config=authorization.k8s.io/v1beta1=true
)。
一个请求内容的例子:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "kittensandponies",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
期待远程服务填充请求的 status
字段并响应允许或禁止访问。
响应主体的 spec
字段被忽略,可以省略。允许的响应将返回:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": true
}
}
为了禁止访问,有两种方法。
在大多数情况下,第一种方法是首选方法,它指示授权 Webhook 不允许或对请求 “无意见”。 但是,如果配置了其他授权者,则可以给他们机会允许请求。 如果没有其他授权者,或者没有一个授权者,则该请求被禁止。Webhook 将返回:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"reason": "user does not have read access to the namespace"
}
}
第二种方法立即拒绝其他配置的授权者进行短路评估。 仅应由对集群的完整授权者配置有详细了解的 Webhook 使用。Webhook 将返回:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"denied": true,
"reason": "user does not have read access to the namespace"
}
}
对于非资源的路径访问是这么发送的:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"nonResourceAttributes": {
"path": "/debug",
"verb": "get"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
Kubernetes v1.31 [alpha]
(enabled by default: false)启用 AuthorizeWithSelectors
特性后,请求中的字段和标签选择算符将被传递给授权 Webhook。
此 Webhook 可以根据作用域字段和标签选择算符做出授权决策(如果它愿意的话)。
SubjectAccessReview API 文档提供了这些字段应如何被授权 Webhook 解释和处理的指南,特别是应使用解析后的要求而不是原始选择算符字符串,以及如何安全地处理未识别的操作符。
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"verb": "list",
"group": "",
"resource": "pods",
"fieldSelector": {
"requirements": [
{"key":"spec.nodeName", "operator":"In", "values":["mynode"]}
]
},
"labelSelector": {
"requirements": [
{"key":"example.com/mykey", "operator":"In", "values":["myvalue"]}
]
}
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
非资源类的路径包括:/api
、/apis
、/metrics
、/logs
、/debug
、
/healthz
、/livez
、/openapi/v2
、/readyz
、和 /version
。
客户端需要访问 /api
、/api/*
、/apis
、/apis/*
和 /version
以便
能发现服务器上有什么资源和版本。对于其他非资源类的路径访问在没有 REST API 访问限制的情况下拒绝。
更多信息请参阅 SubjectAccessReview API 文档和 webhook.go 实现。