Kubernetes安全框架
-
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都 支持插件方式,通过API Server配置来启用插件。
- Authentication(鉴权):身份鉴别,只有正确的账号才能够通过认证
- Authorization(授权):判断用户是否有权限对访问的资源执行特定的动作
- Admission Control(准入控制):用于补充授权机制以实现更加精细的访问控制功能。
-
客户端要想访问K8s集群API Server,一般需要证书、Token或 者用户名+密码;如果Pod访问,需要ServiceAccount
Authentication(鉴权)
三种客户端身份认证:
- HTTP Base认证:通过用户名+密码的方式认证
这种认证方式是把“用户名:密码"用BASE64算法进行编码后的字符串放在HTTP请求中的Header Authorization域里发送给服务端。服务端收到后进行解码,获取用户名及密码,然后进行用户身份认证的过程。
- HTTP Token认证:通过一个Token来识别合法用户
这种认证方式是用一个很长的难以被模仿的字符串–Token来表明客户身份的一种方式。每个Token对应一个用户名,当客户端发起API调用请求时,需要在HTTP Header里放入Token, API Server 接到Token后会跟服务器中保存的token进行比对,然后进行用户身份认证的过程。
-
HTTPS证书认证:基于CA根证书签名的双向数字证书认证方式
这种认证方式是安全性最高的一种方式,但是同时也是操作起来最麻烦的一种方式。
HTTPS认证大体分为3个过程:
证书申请和下发
HTTPS通信双方的服务器向CA机构申请证书,CA机构下发根证书、服务端证书及私钥给申请者。
客户端和服务端的双向认证
客户端向服务器端发起请求,服务端下发自己的证书给客户端,客户端接收到证书后,通过私钥解密证书,在证书中获得服务端的公钥,客户端利用服务器端的公钥认证证书中的信息,如果一致,则认可这个服务器。
客户端发送自己的证书给服务器端,服务端接收到证书后,通过私钥解密证书, 在证书中获得客户端的公钥,并用该公钥认证证书信息,确认客户端是否合法。
服务器端和客户端进行通信
服务器端和客户端协商好加密方案后,客户端会产生-一个随机的秘钥并加密,然后发送到服务器端服务器端接收这个秘钥后,双方接下来通信的所有内容都通过该随机秘钥加密。
Authorization(授权)
授权发生在认证成功之后,通过认证就可以知道请求用户是谁,然后Kubernetes会根据事先定义的授权策略来决定用户是否有权限访问,这个过程就称为授权。
RBAC(Role-Based Access Control) 基于角色的访问控制,主要是在描述一件事情:给哪些对象授予了哪些权限
RBAC根据API请求属性,决定允许还是拒绝。
比较常见的授权的几个概念:
- 对象:User(用户名)、Groups(用户分组)、 ServiceAccount(服务账号)
- 角色:代表着一组定义在资源上的可操作动作(权限)的集合
- 绑定:将定义好的角色跟用户绑定在一起
角色
- Role:授权特定命名空间的访问权限
- ClusterRole:授权所有命名空间的访问权限
一个角色就是一组权限的集合,这里的权限都是许可形式的(白名单)。
# Role只能对命名空间内的资源进行授权,需要指定nameapce
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: authorization-role
namespace: test
rules:
- apiGroups: [""] # 支持的API组列表,"”空字符串,表示核心API群
resources: ["pods"] # 支持的资源对象列表
verbs: ["get", "watch", "list"] # 允许的对资源对象的操作方法列表
# 该 authorization-role 角色,对指定test命名空间,核心api组的pod资源具有get watch list 权限
# ClusterRole可以对集群范围内资源、跨namespaces的范围资源、非资源类型进行授权
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: authorization-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
rules中的参数说明:
- apiGroups:支持的API组列表
"","apps","autoscaling", "batch"
- resources:支持的资源对象列表
"services","endpoints","pods","secrets","configmaps","crontabs" ,"deployments","jobs",
"nodes" , "rolebindings","clusterroles", " daemonsets" ,"replicasets" ,"statefulsets",
"horizontalpodautoscalers" ,"replicationcontrollers" , "cronjobs"
- verbs:对资源对象的操作方法列表
"get","list", "watch", "create", "update", "patch", "delete", "exec"
角色绑定
- RoleBinding:将角色绑定到主体(即subject)
- ClusterRoleBinding:将集群角色绑定到主体
角色绑定用来把一个角色绑定到一个目标对象上,绑定目标可以是User、Group或者ServiceAccount
# RoleBinding可以将同一namespace中的subject绑定到某个Role下,则此subject即具有该Role定义的权限
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: authorization-role-binding
namespace: test
subjects: # 目标对象信息
- kind: User # 用户类型
name: zhangsan # 存在的用户名
apiGroup: rbac.authorization.k8s.io
roleRef: # 角色信息
kind: Role # Role类型
name: authorization-role # 存在的role
apiGroup: rbac.authorization.k8s.io
# 将 authorization-role 角色绑定到 zhangsan 目标用户上(此时,zhangsan用户即用户authorization-role角色下所定义的权限)
# ClusterRoleBinding在整个集群级别和所有namespaces将特定的subject与ClusterRole绑定,授予权限
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: authorization-clusterrole-binding
subjects: # 目标对象信息
- kind: User # 用户类型
name: zhangsan
apiGroup: rbac.authorization.k8s.io
roleRef: # 角色信息
kind: ClusterRole
name: authorization-clusterrole
apiGroup: rbac.authorization.k8s.io
RoleBinding引用ClusterRole进行授权
RoleBinding可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。
一种很常用的做法就是,集群管理员为集群范围预定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些ClusterRole。这样可以大幅提高授权管理工作效率,也使得各个命名空间下的基础性授权规则与使用体验保持一致。
#虽然authorization-clusterrole是一个集群角色,但是因为使用了RoleBinding ,所以zhangsan只能读取test命名空间中的资源
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: authorization-role-binding-ns
namespace: test
subjects:
- kind: User
name: zhangsan
apiGroup: rbac.authorization.k8s.io
roleRef :
kind: ClusterRole
name: authorization-clusterrole
apiGroup: rbac.authorization.k8s.io
Admission Control(准入控制)
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server 的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过, 则拒绝请求。
案例:为指定用户授权访问不同命名空间权限
Eg: 为xin用户授权default命令空间Pod读取权限
- 用K8S CA签发客户端证书
- 生成kubeconfig授权文件
- 创建RBAC权限策略
签发证书
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
cat > xin-csr.json <<EOF
{
"CN": "xin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes xin-csr.json | cfssljson -bare xin
bash cert.sh
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \ # 指定根证书的名称路径
--embed-certs=true \ # 将根证书内容写入配置文件中
--server=https://192.168.200.29:6443 \ # 指定连接k8s集群的IP地址
--kubeconfig=xin.kubeconfig # 生成的文件名
# 设置客户端认证
kubectl config set-credentials xin \
--client-key=xin-key.pem \
--client-certificate=xin.pem \
--embed-certs=true \
--kubeconfig=xin.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=xin \
--kubeconfig=xin.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=xin.kubeconfig
# 执行文件
bash kubeconfig.sh
# 将文件传到node节点
scp xin.kubeconfig node1:/root/
# 测试 发现xin证书没有授权
$ kubectl get pods --kubeconfig=/root/.kube/config
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-79899cbcb-nl52v 1/1 Running 1 2d
$ kubectl get pods --kubeconfig=xin.kubeconfig
Error from server (Forbidden): pods is forbidden: User "xin" cannot list resource "pods" in API group "" in the namespace "default"
$ cfssl-certinfo --cert xin.pem # 查看证书信息
# 授权操作
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] #API组,空表示在核心组
resources: ["pods"] #资源
verbs: ["get", "watch", "list"] # 操作方法:查看,始时查看,列表
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User #主体
name: xin #用户名
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #角色
name: pod-reader #绑定的角色名称
apiGroup: rbac.authorization.k8s.io
# 执行
$ kubectl apply -f rbac.yaml
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created
$ kubectl get role #创建成功
NAME CREATED AT
leader-locking-nfs-client-provisioner 2023-07-07T18:06:03Z
pod-reader 2023-07-09T19:06:55Z
$ kubectl get pods --kubeconfig=xin.kubeconfig # 可以访问了
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-79899cbcb-nl52v 1/1 Running 1 2d1h
标签:Kubernetes,框架,--,xin,rbac,安全,io,k8s,authorization
From: https://www.cnblogs.com/superingXin/p/17539333.html