一 RBAC介绍

RBAC模型(Role-Based Access Control 基于角色的访问控制),就是用户通过绑定角色就能拥有该角色所拥有的权限。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。(可以把角色理解为组,用户加入组即用户绑定角色)
在这里插入图片描述
k8s先创建基于证书的用户,然后给用户授权角色权限,然后把用户证书写入到kubeconfig,开发人员就可以远程使用用户证书连接k8s了

RBAC有2种账户

UserAccount普通用户,针对人
ServerAccount系统用户,针对运行在pod中的进程
Groups: 组

RBAC有2种角色

Role 普通角色
ClusterRole 集群角色

RBAC有2种绑定关系

RoleBinding 角色绑定,只能绑定角色,只能访问指定名称空间内容
ClusterRoleBinding 集群角色绑定,只能绑定集群角色,权限最大可以访问所有名称空间

RBAC资源与权限

# 只有角色才可以分配权限
-resource(资源)
 pod node deployment...
--verb(权限)
get(或取),list(列出),watch(查看),delete(删除)

二、创建普通用户并授权

1、kubeconfig文件详解
• kubectl 就是通过kubeconfig文件来远程连接k8s集群的
• kubectl默认会去~/.kube/config找kubeconfig文件(需要把kubeconfig.yml改名为/root/.kube/config),也可以通过kubectl get pod --kubeconfig=/xxx/kubeconfig参数指定kubeconfig.yaml文件的路径,必须是绝对路径
• kubeconfig可以是任何名称
• 如果有多个kubeconfig可以通过在/etc/profile.conf中指定export KUBECONFIG=/xx/x/kubeconfig.yaml,就可以直接使用kubectl命令了,连接哪个集群就让哪个生效。
• 如果想让开发人员拥有访问所有k8s集群的权限就直接把管理员权限的kubeconfig.yaml文件给他。

(1) 单套kubeconfig(详细解释看多套配置)
# cat ~/.kube/config 
apiVersion: v1
clusters:             # 集群字段
- cluster:
    certificate-authority-data: LS0tLS1CRUxxx  #k8sca证书64位通过解码可获得cat/etc/kubernetes/pki/ca.crt|base64
    server: https://192.168.1.15:6443    # 集群apiserver地址
  name: cluster1      # 集群名称
contexts:             # 上下文关联表字段
- context:
    cluster: cluster1  # 用户可访问的集群名称
    user: wenqiang     # 关联的用户
    namespace: default      # 这里的名称空间没什么用,主要还得看授权时为用户指定的名称空间(可选)
  name: wenqiang@kubernetes # 上下文关联表名字
current-context: wenqiang@kubernetes
kind: Config
preferences: {}
users:                 # 用户字段
- name: wenqiang
  user:
    client-certificate-data: LS0tLS1CRUxxx
    client-key-data: LS0tLS1CRxxx

(2)多套kubeconfig共存
# cat ~/.kube/config 
apiVersion: v1
clusters:                # 这个是k8s集群信息,可以有多个集群
- cluster:               # 第一个集群信息
    certificate-authority-data: xxxx       # k8sca证书64位通过解码可获得cat /etc/kubernetes/pki/ca.crt|base64
    server: https://192.168.1.15:6443      # 访问k8s集群的api地址
  name: cluster1         # 第一个集群信息的名称,这个名字可以自定义只要用户能找到就行
- cluster:               # 第二个集群信息 
    certificate-authority-data: xxx
    server: https://10.29.12.22:6443
  name: kubernetes2  
- cluster:               # 第三个集群信息 
    certificate-authority-data: xxx
    server: https://10.59.32.42:6443
  name: kubernetes      

contexts:                # 这个是上下文关联信息表,用于绑定用户/集群/名称空间,让用户去访问对应的集群和名称空间
- context:               # 第一个上下文关联表
    cluster: cluster1    # 绑定的集群名称
    user: admin          # 绑定的用户,这个用户可以访问cluster1集群
  name: context-cluster1 # 第一个上下文关联表的名字
