1、认证,授权,准入控制
-
流程
-
对于认证,授权,访问控制精细化的设置
-
api-server是集群访问控制的唯一入口
-
在部署应用程序的时候,通过nodeport暴露程序,访问的时候,认证–>>授权—>>准入控制
-
-
认证
- 对客户端的认证,用户名和密码进行验证
-
授权
- 判断你是否有操作资源的权限,比如,你要创建一个pod的请求,授权会检查这个名称空间下的pod的创建你是否有权限进行该操作,没有的话,则为无法实现该操作
-
准入控制机制
-
位于apserver中,一般用来做身份验证和授权
-
2个控制器,来进行验证,最后一次的验证
-
1、认证
-
认证的种类:
-
令牌认证(token)
- 需要一对密码下来,客户端登录的时候使用这个密码即可进行登录,k8s提供了一个resetful接口,所有服务都是通过这个http协议提供的
-
ssl认证
-
-
k8s上的账号
-
user account, 人可以进行登录的账号,客户端对apiserver发出了一个请求,apiserver判断这个用户是否有操作的权限,不同账户有不同的权限
-
service account 方便pod里面的进程调用k8s api的一种资源,创建名称空间后,默认会创建一个sa类型,创建pod的时候没有指定sa的话,会自动的使用默认的sa账号
-
sa的局限性就是只在自己的名称空间下面有效
-
之前的版本的时候,创建sa的时候,会创建一个token和secret,但是之后的版本就不会创建secret
-
-
认证
- 就是一个apiserver信任这个账户的过程
#查看默认的sa
[root@master pv]# kubectl get sa
NAME SECRETS AGE
default 0 17h
[root@master pv]# kubectl create sa test
serviceaccount/test created
[root@master pv]# kubectl describe sa test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
2、授权
-
授权的种类
-
rbac控制
-
role和rolebinding关系,只对一个名称空间有权限,通过这个用户绑定到这个角色,但是不对这个其他的名称空间有权限
-
clusterrole和clusterrolebinding关系,集群角色,对所有的名称空间都有操作的权限
-
三种绑定的方式
-
role和rolebinding之间的绑定
-
clusterrole和clusterrolebinding绑定
-
rolebinding绑定clusterrole
-
如果有n个名称空间的话,就需要创建n个role和n个rolebindging进行绑定,非常的不方便,只需要定义一个集群角色(clusterrole)与rolebinding进行绑定,对clusterrole进行授权,这样的话,就会对自己的名称空间下面有管理员的权限
-
这样的话,用户通过集群角色与角色绑定进行关联的话,对于所有的名称空间下面都会有操作的权限,rolebinding只对自己的名称空间有权限,需要新创建一个role,只需要一个clusterrole即可
-
-
-
3、准入控制
4、rbac授权策略
1、role角色和rolebinding集群角色
#role只能对一个名称空间
[root@master rbace]# cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-read
namespace: test
rules:
- apiGroups: [""] #支持的api组列表
resources: ["pods"] #支持的资源对象列表,pods等
resourceNames: [] #指定资源的名称
verbs: ["get","watch","list"] #最资源对象的操作
#定义一个集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-cluster
rules:
- apiGroups: [""]
resources: ["pods"]
resourceNames: []
verbs: ["get","watch","list"]
2、角色绑定和集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rolebind
namespace: test
roleRef: #绑定的角色
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-role
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-cluster
subjects: #绑定的主体,可以是用户,service account等
5、操作
1、命令行创建
2、限制不同用户对k8s的操作
#切换用户的时候只能查看名称空间下面的内容,其他的不能进行查看
#将配置文件里面admin的信息删除即可,拷贝到家目录下即可
#创建证书
##创建私钥
[root@master ~]# openssl genrsa -out devuser.key 2048
##利用私钥创建一个csr(证书请求)文件
openssl req -new -key devuser.key -subj "/CN=devuser" -out devuser.csr
##私钥加上请求文件生成证书
openssl x509 -req -in devuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devuser.crt -days 365
#生成账号
[root@master ~]# kubectl config set-credentials devuser --client-certificate=./devuser.crt --client-key=./devuser.key --embed-certs=true
User "devuser" set.
#设置上下文参数,这里设置名称空间没有直接的关系,并不是这个用户只能在这个名称空间下面操作,其他的空间也可以,要设置权限
kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser --namespace=dev
#查看上下文
[root@master ~]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
devuser@kubernetes kubernetes devuser dev
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
#切换为创建的用户的上下文环境中
[root@master ~]# kubectl config use-context devuser@kubernetes
Switched to context "devuser@kubernetes".
#发现看不了,因为没有设置这个用户的相关的权限
[root@master ~]# kubectl get pod -n test
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "test"
#只能devuser只能在test空间下面查看pod,其他空间不行
[root@master test]# cat devuser.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: devuser-role
namespace: test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: devuser-rolebinding
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: devuser-role
subjects:
- name: devuser
kind: User #用户绑定上面
apiGroup: rbac.authorization.k8s.io
#现在这个就有查看pod权限了
[root@master test]# kubectl config use-context devuser@kubernetes
Switched to context "devuser@kubernetes".
[root@master test]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 8m51s
#创建一个devuser用户,将./kube/config文件中的admin删除掉,只留下一个devuse拷贝到devuser家目录下面
[root@master devuser]# cp -ar /root/.kube/ .
[root@master devuser]# su - devuser
Last login: Thu Sep 19 08:21:18 UTC 2024 on pts/0
[devuser@master ~]$ kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 24m
#只能看test名称空间下面的内容,其他空间都不能查看
[devuser@master ~]$ kubectl get pod -n default
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "default": RBAC: role.rbac.authorization.k8s.io "devuser-role" not found
3、对于service account授权
-
这个sa就是为pod服务的,决定着里面pod的权限
-
创建一个sa后,会有一个token,还要创建一个secret绑定一下即可
#创建sa和secret
[root@master sa-role]# cat sa-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: se1
namespace: test
annotations:
kubernetes.io/service-account.name: sa1
data:
username: YWRtaW4=
password: YWRtaW4=
type: Opaque
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa1
namespace: test
secrets:
- name: se1
#创建pod,关联sa
[root@master sa-role]# cat sa-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sa-pod
namespace: test
spec:
containers:
- name: buxybox
image: docker.io/library/busybox:1.28
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","sleep 36000"]
serviceAccount: sa1
#默认的token会挂在到/var/run/secrets/kubernetes.io/serviceaccount这个路径下面,但是自定义的secre需要自己手动指定
#创建一个pod文件,并且将secret挂载到里面去
[root@master sa-role]# cat sa-pod.yaml
[root@master sa-role]# cat sa-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sa-pod
namespace: test
spec:
containers:
- name: buxybox
image: docker.io/library/tomcat
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /tmp/config
name: sa-1
serviceAccount: sa1
volumes:
- name: sa-1
secret:
secretName: se1
#secret被挂载到里面了
[root@master sa-role]# kubectl exec -ti -n test sa-pod -- /bin/bash
root@sa-pod:/usr/local/tomcat# cd /tmp/config/
root@sa-pod:/tmp/config# ls
password username
root@sa-pod:/tmp/config#
#sa的token信息
root@sa-pod:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt namespace token
#pod里面进行访问的时候,发现没有权限
root@sa-pod:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "pods is forbidden: User \"system:serviceaccount:test:sa1\" cannot list resource \"pods\" in API group \"\" in the namespace \"test\"",
"reason": "Forbidden", #权限禁止了
"details": {
"kind": "pods"
},
"code": 403
#sa添加权限
[root@master sa-role]# cat sa-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: sa-role
namespace: test
rules:
- apiGroups: ["*"]
resources: ["pods"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-rolebinding
namespace: test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: sa-role
subjects:
- kind: ServiceAccount
name: sa1
apiGroup: "" #这个值就是sa的值
#输出信息省略
[root@master sa-role]# kubectl exec -ti -n test sa-pod -- /bin/bash
root@sa-pod:/usr/local/tomcat# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "144207"
},
"items": [
创建一个service account绑定一个secret 然后创建pod的时候不授权,就没有权限
创建pod的时候授权的话,就会有权限
2、rbac字段
1、role和clusterrole
rules:
- apiGroups: ["*"] #核心的api组,
resources: ["pods"] #常见的资源类型,pods,services,deployment等
verbs: ["*"]
#verbs
- get 获取资源
- list 列出资源
- watch 监视资源
- create 创建资源
3、总结
-
主体为用户的话
- 需要创建用户等一系列的操作,证书等
-
主体为sa的话
-
需要创建一个secret进行关联
-
sa就是为了pod服务的,通过这个来进行通信
-
对sa赋予权限,pod就能做出各种操作
-
-
角色和集群角色
-
角色只作用于单个名称空间
-
集群角色作用于所有的名称空间
-
-
主体
-
sa,k8s的账号,pod访问k8s时的身份标识
-
user 独立于k8s之外的账号
-
-
RBAC(基于角色的访问控制),在k8s中权限检查流程如下
1.认证
-
用户或服务通过身份验证机制(证书,令牌等)与api server建立连接
2.授权:一但用户或服务通过认证,api server对请求的进行授权检查,授权检查的过程包括以下步骤 -
识别主体,api server根据认证信息识别请求的主体,即发送请求的用户,服务或实体
-
确定请求的操作和目标资源,api server解析请求中包含的操作(例如,get,post,delete等)和目标资源(pod,deploy等)
-
查询RBAC规则,api server根据主体和请求的操作的资源,查询与之相关的RABC规则,这些规则通常存储在集群中的role,ClusterRole,rolebinding和clusterrolebinding中
-
匹配规则,api server会将查询到的规则与请求的进行匹配,如果存在请求匹配的规则,则请求被授权执行,否则,请求被拒绝
-
执行请求:如果请求同构了授权检查,api server将hi执行请求所代表的操作,列如创建,更新,删除资源等
通过以上的流程,RBAC系统实现了对用户和服务细粒度访问控制,确保只有经过授权的和服务才能执行特定的操作
-