k8s结合jumpserver作kubectl权限控制 用户在多个namespaces的访问权限 rbac权限控制

圈子过小,作人留一面,往后好相见。html

 

其实这个文章就是用户用jumpserver登陆到k8s master节点node

而后执行kubectl的时候只有本身namespaces的全部权限。git

 

背景

1,k8s 有一天忽然kubectl 执行任何命令都报权限不对。后端

2,最后查明是由于有一个开发不当心把admin的ClusterRoleBinding给删除了。api

3,jumpserver给全部开发的权限都是同一个普通用户。安全

4,由于咱们是一个k8s集群,而后用不一样的namespaces区分不一样的业务小组。每一个小组有固定的node机器。bash

5,kubectl 的配置文件都是用的同一个,权限也是admin的。app

 

要求

1,领导要求业务小组只有本身namespaces的权限。spa

2,业务小组不能有一个集群的大的权限,好比删除node,不能更新master node的一些信息。ssr

 

整体思路

1,在jumpserver上面新建各业务方系统用户。

2,把系统用户绑定给各业务方用户组。(关于Jumpserver  系统用户和管理用户介绍,后期出一篇单独的文章。)

3,在k8s  master1节点上面的各个业务方系统用户家目录下面 新建不一样的.kube/config文件。

 

1、.kube/config 文件生成

1,这里我就用我这边的需求写了,有关于k8s rbac的分享,我在后期会写一篇单独的文章。https://www.cnblogs.com/fanfanfanlichun/p/15005427.html

2,业务方有:axer,paas。这是我公司这边的两个业务方。

3,其实k8s的rbac确实很是的复杂,难理解,实现权限划分的方式

 

1.1 权限划分思路

1,首先是各类资源的权限,k8s资源又分两种,一种是集群的资源,一种是ns资源。

2,而后是将权限和谁绑定起来。 大概就是两步:权限和绑定权限。

 

3,我这里是用了两个ClusterRole,一个是集群的资源的权限,一个是ns资源的权限

4,我选择的是sa来作受权的对象。而后用这个sa的token去作kubectl的权限验证

5,多个RoleBinding,每个RoleBinding把ns的资源权限固定在一个ns里面。你想要这个sa有哪些ns的权限,就写几个RoleBinding。

6,一个ClusterRoleBinding,用于绑定sa对集群资源的权限。

 

1.2 建立ClusterRole

 

1.2.1 集群资源权限

也就是说整个k8s集群的一些权限。好比:get ns,get node,get node status,git ns status......

# 其实这里就是设置对k8s集群的一些权限的

apiVersion: rbac.authorization.k8s.io/v1    # api
kind: ClusterRole                           # 资源类型
metadata:                                   # 元数据 ClusterRole 不受ns的限制,因此不用写ns
  name: business-axer-get-auth              # ClusterRole 的名称,能区分就行
rules:
- apiGroups:                                # apiGroups 就是api资源组,你kubectl get apiservice 就能够看到集群全部的api组
  - ""                   # 我这里表明为空,就是api组里面有一个v1.   这样的
  resources:             # 就是k8s资源的名称。kubectl api-resources 这个命令能够查看到,第一列是资源名称,就是能够写在这里的。
                         # 第二列是简写,kubectl get 后面的能够简写。
                         # 第三列是APIGROUP组
                         # 第四列是是否属于NAMESPACED资源,就是你能够在ns下面看到的资源
                         # 第五列是kind的时候写的名称
                         # 资源还分子资源,后期会写一篇专门的文章介绍
  - namespaces/status    # 这个是ns状态
  - namespaces           # 这个是ns
  - persistentvolumes    # pv
  verbs:                 # verbs是定义动做的
  - get                  # 就是能够查看ns的权限
  - list
  - watch
- apiGroups:
  - ""
  resources:             # 这里定义的是能够查看node的权限,更新node的权限。
  - nodes
  - nodes/status
  verbs:
  - get
  - list
  - watch
  - patch
  - update
- apiGroups:
  - "storage.k8s.io"
  resources:               # 这里定义的是能够查看sc的权限,由于咱们有后端的存储集群,他们能够对sc的全部权限
  - storageclasses
  - storageclasses/status
  resourceNames:           # 由于sc属于集群资源,不一样的业务方须要对本身的sc才有 所有权限。
  - axersc                 # 全部这里能够指定对哪个sc有所有权限
  verbs:
  - create
  - delete
  - deletecollection
  - get
  - list
  - patch
  - update
  - watch

 

