zoukankan      html  css  js  c++  java
  • k8s结合jumpserver做kubectl权限控制 用户在多个namespaces的访问权限 rbac权限控制

    圈子太小,做人留一面,日后好相见。

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

    然后执行kubectl的时候只有自己namespaces的所有权限。

    背景

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

    2,最后查明是因为有一个开发不小心把admin的ClusterRoleBinding给删除了。

    3,jumpserver给所有开发的权限都是同一个普通用户。

    4,因为我们是一个k8s集群,然后用不同的namespaces区分不同的业务小组。每个小组有固定的node机器。

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

    要求

    1,领导要求业务小组只有自己namespaces的权限。

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

    总体思路

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

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

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

    一、.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。

    二、配置jumpserver

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

    那么用户组里面的用户登录k8s master1机器的时候就是他们自己的系统用户了。

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

    config文件又是我们生成的。

    这样就可以把用户限制在ns里面了。

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

  • 相关阅读:
    LeetCode——003 Longest Substring Without Repeating Characters
    LeetCode——002 Add Two Numbers
    LeetCode——001 Two Sum
    【日常训练】Hockey(CodeForces-96C)
    【日常训练】数据中心(CSP 201812-4)
    【赛后补题】Lucky Probability(CodeForces 110D)
    「Leetcode」14. Longest Common Prefix(Java)
    「Leetcode」13. Roman to Integer(Java)
    「日常训练」Magic Stones(CodeForces-1110E)
    「日常训练」Jongmah(Codeforces-1110D)
  • 原文地址:https://www.cnblogs.com/fanfanfanlichun/p/14989454.html
Copyright © 2011-2022 走看看