- context:               # 第二个上下文关联表
    cluster: kubernetes2 # 绑定的集群名称
    namespace: devops    # 里的名称空间没什么用,主要还得看授权时为用户指定的名称空间(可选)
    user: qiangqiang     # 绑定的用户,这个用户可以访问kubernetes2集群中的devops空间资源
  name: qiangqiang@kubernetes # 第二个上下文关联表名称
- context:               # 第三个上下文关联表
    cluster: kubernetes
    namespace: devops
    user: wenqiang
  name: wenqiang@kubernetes
current-context: context-cluster1    # kubectl默认访问的是context-cluster1上下文关联表
kind: Config             # 这是一个配置文件
preferences: {}          # 固定写法
users:                   # 用户信息
- name: admin            # 第一个用户
  user:                  # 用户的密钥信息
    client-certificate-data: xxx
    client-key-data: xxx 
- name: qiangqiang       # 第二个用户
  user:
    client-certificate-data: xxx     # qiangqiang.crt base64解密后的内容
    client-key-data: xxx             # qiangqiang.key base64解密后的内容
- name: wenqiang         # 第三个用户
  user:             
    client-certificate-data: xxxx
    client-key-data: xxxx

2、创建UserAccount用户证书并生成kubeconfig
• 为新用户设置kubeconfig文件是会默认写到~/.kube/config中,可以先把管理员的config挪开,但是这样生成的config会缺少集群信息,需要从别的kubeconfig中拷贝一份就可以了
• 如果kubeconfig中有多个集群地址的话每次kubectl访问k8s时就需要提前通过kubectl config use-context切换一下集群关系表
• kubeconfig只能让用户可以远程连接k8s,还需要绑定角色才能访问k8s资源。
• UserAccount用户可以直接绑定cluster-admin管理员角色

(1) 创建用户证书(创建证书就是在创建用户):wenqiang.crt和wenqiang.key
# openssl genrsa -out wenqiang.key 2048    # 为用户创建key
# openssl req -new -key wenqiang.key -out wenqiang.csr -subj "/CN=wenqiang/O=ops" # 为用户生成证书申请文件,CN用户名O部门
# openssl x509 -req -in wenqiang.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out wenqiang.crt -days 365 # 使用k8s证书给用户签发新证书
(2) 生成kubeconfig上下文关系表和用户认证信息
# kubectl config set-cluster myk8s --server=https://192.168.1.111:6443 --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs=true  --kubeconfig=/root/wenqiang-admin.conf  # 这一步会生成cluster字段包含集群信息和apiserver地址并保存在指定kubeconfig文件中,embed-certs=true表示把证书内容嵌入到config中
# kubectl config  set-credentials wenqiang --client-certificate=/tmp/wenqiang/wenqiang.crt --client-key=/tmp/wenqiang/wenqiang.key  --embed-certs=true --kubeconfig=/root/wenqiang-admin.conf # 设置客户端认证参数,这一步会在config中生成user字段包含用户密钥,这里的crt和key是之前创建好的
# kubectl config set-context wenqiang@myk8s --cluster=myk8s --user=wenqiang # 设置上下文参数,这一步会在config中生成context字段,wenqiang@myk8s是上下文关系表名称 --cluster是用户要连接的集群名称,--user是关联的用户
(3) 完成1 2步就生成了kubeconfig文件,如果没有指定--kubeconfig就会把所有的用户信息都保存到默认的~/.kube/config,里面既有admin的信息又有wenqiang或其它用户的信息(里面有默认的admin信息,新生成的用户信息回加入到admin后面),如果想访问kubernetes集群就需要切换到wenqiang@k8s关联表
# kubectl config use-context wenqiang@myk8s   # 这个是连接myk8s集群的
# kubectl config use-context context-cluster1 # 这个是连接另外一个集群的,可以通过kubeconfig中看到
# 如果两个集群都是写的一个apiserver地址那么这两个集群即使再怎么切换看到的东西也一样,如果把myk8s集群的配置文件拷贝到客户的手中,客户拿到后需要先切换集群到wenqiang@myk8s才能使用

# 查看,可以通过--kubeconfig=指定config文件
kubectl config get-clusters    # 查看当前正在使用的集群 
kubectl config get-contexts    # 查看当前集群的上下文关联表
kubectl config get-users       # 查看当前用户信息UserAccount 