1.2.2 ns资源权限

就是定义业务方对本身ns的全部权限,本身的ns里面的全部资源都要有权限。

点击查看代码

点击查看代码

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: business-axer-admin-auth
rules:
- apiGroups:
  - ""
  resources:            # 对pod的一些权限。
  - pods/attach
  - pods/exec           # exec pod
  - pods/portforward    # 设置pod的转发
  - pods/proxy
  - secrets             # secrets的权限
  - services/proxy
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - serviceaccounts     # sa的权限
  verbs:
  - impersonate
- apiGroups:
  - ""
  resources:
  - pods
  - pods/attach
  - pods/exec
  - pods/portforward
  - pods/proxy
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - replicationcontrollers
  - replicationcontrollers/scale
  - secrets
  - serviceaccounts
  - services
  - services/proxy
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - apps
  resources:
  - daemonsets
  - deployments
  - deployments/rollback
  - deployments/scale
  - replicasets
  - replicasets/scale
  - statefulsets
  - statefulsets/scale
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - batch
  resources:
  - cronjobs
  - jobs
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - extensions
  resources:
  - daemonsets
  - deployments
  - deployments/rollback
  - deployments/scale
  - ingresses
  - networkpolicies
  - replicasets
  - replicasets/scale
  - replicationcontrollers/scale
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - policy
  resources:
  - poddisruptionbudgets
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  - networkpolicies
  verbs:
  - create
  - delete
  - deletecollection
  - patch
  - update
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - pods
  - replicationcontrollers
  - replicationcontrollers/scale
  - serviceaccounts
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - bindings
  - events
  - limitranges
  - pods/log
  - pods/status
  - replicationcontrollers/status
  - resourcequotas
  - resourcequotas/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - apps
  resources:
  - controllerrevisions
  - daemonsets
  - deployments
  - deployments/scale
  - replicasets
  - replicasets/scale
  - statefulsets
  - statefulsets/scale
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - autoscaling
  resources:
  - horizontalpodautoscalers
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - batch
  resources:
  - cronjobs
  - jobs
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  resources:
  - daemonsets
  - deployments
  - deployments/scale
  - ingresses
  - networkpolicies
  - replicasets
  - replicasets/scale
  - replicationcontrollers/scale
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - policy
  resources:
  - poddisruptionbudgets
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  - networkpolicies
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - authorization.k8s.io
  resources:
  - localsubjectaccessreviews
  verbs:
  - create
- apiGroups:
  - rbac.authorization.k8s.io
  resources:
  - rolebindings
  - roles
  verbs:
  - create
  - delete
  - deletecollection
  - get
  - list
  - patch
  - update
  - watch

 

这样两个权限的ClusterRole就建立好了。其实就是定义权限。有哪些权限。

 

1.3 建立sa ServiceAccount

我选择的是sa作角色,固然也能够选择user,或者usergroup。就是K8s实现权限划分有不少方式。看你们的选择需求了。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: business-axer-serviceaccount    # sa的名称。随便取,固然你要能认识区分
  namespace: business-auth              # sa的ns。我这里单独的建了一个ns,就是为了作权限划分的ns。

 

1.4 建立ClusterRoleBinding

ClusterRoleBinding是用来绑定集群权限的。

也就是说把我上面定义的集群权限ClusterRole绑定给sa。这样这个sa就有操做集群的一些字眼的权限了。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding                   # ClusterRoleBinding 用于绑定集群权限的
metadata:
  name: business-axer:get                  # 名称  ClusterRoleBinding 不受ns的限制,因此没有ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole                        # 上面定义的ClusterRole名称
  name: business-axer-get-auth
subjects:
- kind: ServiceAccount                     # 上面定义的sa名称
  name: business-axer-serviceaccount
  namespace: business-auth

 

1.5 建立RoleBinding

这个RoleBinding就是绑定ns里面的资源的权限的。

也就是说我把上面定义的ClusterRole权限绑定给sa。而后这个权限只能在这个RoleBinding所在的ns里面才有权限。

想要受权给业务放哪一个ns的权限 就要在哪一个ns里面建立一个RoleBinding。

