K8s(15)——认证与授权基于rbac实验
主要分为三个部分,认证、授权和准入控制。
目录
访问控制基本流程
主要分为三个部分,认证、授权和准入控制。
认证
k8s将所有客户端发起的请求的请求主体分为两类:用户账户(User Account)和服务账户(Service Account)
用户账户:其使用主体一般是真正的用户,比如集群管理员用户。这类账户一般由外部的用户管理系统存储和管理,k8s本身并不维护这一类任何用户账户的信息,仅仅用于检验用户是否有权限执行其请求的操作
服务账户:其使用主体是应用程序,专用于为Pod中的进程提供访问API Server的身份标识;Service Account属于名称空间级别,有API Server或者管理员手动创建,通常会绑定一个保存着访问API Sever认账凭据的Secret,可用同一名称空间下的Pod方式API Server时使用
k8s支持的认证方式有如下几种
静态令牌文件
X509客户端证书验证
引导令牌(Bootstarp Token)
Service Account令牌认证
Webhook令牌认证
OpenID Connect令牌认证
授权
为了校验用户的操作许可,成功通过身份验证后的请求还要交给授权插件进行权限检查,以确保其拥有执行相应操作的许可。API Server主要支持以下4类内置的授权插件来检查用户的操作权限:
Node:基于Pod资源的调度目标节点来实现对kubelet的访问控制
ABAC:基于属性的访问控制
RBAC:基于角色的访问控制
Webhook:基于HTTP的回调机制实现外部服务REST检查,确认用户授权的访问控制
目前默认启用Node和RBAC两个插件,可以通过kube-apiserver的–authorization-mode选项指定要启用的插件,多个值以逗号分割。
准入控制
准入控制器(admission controller)用于客户端请求在通过身份验证和权限检查之后,将对象数据保存到etcd数据库之前拦截请求,从而实现在资源的创建、修改和删除操作期间强制执行对象的语义验证等功能,读取资源信息的请求不会经过准入控制器检查。API Server内置了许多准入控制器,常用的包括以下几种:
AlwaysPullImage:总是下载镜像,每次创建Pod都要下载镜像
NamespaceLifecycle:拒绝在不存在的名称空间创建资源,而删除名称空间会删除名称空间下的所有资源
LimitRanger:用于确保资源请求不会超出LimitRange的限制范围
ServiceAccount:用于实现服务账户管控机制的自动化,实现创建Pod对象时自动为其附加相关的Service Account对象
ResourceQuota:用于为名称空间设置资源配额,确保在名称空间中创建了任何资源对象时不会超出配额
DefaultStorageClass:监控所有创建PVC对象的请求,保证那些没有附加任何专用StorageClass的请求会被设置一个默认值。如果没有设置默认StorageClass则此准入控制器不执行任何操作
可以通过kube-apiserver的–enable-admission-plugins指定要启用的准入控制插件,通过–disable-admission-plugins指定要禁用的准入控制插件
RBAC
RBAC就是一种访问控制模型,它以角色为中心界定了“谁”(subject)能够对哪个或哪类“对象”(object)执行哪些“操作”(verb)。动作的发出这是“主体”,在k8s上,可以是普通账户也可以是服务账户。“动作”用于表明要执行的具体操作,包括增删改查等,对API Server来说就是POST、GET、PUT、DELETE等请求方法。而“对象”则指管理操作能够施加的目标主体,对k8s来说主要是各类资源对象以及非资源型URL。
RBAC的三个基本概念:
Subject: 被作用者,它表示k8s中的三类主体, user, group, serviceAccountRole:角色,它其实是一组规则,定义了一组对 Kubernetes API对象的操作权限RoleBinding:定义了“被作用者”和“角色”的绑定关系。
Role 和 ClusterRole
Role是一系列的权限的集合,Role只能授予单个namespace 中资源的访问权限ClusterRole 跟 Role 类似,但是可以在集群中全局使用。
ServiceAccount
之前说到,如果镜像放在一个私有仓库中,拉取镜像是会失败的。产生一个secret,名字叫myregistrykey,其中指定了仓库名字,给定了仓库的用户名和密码。
pod绑定sa,创建ServiceAccount,为用户自动生成认证信息,但没有授权
[root@k8s2 ~]# kubectl create sa admin
[root@k8s2 ~]# kubectl get secrets myregistrykey
NAME TYPE DATA AGE
myregistrykey kubernetes.io/dockerconfigjson 1 16d
添加secrets到serviceaccount中
[root@k8s2 secret]# kubectl patch serviceaccount admin -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
现在如果有pod使用admin这个serviceaccount就可以调用myregistrykey,但无法破解具体密码
可以看到myregistrykey和admin绑定成功
[root@k8s2 secret]# kubectl describe sa admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: myregistrykey
Mountable secrets: <none>
Tokens: <none>
Events: <none>
编辑pod,使用sa,所需要的权限则通过sa即可
[root@k8s2 secret]# vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
serviceAccountName: admin #使用admin这个sa
containers:
- name: game2048
image: reg.westos.org/westos/game2048 #拉取私有仓库的镜像
查看,拉取私有仓库成功
认证
UserAccount
进入k8s证书默认生成位置
[root@k8s2 secret]# cd /etc/kubernetes/pki/
生成自签名,2048位,可以用4096
[root@k8s2 pki]# openssl genrsa -out test.key 2048
提交证书申请请求
[root@k8s2 pki]# openssl req -new -key test.key -out test.csr -subj "/CN=test"
产生x509证书,有效期365天
[root@k8s2 pki]# openssl x509 -req -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt -days 365
查看证书
openssl x509 -in test.crt -text -noout
设定test用户使用认证
[root@k8s2 pki]# kubectl config set-credentials test --client-certificate=/etc/kubernetes/pki/test.crt --client-key=/etc/kubernetes/pki/test.key --embed-certs=true
创建上下文切换
[root@k8s2 pki]# kubectl config set-context test@kubernetes --cluster=kubernetes --user=test
查看配置
[root@k8s2 pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.56.172:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: test
name: test@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: test
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
切换用户
[root@k8s2 pki]# kubectl config use-context test@kubernetes
默认用户没有任何权限,需要授权
切回admin
[root@k8s2 pki]# kubectl config use-context kubernetes-admin@kubernetes
进行授权工作,对pod资源进行授权,仅在default的ns
[root@k8s2 rbac]# vim roles.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: myrole
rules:
- apiGroups: [""]
resources: ["pods"] #对pod可以操作,其他不行
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
---
kind: RoleBinding #通过RB赋予给作用对象
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-read-pods
namespace: default #只针对default的ns,其他不行
subjects:
- kind: User
name: test
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: myrole
apiGroup: rbac.authorization.k8s.io
运行,对test角色权限设定成功
[root@k8s2 rbac]# kubectl apply -f roles.yaml
role.rbac.authorization.k8s.io/myrole created
rolebinding.rbac.authorization.k8s.io/test-read-pods created
切换到test
[root@k8s2 rbac]# kubectl config use-context test@kubernetes
Switched to context "test@kubernetes".
测试,创建和查询pod都可以
[root@k8s2 rbac]# kubectl run demo --image nginx
pod/demo created
[root@k8s2 rbac]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 2s
但现在只能操作pod资源,其它不行
切回admin
[root@k8s2 rbac]# kubectl config use-context kubernetes-admin@kubernetes
添加权限,使用全局clusterrole,增加pod和deployments
[root@k8s2 rbac]# vim roles.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: myrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-read-pods
namespace: default
subjects:
- kind: User
name: test
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: myrole
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole #全局资源,不需要指定ns
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myclusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "delete", "create", "update"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding #RoleBinding必须指定namespace
metadata:
name: rolebind-myclusterrole
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding #ClusterRoleBinding全局授权
metadata:
name: clusterrolebinding-myclusterrole
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
运行
[root@k8s2 rbac]# kubectl apply -f roles.yaml
role.rbac.authorization.k8s.io/myrole unchanged
rolebinding.rbac.authorization.k8s.io/test-read-pods unchanged
clusterrole.rbac.authorization.k8s.io/myclusterrole unchanged
rolebinding.rbac.authorization.k8s.io/rolebind-myclusterrole unchanged
clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding-myclusterrole created
切回test
[root@k8s2 rbac]# kubectl config use-context test@kubernetes
deployments创建没问题了,但是也仅限于pod和这个,其他的svc没有
切回admin
[root@k8s2 rbac]# kubectl config use-context kubernetes-admin@kubernetes
回收
[root@k8s2 rbac]# kubectl delete -f roles.yaml
[root@k8s2 rbac]# kubectl config delete-user test
[root@k8s2 rbac]# kubectl config delete-context test@kubernetes
更多推荐
所有评论(0)