# 删除
kubectl config delete-cluster  # 从 kubeconfig 中删除指定的集群
kubectl config delete-context  # 从 kubeconfig 中删除指定的上下文关联表
kubectl config delete-user     # 从 kubeconfig 中删除用户 

3、为UserAccount用户绑定角色并授权
• role和rolebinding只对名称空间生效,所以一个role/rolebinding只能对应一个namespace,想要给用户增加一个名称空间需要再创建一套role/rolebinding,这样同一个用户就有多套角色的权限了
• 如果想让用户能查看所有名称空间内容,那就创建一个只读的clusterrole然后为每个用户创建clusterrolebind,集群角色没有名称空间一说

(1) 命令行方式授权(不推荐)
# 创建角色role,如果想修改需要先删除再创建
kubectl create role wenqiang --verb=get,list,watch --resource=pods --namespace=devops   # 第一个角色对devops名称空间下的pod资源有查案权限
kubectl create role wenqiang --verb=get,list,watch,delete,create --resource=pods --namespace=wenqiang # 第二个角色对wenqiang名称空间下的pod,deployment资源有查看创建删除权限
# 如果想对node有查看权限就需要创建集群角色了,应为node属于集群级别资源
# kubectl create clusterrole wenqiang-cluster --verb=get,list,watch --resource=nodes
# # kubectl edit role wenqiang  # edit可以编辑角色
----------------------------
kubectl create role :创建角色,角色名字是wenqiang
--verb: 该角色的权限 "get", "list", "watch", "create", "update", "patch", "delete", "exec"
--resource: 支持的资源 "services", "endpoints", "pods","secrets","configmaps","crontabs","deployments","jobs",
  "nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets",
  "horizontalpodautoscalers","replicationcontrollers","cronjobs"

# 创建角色绑定关系表,一个用户可以关联多个角色绑定表,user是之前创建的userAccount用户
kubectl create rolebinding wenqiang --role=wenqiang --user=wenqiang --namespace=devops    # 第一个角色绑定表这个表的名字叫wenqiang
kubectl create rolebinding wenqiang --role=wenqiang --user=wenqiang --namespace=wenqiang  # 第二个角色绑定表
# 想对node有查看权限还需要创建集群角色绑定关系表
# kubectl create clusterrolebinding wenqiang-cluster --clusterrole=wenqiang-cluster --user=wenqiang

# 查看role与rolebinding
# kubectl get rolebinding -n devops               # 查看角色绑定
NAME           ROLE               
wenqiang   Role/wenqiang 
kubectl get role -n devops                         # 查看角色
wenqiang
kubectl describe role wenqiang -n devops           # 查看该角色权限
kubectl describe rolebinding wenqiang -n devops    # 查看角色绑定详细信息
Name:         wenqiang # 角色绑定表名称
Role:
  Kind:  Role
  Name:  wenqiang   # 角色名称
Subjects:
  Kind  Name      Namespace
  ----  ----      ---------
  User  wenqiang  # 关联用户
 
#  查看clusterrole和clusterrolebinding
# kubectl get clusterrole wenqiang-cluster
NAME               CREATED AT
wenqiang-cluster   2024-03-25T11:30:29Z
# kubectl get clusterrolebinding wenqiang-cluster
NAME               ROLE                           AGE
wenqiang-cluster   ClusterRole/wenqiang-cluster   9m47s

(2) yaml方式授权(想修改权限直接修改yaml文件然后apply)
# cat wenqiang-role.yaml 
kind: Role              # 创建角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: devops      # 针对名称空间生效
  name: wenqiang         # 角色名
rules:                  
- apiGroups: [""]
  resources: ["pods","nodes","pods/exec"]    # 针对资源
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "exec"]    # 授权  
---

kind: RoleBinding      # 创建角色绑定表
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: wenqiang       # 角色绑定表名称
  namespace: devops    # 针对名称空间生效
subjects:
- kind: User           # 关联类型为用户
  name: wenqiang       # 用户名称,这个用户需要提前创建好
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role           # 关联的类型为角色
  name: wenqiang       # 角色名称
  apiGroup: rbac.authorization.k8s.io

