【Kubernetes】K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制
G皮T 2024-09-16 15:33:01 阅读 50
《K8s 的安全认证》系列,共包含以下文章:
K8s 的安全框架和用户认证K8s 的鉴权管理(一):基于角色的访问控制(RBAC 鉴权)K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制服务账号 Service Account
😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!
K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制
1.基于属性的访问控制(ABAC 鉴权)2.基于节点的访问控制(node 鉴权)2.1 读取操作2.2 写入操作
3.基于 Webhook 的访问控制3.1 基于 Webhook 的访问控制的架构3.2 基于 Webhook 的访问控制的运行机制
1.基于属性的访问控制(ABAC 鉴权)
✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/abac/
❗ ABAC 鉴权功能从 Kubernetes <code>1.6 版本被弃用。
基于属性的访问控制(Attribute-Based Access Control
,ABAC
)通过将属性组合在一起来定义用户可以访问的范围。其策略文件是一个具有多行 JSON 格式的文件,该文件中的每一行都是一个策略(即一个 JSON 对象)。
下表列举了该 JSON 对象应具备的属性。
属性 |
属性中的字段
|
---|---|
版本控制 | 1️⃣ <code>apiVersion:字符串类型。该字段表示匹配 Kubernetes API 的哪些版本。该字段允许的值为 abac.authorization.kubernetes.io/v1beta1 。2️⃣ |
spec | 1️⃣ <code>user:字符串类型。该字段的值可以是验证通过的用户名,也可以是通过 --token-auth-file 指定的 Token 文件。2️⃣ |
资源匹配 | 1️⃣ <code>apiGroup:字符串类型,表示匹配一个 Kubernetes API 资源组。使用 * 则匹配所有 API 资源组。也可以具体指定某一个资源组,例如 extensions 。2️⃣ 3️⃣ |
非资源匹配 | <code>nonResourcePath:字符串类型,表示请求的路径。例如:/version 或 /apis 。该字段也可以使用通配符。例如,使用 * 则匹配所有非资源请求;使用 /dev/* 则匹配 /dev/ 的所有子路径。 |
readonly | 布尔类型。当该字段被设置为 <code>true 时,资源匹配策略仅适用于 GET、LIST 和 WATCH 操作,而非资源匹配策略仅适用于 GET 操作。 |
下面是使用 ABAC 鉴权时的几个 JSON 策略。
alice
用户可以对所有资源做任何事情。
{ -- -->
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "alice",
"namespace": "*",
"resource": "*",
"apiGroup": "*"
}
}
Kubelet
用户可以访问任何 Pod 和服务。
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "kubelet",
"namespace": "*",
"resource": "pods",
"readonly": true
}
}
Bob
用户可以在命名空间 dev-demo
中访问 Pod。
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "bob",
"namespace": "dev-demo",
"resource": "pods",
"readonly": true
}
}
🚀 在实际情况中,通常会把一个 JSON 字符串放到一个 JSON 策略文件中,来作为访问控制的策略文件。在配置完 JSON 策略文件后,在重启 API Server 时需要指定该文件才能获取新的策略。
2.基于节点的访问控制(node 鉴权)
✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/node/
基于节点的访问控制(node
鉴权)是专门针对 kubectl
发出的 API 请求的一种鉴权。
🚀 要启用基于节点的访问控制,则需要在启动 API Server 时使用
--authorization-mode=Node
参数。
对于 kubectl
执行的 API 请求,Node 鉴权过程主要包括 读取操作 和 写入操作。
2.1 读取操作
当 kubectl
使用基于节点的方式操作 API 资源时,允许对以下资源进行 读取操作:
Pod、Service、Endpoint、NodeSecret、ConfigMap、PVC绑定到 kubelet
节点的与 Pod 相关的持久卷
2.2 写入操作
当 kubectl
使用基于节点的方式操作 API 资源时,允许对以下的资源进行 写入操作:
节点和节点状态(启用 NodeRestriction 准入控制器,以限制 kubelet
只能修改本节点的信息)。Pod 和 Pod 状态(启用 NodeRestriction 准入控制器,以限制 kubelet
只能修改绑定到本节点的 Pod 信息)。Event(事件)。
🚀 由于写入操作需要启用 NodeRestriction(准入控制器),因此在启动 API Server 时,需要在
--enable-admission-plugins
中加入NodeRestriction
,例如:--enable-admission-plugins=...,NodeRestriction,...
3.基于 Webhook 的访问控制
✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/webhook/
基于 Webhook 的访问控制定义了 HTTP 的一个回调接口,从而实现在某些特定事件发生时,该接口的应用会向一个远端的授权服务器发送 HTTP POST 信息。因此,在启用基于 Webhook 的访问控制后,Kubernetes 会调用外部的服务来对用户访问的资源进行授权。
🚀 要启用基于 Webhook 的访问控制,则需要在启动 API Server 时使用
--authorization-mode=webhook
参数。
3.1 基于 Webhook 的访问控制的架构
基于 Webhook 的访问控制的架构如下图所示。
从架构来看,基于 Webhook 的访问控制其实是一种基于 HTTP 协议的客户端与服务器(<code>Client-Server)架构。由于 Kubernetes 的访问控制是围绕 API Server 进行的,因此,这里的 HTTP 客户端就是 API Server,而 HTTP 服务器端就是远端的授权服务器。在配置 HTTP 客户端 API Server 时,需要使用一个配置文件来指定远端的授权服务器的信息。
下面是 Kubernetes 官方提供的一个 HTTP 客户端配置示例。
# Kubernetes API version
apiVersion: v1
# kind of the API object
kind: Config
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authz-service
cluster:
# CA for verifying the remote service.
certificate-authority: /path/to/ca.pem
# URL of remote service to query. Must use 'https'. May not include parameters.
server: https://authz.example.com/authorize
# users refers to the API Server's webhook configuration.
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
client-key: /path/to/key.pem # key matching the cert
# kubeconfig files require a context. Provide one for the API Server.
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authz-service
user: name-of-api-server
name: webhook
🚀 其中的
clusters
字段代表的是远端的授权服务器。
有了客户端的配置文件后,在启动 API Server 时,除要指定使用 Webhook 的鉴权方式(即设置 --authorization-mode=webhook
参数)外,还需要用 --authorization-webhook-config-file
参数来指定 HTTP 客户端 API Server 的配置文件。
3.2 基于 Webhook 的访问控制的运行机制
在 Kubernetes 配置好基于 Webhook 的访问控制后,在进行鉴权时,API Server 会自动向远端的授权服务器发送一个 HTTP POST 的报文,在该请求中包含一个 JSON 格式的 SubjectAccessReview
对象用来描述当前执行的动作请求。
以下是对 Kubernetes 的资源对象请求进行鉴权的 HTTP POST 报文格式。该报文希望 jane
用户可以获取 Pod 的列表。
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "kittensandponies",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
可以看出,SubjectAccessReview
对象中除包含被访问资源和请求的动作信息外,还包含用户的信息。
如果要对 Kubernetes 的非资源对象的请求进行鉴权,则报文格式如下:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"nonResourceAttributes": {
"path": "/debug",
"verb": "get"
},
"user": "jane",
"group": [
"group1",
"group2"
]
}
}
远端的授权服务器在收到 HTTP POST 报文后,如果鉴权成功,则返回一个 SubjectAccessReview
对象,并在对象中填充 status
字段来允许访问。例如:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": true
}
}
在远端的授权服务器拒绝请求的 HTTP POST 报文时,也是通过填充 status
字段来拒绝。例如:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"reason": "user does not have read access to the namespace"
}
}
如果远端的授权服务器拒绝了 API Server 的请求,同时也想拒绝其他授权者再次对该请求进鉴权,则可以在 status
字段中增加一个 denied
参数。例如:
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"status": {
"allowed": false,
"denied": true,
"reason": "user does not have read access to the namespace"
}
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。