假如说一个业务放有10个ns的权限,那么久须要建立10个RoleBinding。

 

# 我这下面是给这个sa了两个ns的全部权限
# ai-platform-deploy和ai-platform-test命名空间的全部权限
# 若是须要别的ns的权限那就定义多个RoleBinding。
# 固然这个RoleBinding必需要在ns里面。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: business-axer:ai-platform-deploy
  namespace: ai-platform-deploy
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: business-axer-admin-auth
subjects:
- kind: ServiceAccount
  name: business-axer-serviceaccount
  namespace: business-auth

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: business-axer:ai-platform-test
  namespace: ai-platform-test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: business-axer-admin-auth
subjects:
- kind: ServiceAccount
  name: business-axer-serviceaccount
  namespace: business-auth

 

权限和绑定都作完了,剩下的就是生成config文件了

1.6 生成config文件

 

我这里选择的是token的验证方式。

我是写了一个简单的脚本。

#!/bin/bash
sa_name="business-axer-serviceaccount"    # 这个是sa的名称

user="business-axer"                      # 这个是user,对于我使用token的验证方式,这里的user没啥用,随便写
context_name="business-axer-ct"           # 对于我使用token的验证方式,这个也是能够随便写,

cp ./demo.config ./guest.config           # 拷贝一份demo.config

# 这里是获取sa的secret名称,每个sa都会有。
secret_name=`kubectl get sa -n business-auth $sa_name -o go-template='{{range .secrets}}{{.name}}{{end}}'`
# 这里是获取secret的token
TOKEN=`kubectl -n business-auth get secret $secret_name -o go-template='{{.data.token}}'`

# 这下面是设置一些上下文
kubectl config set-credentials $user --token=`echo ${TOKEN} | base64 -d` --kubeconfig=./guest.config
kubectl config set-context $context_name --cluster=kubernetes --user=$user --kubeconfig=./guest.config
kubectl config use-context $context_name --kubeconfig=./guest.config

 

demo.config文件

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUCg==   这个是固定的,你查看一下线上的,其实就是https安全验证,ca证书
    server: https://10.19.250.206:8443         # k8s集群apiservice的端口
  name: kubernetes    # 集群的名称
kind: Config

 

最终的guest.config文件,个人下面的除了token和ca我删了,其余的都是正确的。

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LShRTl0tLS0tCg==
    server: https://10.19.250.206:8443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: business-axer
  name: business-axer-ct
current-context: business-axer-ct
kind: Config
preferences: {}
users:
- name: business-axer
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZC-iyX0M6m5nEXqC6w

 

解读以下:

clusters记录了 clusters(一个或多个 K8S 集群)信息:

        name是这个 cluster(K8S 集群)的名称代号

        server是这个 cluster(K8S 集群)的访问方式,通常为 IP+PORT

        certificate-authority-data是证书数据,只有当 cluster(K8S 集群)的链接方式是 https 时,为了安全起见须要证书数据

users记录了访问 cluster(K8S 集群)的帐号信息:

        name是用户帐号的名称代号

        user/token是用户的 token 认证方式,token 不是用户认证的惟一方式,其余还有帐号+密码等。

contexts是上下文信息,包括了 cluster(K8S 集群)和访问 cluster(K8S 集群)的用户帐号等信息:

        name是这个上下文的名称代号

        cluster是 cluster(K8S 集群)的名称代号

        user是访问 cluster(K8S 集群)的用户帐号代号

current-context记录当前 kubectl 默认使用的上下文信息

kind和apiVersion都是固定值,用户不须要关心

preferences则是配置文件的其余设置信息,我没有使用过,暂时不提。

1.7 config文件放入业务方用户的家目录下面的.kube/config。权限要644的。

 

多个业务放就按照上面的步骤建立就行,能够把业务放理解成sa。

 

2、配置jumpserver

其实就是在jumpserver上面建立系统用户,而后把这个系统用户绑定到用户组。

那么用户组里面的用户登陆k8s master1机器的时候就是他们本身的系统用户了。

而后这个用户执行kubectl 的时候 默认会去家目录下面的.kube找config文件。

config文件又是咱们生成的。

这样就能够把用户限制在ns里面了。

 

 

欢迎大佬留言评论,有什么不足的望各位大佬指出。