4、让用户能远程连接k8s资源

(1) 把生成的~/.kube/config拷贝到用户远程机器上,在远程机器创建~/.kube/目录
(2) 再远程机器上安装同样版本的kubernetes-client
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.25.6/bin/linux/amd64/kubectl
mv kubectl /usr/local/bin
kubectl version
(3) 使用命令访问k8s集群,先切换到指定集群。

三、创建SA系统用户并授权集群角色权限

• 系统用户ServiceAccount是用于连接pod中的程序的,并不能当作真实用户来远程连接k8s集群,它的用途是当jenkins/prometheus需要连接k8s集群时才能通过sa的token来建立连接
• cluster-admin是管理员角色拥有所有权限
• 创建kubeconfig过程只能通过命令行,无法下入到yaml文件中
1、命令行操作(不推荐,建议编写yaml文件)

(1) 创建名称空间
# kubectl create ns devops

(2) 创建系统账户ServiceAccount并加入名称空间
# kubectl create sa wenqiang-sa -n devops
# kubectl get sa -n devops       # 查看sa用户
# kubectl delete sa wenqiang-sa  # 删除sa用户

(3) 创建集群角色
# kubectl create clusterrole wenqiang-cluster --verb=get,list,watch,create,delete --resource=pods,services,nodes

(4) 创建集群角色绑定关系,并指定要绑定的集群角色和系统用户(集群角色/角色需要提前创建)
 kubectl create clusterrolebinding wenqiang-crb --clusterrole=cluster-admin --serviceaccount=devops:wenqiang-sa
--------------------
kubectl create clusterrolebinding 表示创建一个集群角色绑定关系,为这个绑定关系起个名字叫wenqiang-crb
--clusterrole 表示要绑定的集群角色,我没有绑定wenqiang-cluster而是绑定的cluster-admin是k8s自带的一个角色,该角色拥有所有权限
--serviceaccount  表示要绑定的系统用户,devops:wenqiang-sa前面是名称空间:后面是用户名称
# kubectl get clusterrolebinding |grep wenqiang  # 查看集群角色绑定关系
# kubectl delete clusterrolebinding wenqiang-crb # 删除集群角色绑定关系

# 为sa用户创建临时token(只有sa用户可以创建token)这个信息不能通过kubectl get secrets查看到的
# kubectl create token wenqiang-sa -n devops

(5) 如果想把sa用户信息保存到kubeconfig中就需要完成以下内容(比如要用这个文件去登录dashboard)
1> 先通过yaml文件创建一个sa用户的token信息,这个信息是可以通过kubectl get secrets查看到的
# cat wenqiang-token.yaml 
apiVersion: v1
kind: Secret        # 这是一个密码类型资源用于存放账户密码/token等类型
type: kubernetes.io/service-account-token    # 指定类型为token
metadata:
  name: wenqiangsa-token      # token的名字
  namespace: devops
  annotations:              # 注释,这个token的账户是wenqiang,通过这个注释来关联用户
    kubernetes.io/service-account.name: "wenqiang-sa" 
2> 然后创建集群信息并保存到kubeconfig中
# kubectl config set-cluster mycluster --server=https://192.168.1.111:6443 --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs=true --kubeconfig=/root/wenqiangsa.conf
3> 创建kubeconfig中user字段信息
# wenqiangsa_token=$(kubectl get secrets wenqiangsa-token -o jsonpath={.data.token}|base64 -d) # 获取sa token
# kubectl config set-credentials wenqiangsa --token=${wenqiangsa_token} --kubeconfig=/root/wenqiangsa.conf
4> 创建kubeconfig中上下文信息
# kubectl config set-context wenqiangsa@mycluster --cluster=mycluster --user=wenqiangsa --kubeconfig=/root/wenqiangsa.conf

2、通过yaml配置文件创sa用户并授权
• 通过yaml只能创建sa用户、sa-token、集群角色、集群角色绑定表
• yaml方式无法创kubeconfig文件,只能通过命令行创建kobeconfig文件

