admin管理员组文章数量:1633030
1、报错信息描述
错误信息:
Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. endpoints "xxx" is forbidden: User "system:serviceaccount:xxx:default" cannot get resource "endpoints" in API group "" in the namespace "xxx".
报出这个错误,要解决的话,首先你要知道serviceaccount是什么?
serviceaccount也是K8s中的资源对象,例如Pod、Deployment等一样,可以通过yaml定义。
Pod内部环境应用程序在访问Kubernetes的Api Server的时候的权限验证就是通过serviceaccount实现的。
当你创建namespace的时候,会默认为该namespace创建一个名为default的serviceaccount。可以通过命令查看:
kubectl get sa -n 你的namespace
正如报错所示“system:serviceaccount:xxx:default”,这个就是pod内部的用到的默认的serviceaccount,xxx代表你的namespace,default则是namespace的默认serviceaccount名字,前面system:serviceaccount代表k8s中的serviceaccount用户组。
所以这个的错误的信息代表的意思是,pod用namespace默认的serviceaccout是没有权限访问K8s的 API group的。
2、解决方法
知道了报错的原因,我们就可以解决这个问题了,那就是创建一个新的serviceaccount绑定到我们的pod上。
而新创建的serviceaccount需要有 API group的权限。说到权限有涉及到新的知识点,就是K8s的授权插件,我这里用的是RBAC,意思就是根据角色来控制权限。
serviceaccount对象代表一个账号,则我们还需要一个role对象和一个role与serviceaccount绑定的rolebinding对象,这些都是RBAC插件提供的资源对象。
举个例子,这个例子可以解决上面的报错,在你的namespace下创建一个拥有K8s集群里最高权限的serviceaccount,可以对任何资源对象操作:
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: test #ClusterRoleBinding的名字
subjects:
- kind: ServiceAccount
name: test #serviceaccount资源对象的name
namespace: test #serviceaccount的namespace
roleRef:
kind: ClusterRole
name: cluster-admin #k8s集群中最高权限的角色
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test # ServiceAccount的名字
namespace: test # serviceaccount的namespace
labels:
app: test #ServiceAccount的标签
然后通过在deployment内设置spec.template.spec.serviceAccountName或者pod的spec.serviceAccountName完成与serviceaccount的绑定。
以上可以解决,但是权限也非常的高。
我们还可以创建一个 ClusterRole,一个ServiceAccount,一个ClusterRoleBinding。(访问集群中所有资源的权限)
或者Role,一个ServiceAccount,一个RoleBinding。(同一个namespace下的资源控制)
ClusterRole制定角色的权限,然后通过ClusterRoleBinding与ServiceAccount绑定起来,做到精细化的权限控制
配置kubernetes中的访问权限
其实这个spring-cloud-kubernetes 项目最终能否部署成功,最大的坑就在这里,首先官方文档对这里的描述介绍简直是惜字如金
如果不仔细看,很容易误会这里对kubernetes api的调用是使用的默认的serviceaccount,其实是需要自定义 角色、用户、和角色绑定的.
另外网上的资料对权限这块都是基于非常简单的default命名空间,如果再换一个自定义的,就不起作用了,所以我在这一步,花费了不少时间,如果不是很了解kubernetes的权限控制,很容易停滞不前
spring-cloud-kubernetes项目无非就是帮我们封装了对kubernetes的api的访问,然而kubernetes是有自己的权限控制的,那么spring-cloud-kubernetes 是如何通过对应的权限校验成功调用对应的api的,kubernetes有自己的一套基于权限的角色控制,通过角色、用户、两者的绑定关系这三个api对象,来配置不同用户的的权限,而大部分时候我们在使用k8s,根本不关心这个用户是谁,是因为我们使用了它的内置用户ServiceAccount,所以在实际部署的时候针对不同的环境和业务需求可能需要配置我们自己的角色权限
role
首先要配置角色,它定义了一个权限集合,我们这里配置这个名叫svcdemo的角色,拥有对"pods",“services”,"endpoints"这三个api对象的所有权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: mynamespace
name: svcdemo
rules:
- apiGroups: [""]
resources: ["pods","services","endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
ServiceAccount
定义上文中用到的内置用户ServiceAccount,需要在deployment中明确指定
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: mynamespace
name: svcdemo
角色绑定
已经定义好了角色和用户,最后需要角色绑定这个api对象,将这两者关联起来,这样我们才能在项目中成功的调用到k8s的api
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: svcdemo
namespace: mynamespace
subjects:
- kind: ServiceAccount
name: svcdemo
namespace: mynamespace
roleRef:
kind: Role
name: svcdemo
apiGroup: rbac.authorization.k8s.io
修改Deployment
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: svcdemo
namespace: mynamespace
spec:
replicas: 1
selector:
matchLabels:
run: svcdemo
template:
metadata:
labels:
run: svcdemo
spec:
## 后面有对serviceAccountName进行讲解
serviceAccountName: svcdemo
本文标签: SpringCloudKubernetesServiceAccount
版权声明:本文标题:SpringCloudKubernetes的ServiceAccount配置 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729157371a1188115.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论