SpringCloudKubernetes的ServiceAccount配置

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
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值