(1) 创建系统用户
# cat sa.yaml 
apiVersion: v1
kind: ServiceAccount       # 这是一个SA用户(k8s系统用户)
metadata:
  name: wenqiang           # SA用户名
  namespace: devops        # 名称空间
# kubectl apply -f sa.yaml

(2) 为刚刚创建的用户设置token密码(如何确定这个token就是给sa创建的?)
# cat wenqiang-token.yaml 
apiVersion: v1
kind: Secret        # 这是一个密码类型资源用于存放账户密码/token等类型
type: kubernetes.io/service-account-token    # 指定类型为token
metadata:
  name: wenqiang-token      # token的名字
  namespace: devops
  annotations:              # 注释,这个token的账户是wenqiang
    kubernetes.io/service-account.name: "wenqiang"
# kubectl describe sa wenqiang -n devops           # 查看sa账户的token名称
# kubectl describe secret wenqiang-token -n devops # 查看token的内容后面要用到

(3) 创建集群角色并授权
# cat clusterrole.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole           # 集群角色类型
metadata:
  name: cluster-wenqiang    # 集群角色名称
rules:                      # 授权操作
- apiGroups:
  - ""
  resources:                # 授权对象
  - nodes
  - services
  - endpoints
  - pods
  - nodes/proxy
  verbs:                    # 该角色拥有这些权限
  - get
  - list
  - watch
# kubectl describe clusterrole cluster-wenqiang # 查看集群角色拥有的权限

(4) 创建集群角色绑定关系表(把sa账户和集群角色绑定一起,让sa拥有集群角色的权限)
# cat  clusterrolebinding.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding          # 集群角色绑定关系
metadata:
  name: wenqiang-crb              # 为这个集群角色绑定关系起个名字
roleRef:                         # 声明开始绑定角色 
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole              # 要绑定的类型为集群角色
  name: cluster-wenqiang         # 要绑定的集群角色名称(上面创建好的)
subjects:                        # 声明开始绑定用户
- kind: ServiceAccount           # 要绑定的类型为SA账户
  name: wenqiang                 # 要绑定的SA账户名称(上面创建好的)
  namespace: devop               # 要绑定哪个名称空间下的SA账户
# kubectl describe clusterrolebinding wenqiang-crb  # 查看绑定关系表详细信息
Name:         wenqiang-crb      # 绑定关系表名称
Labels:       <none>
Annotations:  <none>
Role:                           # 绑定的角色信息
  Kind:  ClusterRole
  Name:  cluster-wenqiang
Subjects:                       # 绑定的账户信息
  Kind            Name      Namespace
  ----            ----      ---------
  ServiceAccount  wenqiang  devop

(5)测试访问
# 如果直接访问会报错401权限不足
https://10.211.55.103:6443/api  error 401
# 找一台远程机测试访问这里的值就是token值
% curl -k https://10.211.55.103:6443/api -H  "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im9JcWI5RzdKRkpQQlExREZFN2d5T1plemNTVXNuRmRHdjlYUV9nLW5zbzQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZvcHMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoid2VucWlhbmctdG9rZW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoid2VucWlhbmciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIwMGVkZDU0MC1jMzVlLTRmODktYWRlYy1lOWZkOWZjMjZkYzEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGV2b3BzOndlbnFpYW5nIn0.f89_zpMokanQQFcJr9p7qX9b35uuMyyhiZTANiAIiVeUh4OPv76Tpw0fc1jD8ndzo0dXh_renETjI0b1coidlpzdAyCBpbxDXc6QcPLmXINr3L7uk6TT4Z7cHZ7_SYWFBLjEHW0EdzbskztugouRcI30pU2vXHOiXevHBr9al-XojoX47ulfcI64ivO2Vtx1tqbTD8UJHXw1lcjN7IJWmp7UArbaEvXedZO3o-2fvSn9OLroIdhh5k-0WLIWvLTUNZwUo2dvCujDMvRtJIhl5EJZUm_v8RKzsA7hs9jiDlhxi4E802GeWSQ29qXetLmlNXE1k7HM4HG4jhwco2GLWg"
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.211.55.103:6443"
    }
  ]
}%

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