前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k8s 基于角色的权限控制 RBAC

k8s 基于角色的权限控制 RBAC

作者头像
LinkinStar
发布2022-09-01 14:35:35
6120
发布2022-09-01 14:35:35
举报
文章被收录于专栏:LinkinStar's Blog

RBAC 之所以一直没有写这个,一方面是因为它确实并不复杂,二来平常确实接触不多,今天就来顺路讲讲它

定义

Role-Based Access Control 我们常说的 RBAC,我们知道在一个后台管理系统里面经常会有权限管理。而最常用的一种权限设计方式就是基于角色的权限设计,A 用户是管理员拥有所有的权限,B 是普通用户角色只有部分权限等等,而 k8s 也是如此,k8s 内部也有许许多多的资源,通过 RBAC 的权限设计进行管理授权工作。

  • Role: 角色,定义了一组对 Kubernetes API 对象的操作权限
  • Subject: 用户,绑定角色的对象
  • RoleBinding: 用户和角色的绑定关系

其实非常好理解: 用户 -> 角色 -> 权限

Role

代码语言:javascript
复制
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

这就是 k8s 里面的角色,这里定义了一个角色 pod-reader 这个角色可以对 default 命名空间中的 pod 资源进行 get watch list 操作

ClusterRole

代码语言:javascript
复制
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Secret 对象的资源的名称为 "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

ClusterRole 属于集群范围,所以整个集群对应的资源都可以被使用

RoleBinding

代码语言:javascript
复制
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pods
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
  name: jane # "name" 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role # 此字段必须是 Role 或 ClusterRole
  name: pod-reader     # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io

有了角色自然就是将用户绑定到对应的角色上去了,这个没有什么好说的,很容易理解

ClusterRoleBinding

代码语言:javascript
复制
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager # 'name' 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

同样的 ClusterRoleBinding 也是类似

ServiceAccount

其实 User 不多,其实我们更多的使用 k8s 里的内置用户也就是 ServiceAccount,这个 ServiceAccount 会生成一个 secrets 利用这个可以跟 APIServer 进行交互

代码语言:javascript
复制
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: mynamespace
  name: example-sa
代码语言:javascript
复制
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-rolebinding
  namespace: mynamespace
subjects:
- kind: ServiceAccount
  name: example-sa
  namespace: mynamespace
roleRef:
  kind: Role
  name: example-role
  apiGroup: rbac.authorization.k8s.io
代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  namespace: mynamespace
  name: sa-token-test
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
  serviceAccountName: example-sa

通过 serviceAccountName 指定对应的 ServiceAccount 就可以使用了

通过 client-go 来使用

如果只是上面那样有点空,也有点虚,不如直接开官网文档来的快。下面就直接使用实际的案例来看看 rbac 到底是怎么样作用的。

目标

我们的目标是创建一个用户,然后绑定对应的权限,有了对应的权限之后,创建的对应的 deployment 使用对应的用户,然后获取到对应的资源,我们使用 client-go 直接获取对应的资源信息看看。

创建用户

这里我们使用 ClusterRole,并且直接绑定已有的角色 cluster-admin, 然后创建需要使用的 ServiceAccount

代码语言:javascript
复制
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: admin
  namespace: my-namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: my-namespace
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile

一个简单的 client-go 应用

代码语言:javascript
复制
package main

import (
   "context"
   "fmt"

   metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
   "k8s.io/client-go/kubernetes"
   "k8s.io/client-go/rest"
   //
   // Uncomment to load all auth plugins
   // _ "k8s.io/client-go/plugin/pkg/client/auth"
   //
   // Or uncomment to load specific auth plugins
   // _ "k8s.io/client-go/plugin/pkg/client/auth/azure"
   // _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
   // _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
   // _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
)

func main() {
   config, err := rest.InClusterConfig()
   if err != nil {
      panic(err.Error())
   }

   clientset, err := kubernetes.NewForConfig(config)
   if err != nil {
      panic(err.Error())
   }

   fmt.Printf("all namespaces: ")
   nsList, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
   if err != nil {
      panic(err.Error())
   }
   for _, item := range nsList.Items {
      fmt.Printf("%s ", item.Name)
   }

   fmt.Println()
   fmt.Printf("all deployments in default namespace: ")
   deployments, err := clientset.AppsV1().Deployments("default").List(context.TODO(), metav1.ListOptions{})
   if err != nil {
      panic(err.Error())
   }
   for _, item := range deployments.Items {
      fmt.Printf("%s ", item.Name)
   }

   select {}
}

因为我们的应用运行在 k8s 内部,所以使用 client-go 非常容易,使用 rest.InClusterConfig() 就可以获取到对应配置

只要当前 deployment 有对应的权限,就可以获取到对应的资源 pod 或者 namespace 等

创建 deployment

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rabc-test
  namespace: my-namespace
  labels:
    app: rabc-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rabc-test
  template:
    metadata:
      labels:
        app: rabc-test
    spec:
      containers:
      - name: rabc-test
        image: linkinstars.com/rabc-test:latest
      serviceAccountName: admin

创建 deployment 使用 serviceAccountName 指定刚才创建的 ServiceAccount admin 这里需要注意缩进,它是 template 下的 spec 的一个属性

运行后查看日志则可以获取到对应的所有的 namespace 列表和 default 下的所有 deployment

总结

  • 对于 k8s 的 rbac 其实使用还是非常简单的,基本上没有必要单独去记,用到的时候需要创建对应权限角色的时候查询对应的文档使用就可以了。
  • 而当我们有了对应权限之后就可以在 k8s 内部的应用使用 client-go 去获取对应的 k8s 的资源信息,并且还可以对相应的资源进行操作,这样就大大的丰富了你开发 k8s 原生应用的想象力

参考文档:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义
  • Role
  • ClusterRole
  • RoleBinding
  • ClusterRoleBinding
  • ServiceAccount
  • 通过 client-go 来使用
    • 目标
      • 创建用户
        • 一个简单的 client-go 应用
          • 创建 deployment
          • 总结
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档