Kubernetes-RBAC角色权限_命名空间

RBAC角色访问控制策略

在k8s上控制访问权限,Role-based access control (RBAC) - 基于角色(Role)的访问控制,(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。

RBAC里面的几种资源关系图,下面将用下面的资源来演示生产中经典的RBAC应用

|--- Role --- RoleBinding                #只在指定namespace中生效
ServiceAccount ---|
                  |--- ClusterRole --- ClusterRoleBinding  #不受namespace限制,在整个K8s集群中生效

一、RBAC核心概念

1.角色(Role)与集群角色(ClusterRole)

**角色(Role):**是一种Kubernetes对象,它定义了对特定命名空间内资源的一组权限,这些权限可以是创建、读取、更新和删除等操作(增删改查),针对特定的API资源对象(如Pod、Service、ConfigMap、Secret等)。Role对象只能在特定的命名空间内生效,即所定义的权限只适用于该命名空间内的资源。

意思就是角色(Role)被名称空间限制,比如给他授权test1名称空间的怎删改查的权限,他就只能对test1做操作,其他的名称空间不可以,要想对test2的名称空间做操作得需要再加权限。

**集群角色(ClusterRole)**与Role差不多,但是范围更广,Role是受名称空间限制,ClusterRole不受名称空间限制。ClusterRole定义了对集群范围内资源的权限,可以包括所有命名空间中的资源,也可以包括集群级别的资源,列如节点(Nod)、名称空间(Namespace)等。

2.角色绑定(RoleBinding)与集群角色绑定(ClusterRoleBinding)

角色绑定(RoleBinding):用于将用户、组活服务账户与角色关联起来,从而赋予它们在某个命名空间内的资源上执行操作的权限。例如,看了一将角色“编辑者”(Editor)与角色“Alice”绑定在一起,这样Alice就具有在特定命名空间内编辑资源的权限。

集群角色绑定(ClusterRoleBinding):类似于RoleBinding,但作用范围更广泛,它用于将集群角色与用户、组活服务账户绑定在一起,赋予他们在整个集群范围内执行操作的权限。例如,可以将集群角色“集群管理员”(ClusterAdmin)与用户组“管理员组”绑定在一起,这样管理员组的成员就具有在整个集群中执行管理员操作的权限。

3. 主体(Subject)

在Kubernetes中,主体(Subject)是指具有身份的实体,通常是用户(User)、组(Group)或服务账户(ServiceAccount)。主体通过角色绑定或集群角色绑定与角色或集群角色关联在一起,从而获得对Kubernetes资源的访问权限。

二、开始创建

三种角色账号 SA(ServiceAccount)、Role角色 & ClusterRole集群角色、RoleBinding & ClusterRoleBinding

1首先是创建一个ServiceAccount  #简称SA  类似创建一个账号  这时候账号是一个空白的啥也没有  还没有绑定权限

2然后创建权限  权限的话有两种 一种是 Role 角色  #只对指定的NameSpace有效
另一种是ClusterRole  集群角色 #这个是全局 的整个k8s集群的控制 

3创建完Role后  需要把账号 ServiceAccount(SA) 和Role绑定
需要用到RoleBinding    Role里面有RoleBinding  ClusterRole有ClusterRoleBinding

有些服务是需要有RBAC这个权限分配的,不然用不了,比如在k8s上运行的CICD的GItLab-runner 本身gitlab是个pod他还要启动新的pod所以需要权限 ,本身是个pod,pod里面还要启新的pod,用pod去构建代码,打包镜像,pod里面需要生成pod

博哥给的案例

第一类是保证在K8s上运行的pod服务具有相应的集群权限,如gitlab的CI/CD,它需要能访问除自身以外其他pod,比如gitlab-runner的pod的权限,再比如gitlab-runner的pod需要拥有创建新的临时pod的权限,用以来构建CI/CD自动化流水线,这里大家没用过不懂没关系,先简单了解下就可以了,在本课程后面基于K8s及gitlab的生产实战CI/CD内容会给大家作详细实战讲解;

第二类是创建能访问K8s相应资源、拥有对应权限的kube-config配置给到使用K8s的人员,来作为连接K8s的授权凭证

第一类的实战这里先暂时以早期的helm2来作下讲解,helm是一个快捷安装K8s各类资源的管理工具,通过之前给大家讲解的,一个较为完整的服务可能会存在deployment,service,configmap,secret,ingress等资源来组合使用,大家在用的过程中可能会觉得配置使用较为麻烦,这时候helm就出现了,它把这些资源都打包封装成它自己能识别的内容,我们在安装一个服务的时候,就只需要作下简单的配置,一条命令即可完成上述众多资源的配置安装,titller相当于helm的服务端,它是需要有权限在K8s中创建各类资源的,在初始安装使用时,如果没有配置RBAC权限,我们会看到如下报错:

root@node1:~# helm install stable/mysql
Error: no available release name found

这时,我们可以来快速解决这个问题,创建sa关联K8s自带的最高权限的ClusterRole(生产中建议不要这样做,权限太高有安全隐患,这个就和linux的root管理帐号一样,一般都是建议通过sudo来控制帐号权限)

###下面这个clustrer-admin 可以换成自己创建的角色

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

解释一下

#这一系列kubectl命令在Kubernetes集群中执行了几个关键操作,主要是围绕创建一个新的服务账户(ServiceAccount)、为这个服务账户分配集群级别的管理员权限,以及更新一个部署(Deployment)以使用这个新的服务账户。下面是每个命令的详细解释:


1. 创建服务账户
kubectl create serviceaccount --namespace kube-system tiller
#这个命令在kube-system命名空间中创建了一个新的服务账户(ServiceAccount)名为tiller。服务账户是Kubernetes中用于身份验证的实体,它允许Pod内的进程与Kubernetes API服务器进行交互。kube-system命名空间通常用于存放集群级别的资源和系统守护进程。

2. 创建集群角色绑定
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
#这个命令创建了一个集群角色绑定(ClusterRoleBinding),它将cluster-admin集群角色绑定到了kube-system命名空间中的tiller服务账户上。cluster-admin是一个预定义的集群角色,它拥有对集群中几乎所有资源的完全访问权限。这意味着,任何使用这个服务账户的进程都将能够执行集群上的任何操作。

3. 更新部署以使用新的服务账户
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
#这个命令使用kubectl patch命令来更新kube-system命名空间中的tiller-deploy部署(Deployment)。具体来说,它修改了部署的Pod模板(template)中的spec部分,将Pod的serviceAccount字段设置为tiller。这意味着,当这个部署创建新的Pod时,这些Pod将使用tiller服务账户与Kubernetes API服务器进行通信。

这一系列命令的目的是在Kubernetes集群中创建一个具有集群级别管理员权限的服务账户,并将这个服务账户分配给特定的部署(在这个例子中是tiller-deploy)。这样做的原因可能是出于多种考虑,比如允许该部署执行需要高级权限的操作,或者作为临时的解决方案来绕过正常的权限限制。然而,需要注意的是,赋予服务账户cluster-admin角色会带来安全风险,因为它允许执行几乎任何操作,包括可能对集群造成不可逆损害的操作。因此,这种做法应该谨慎使用,并确保受到适当的监控和审计。

1.创建有只读权限的 集群账号

创建一个具有只读权限的Kubernetes kubeconfig 文件,您需要执行以下步骤:

  1. 创建只读ServiceAccount
  2. 创建与ServiceAccount相关联的Secret
  3. 创建具有只读权限的ClusterRole
  4. 将ServiceAccount绑定到只读ClusterRole
  5. 生成kubeconfig文件

1. 创建只读ServiceAccount

创建一个新的ServiceAccount,命名为readonly-user

SA

apiVersion: v1
kind: ServiceAccount #称SA  类似创建一个账号  这时候账号是一个空白的啥也没有  还没有绑定权限
metadata:
  creationTimestamp: null
  name: readonly-user  #SA 的名字 服务帐户的名称为readonly-user。
  namespace: kube-system
kubectl apply -f read-serviceaccount.yaml

2. 创建与ServiceAccount相关联的Secret

Kubernetes会自动为ServiceAccount创建一个Secret,我们可以使用这个Secret来获取token。

3. 创建具有只读权限的ClusterRole

创建一个ClusterRole,这个角色将具有只读权限。

apiVersion: /v1
kind: ClusterRole
metadata:
  name: readonly-role
rules:      #rules::定义ClusterRole的权限规则。
- apiGroups: #apiGroups: [""]:表示API组为空,表示核心API组(core API group)。
  - ""
  resources:                  #resources::定义此ClusterRole有权限访问的资源类型。
  - "configmaps"              #"configmaps":配置映射。
  - "endpoints"               #"endpoints":服务的端点。
  - "persistentvolumes"       #"persistentvolumes":持久卷。
  - "persistentvolumeclaims"  #"persistentvolumeclaims":持久卷声明
  - "pods"                    #"pods":Pod。
  -  "replicationcontrollers" #"replicationcontrollers":Replication Controller。
  -  "serviceaccounts"        #"serviceaccounts":服务帐户。
  - "services"                #"services":服务。
  - "nodes"                   #"nodes":节点。
  verbs:                      #verbs: ["get", "list", "watch"]:定义可以对上述资源进行的操作。
  - "get"                     #"get":获取资源。
  - "list"                    #"list":列出资源。
  - "watch"                   #"watch":观察资源的变化。
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:
  - "apps"          #表示API组为apps。
  resources:        #resources::定义此ClusterRole有权限访问的资源类型。
  - "deployments"   #"deployments":部署。
  - "statefulsets"  #"statefulsets":有状态集。
  - "daemonsets"    #"daemonsets":守护进程集。
  - "replicasets"   #"replicasets":副本集。
  verbs:
  - "get"           #对上面的资源进行获取
  - "list"          #列出
  - "watch"         #观察
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:
  - "batch"     #表示API组为extensions。
  resources:    #定义此ClusterRole有权限访问的资源类型。
  - "jobs"      #"jobs":作业。
  - "cronjobs"  #"cronjobs":定时作业。
  verbs:
  - "get"       #对上面的资源进行 获取
  - "list"      #列出
  - "watch"     #观察
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:
  - "extensions"    #表示API组为extensions。
  resources:        #定义此ClusterRole有权限访问的资源类型。
  - "ingresses"     #入口资源。
  verbs:
  - "get"           #对上面的资源进行 获取
  - "list"          #列出
  - "watch"         #观察
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:
  - ""   #表示API组为。
  resources:              #定义此ClusterRole有权限访问的资源类型。
  - "networkpolicies"     #网络策略。
  verbs:
  - "get"                 #对上述资源进行获取
  - "list"                #列出
  - "watch"               #观察
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:
  - ""    #表示API组为。
  resources:            #定义此ClusterRole有权限访问的资源类型。
  - "pods"              #Pod。
  verbs:
  - "get"               #对上述资源进行获取、列出和观察操作。
  - "list"
  - "watch"
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
- apiGroups:          #表示API组为。
  - ""
  resources:          #定义此ClusterRole有权限访问的资源类型。
  - "storageclasses"  #存储类。
  verbs:
  - "get"             #可以对上述资源进行获取、列出和观察操作。
  - "list"
  - "watch"
#  - "create" #创建权限
#  - "update" #修改权限
#  - "delete" #删除权限
    #这个只有  获取 列出 查看操作 要想增删改操作  加上  "create", "update", "delete"

保存上述YAML文件为readonly-clusterrole.yaml并应用:

kubectl apply -f readonly-clusterrole.yaml

4. 将ServiceAccount绑定到只读ClusterRole

创建ClusterRoleBinding,将ServiceAccount绑定到只读ClusterRole。

apiVersion: /v1
kind: ClusterRoleBinding
metadata:
  name: readonly-role-binding  #ClusterRoleBinding的名称为readonly-role-binding。
subjects:   #定义要绑定角色的对象
- kind: ServiceAccount      #对象的类型为服务帐户(ServiceAccount)。
  name: readonly-user       #服务帐户的名称为readonly-user。  #要绑定SA的名字
  namespace: kube-system    #服务帐户所在的命名空间为kube-system。
roleRef:    #定义要绑定的角色。
  kind: ClusterRole   #要绑定的角色类型为ClusterRole。  #是集群角色 还是角色 这里选的是集群角色
  name: readonly-role #要绑定集群角色的名字
  apiGroup:    #角色所属的API组为  这个是固定的

    #这个ClusterRoleBinding资源将名为readonly-role的ClusterRole绑定到命名空间kube-system中的readonly-user服务帐户上。

保存上述YAML文件为readonly-rolebinding.yaml并应用:

kubectl apply -f readonly-rolebinding.yaml

5. 生成kubeconfig文件

获取ServiceAccount的token和CA证书,并生成kubeconfig文件。

# 获取ServiceAccount的token
SECRET_NAME=$(kubectl get serviceaccount readonly-user -n kube-system -o jsonpath='{.secrets[0].name}')
#这个是readony-user 是一开始创建的SA账号  ServiceAccount

#kubectl get serviceaccount readonly-user -n kube-system -o jsonpath='{.secrets[0].name}':获取readonly-user服务帐户的第一个关联密钥的名称。
#将获取到的密钥名称存储在变量SECRET_NAME中。

TOKEN=$(kubectl get secret $SECRET_NAME -n kube-system -o jsonpath='{.data.token}' | base64 --decode)
#kubectl get secret $SECRET_NAME -n kube-system -o jsonpath='{.data.token}':获取指定密钥中的token(以Base64编码)。
# | base64 --decode:将Base64编码的token解码为原始字符串。
# TOKEN=$(...):将解码后的token存储在变量TOKEN中。

# 获取CA证书
CA_CERT=$(kubectl get secret $SECRET_NAME -n kube-system -o jsonpath='{.\.crt}')
#kubectl get secret $SECRET_NAME -n kube-system -o jsonpath='{.\.crt}':获取指定密钥中的CA证书(以Base64编码)。
#CA_CERT=$(...):将获取到的CA证书存储在变量CA_CERT中。


# 获取集群的endpoint
ENDPOINT=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
#kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}':从当前kubeconfig上下文中提取集群的服务器端点URL。
#ENDPOINT=$(...):将获取到的集群端点存储在变量ENDPOINT中。



# 生成kubeconfig文件
cat <<EOF > readonly-kubeconfig
apiVersion: v1
kind: Config
clusters: #定义集群列表。
- cluster: #定义一个集群
    certificate-authority-data: $CA_CERT 	#使用变量CA_CERT中的CA证书数据(Base64编码)。
    server: $ENDPOINT 	#使用变量ENDPOINT中的集群服务器端点URL。
  name: readonly-cluster	#集群的名称为readonly-cluster。
contexts:		#定义上下文列表。
- context:		#定义一个上下文。
    cluster: readonly-cluster	#关联到名为readonly-cluster的集群
    user: readonly-user			#关联到名为readonly-user的用户。 #这个是SA账户的名字 前面创建的
  name: readonly-context		#上下文的名称为readonly-context。
current-context: readonly-context	#设置当前使用的上下文为readonly-context。
users:	#定义用户列表
- name: readonly-user	#定义一个名为readonly-user的用户
  user:		#用户配置。
    token: $TOKEN	#使用变量TOKEN中的token。
EOF

1. 使用kubeconfig文件

将生成的readonly-kubeconfig文件复制到您希望使用的机器上。例如,您可以通过scp命令将文件从一台机器复制到另一台机器:

bash
复制代码
scp /path/to/readonly-kubeconfig user@remote-machine:/path/to/destination

2. 设置环境变量

在使用kubectl命令时,可以通过设置KUBECONFIG环境变量来指定使用这个新的kubeconfig文件:

bash
复制代码
export KUBECONFIG=/path/to/readonly-kubeconfig

3. 验证配置

确保新的kubeconfig文件配置正确并且可以访问集群。您可以运行以下命令来验证:

bash复制代码kubectl config view
kubectl get pods --all-namespaces

这些命令将使用新的kubeconfig文件来查看当前的配置并列出所有命名空间中的Pod。如果您看到预期的输出,说明配置成功。

4. 使用新的kubeconfig文件进行操作

现在,您可以使用kubectl命令进行各种只读操作,如获取资源、查看日志等。例如:

bash复制代码kubectl get nodes
kubectl get pods -n kube-system
kubectl describe pod <pod-name> -n <namespace>

这些操作都将使用新的只读权限进行,不会对集群进行修改。

5. 临时使用kubeconfig文件

如果您不想永久设置KUBECONFIG环境变量,也可以在每次运行kubectl命令时指定kubeconfig文件:

bash
复制代码
kubectl --kubeconfig=/path/to/readonly-kubeconfig get pods --all-namespaces

示例

假设您的readonly-kubeconfig文件位于/home/user/readonly-kubeconfig,您可以运行以下命令:

bash复制代码export KUBECONFIG=/home/user/readonly-kubeconfig
kubectl get pods --all-namespaces

或者临时使用:

bash
复制代码
kubectl --kubeconfig=/home/user/readonly-kubeconfig get pods --all-namespaces

通过这些步骤,您可以使用生成的只读kubeconfig文件访问Kubernetes集群,执行只读操作,而不必担心对集群的资源进行修改。

2.创建一个只有名为“jsh”名称空间怎删改查权限的kubeconfig文件

1. 创建 ServiceAccount

apiVersion: v1
kind: ServiceAccount  #称SA  类似创建一个账号  这时候账号是一个空白的啥也没有  还没有绑定权限
metadata:
  name: jsh-user	#服务帐户的名称为jsh-user。
  namespace: jsh
kubectl apply -f 1-jsh-serviceaccount.yaml

2. 创建 Role

apiVersion: /v1
kind: Role		#这是角色 他有名称空间的划分 和集群角色不一样
metadata:
  namespace: jsh
  name: jsh-role
rules:
- apiGroups: 	#资源所在的API组,这里为空字符串表示核心组。
  - ""
  resources: 	#定义该角色可以操作的资源类型。
  - "pods"
  - "services"
  - "configmaps"
  - "secrets"
  verbs: 	#定义该角色可以执行的操作。 这是全部权限 也可以用"*"表示
  - "create"
  - "delete"
  - "get"
  - "list"
  - "patch"
  - "update"
  - "watch"
- apiGroups: 
  - "apps"
  resources: 
  - "deployments"
  - "statefulsets"
  - "daemonsets"
  - "replicasets"
  verbs: 	#定义该角色可以执行的操作。
  - "create" 
  - "delete"
  - "get"
  - "list"
  - "patch"
  - "update"
  - "watch"
- apiGroups: 
  - "batch"
  resources: 
  - "jobs"
  - "cronjobs"
  verbs: 	#定义该角色可以执行的操作。
  - "create"
  - "delete"
  - "get"
  - "list"
  - "patch"
  - "update"
  - "watch"
kubectl apply -f 2-jsh-role.yaml

3. 创建 RoleBinding

apiVersion: /v1
kind: RoleBinding
metadata:
  name: jsh-rolebinding #角色绑定的名称为jsh-rolebinding
  namespace: jsh
subjects:	#定义要绑定角色的对象。
- kind: ServiceAccount  #对象的类型为服务帐户(ServiceAccount)。 SA
  name: jsh-user	#服务帐户的名称为jsh-user。  SA的名字
  namespace: jsh
roleRef:  #定义要绑定的角色。
  kind: Role	#要绑定的角色类型为Role。
  name: jsh-role	#要绑定的角色名称为jsh-role。  上面创建的role名字
  apiGroup:  #角色所属的API组为。 这个是固定的
kubectl apply -f 3-jsh-rolebinding.yaml

4. 提取 ServiceAccount 的 token 和 CA 证书

SECRET_NAME=$(kubectl get serviceaccount jsh-user -n jsh -o jsonpath='{.secrets[0].name}')

kubectl get serviceaccount jsh-user -n jsh -o jsonpath='{.secrets[0].name}':获取jsh-user服务帐户的第一个关联密钥的名称。

  • SECRET_NAME=$(...):将获取到的密钥名称存储在变量SECRET_NAME中。
TOKEN=$(kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.data.token}' | base64 --decode)

kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.data.token}':获取指定密钥中的token(以Base64编码)。

| base64 --decode:将Base64编码的token解码为原始字符串。

TOKEN=$(...):将解码后的token存储在变量TOKEN中。

CA_CERT=$(kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.\.crt}')

kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.\.crt}':获取指定密钥中的CA证书(以Base64编码)。

  • CA_CERT=$(...):将获取到的CA证书存储在变量CA_CERT中。
ENDPOINT=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')

kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}':从当前kubeconfig上下文中提取集群的服务器端点URL。

ENDPOINT=$(...):将获取到的集群端点存储在变量ENDPOINT中。

5. 生成 kubeconfig 文件

cat <<EOF > jsh-kubeconfig
apiVersion: v1
kind: Config
clusters:	#定义集群列表。
- cluster:		#定义一个集群。
    certificate-authority-data: $CA_CERT	#使用变量CA_CERT中的CA证书数据(Base64编码)。
    server: $ENDPOINT		#使用变量ENDPOINT中的集群服务器端点URL。
  name: jsh-cluster		#集群的名称为jsh-cluster。
contexts:	#定义上下文列表。
- context:	#定义一个上下文。
    cluster: jsh-cluster	#关联到名为jsh-cluster的集群。
    user: jsh-user			#关联到名为jsh-user的用户。
    namespace: jsh			#默认命名空间为jsh。
  name: jsh-context			#上下文的名称为jsh-context。
current-context: jsh-context		#设置当前使用的上下文为jsh-context。
users:		#定义用户列表。
- name: jsh-user	#定义一个名为jsh-user的用户。
  user:				#用户配置。
    token: $TOKEN	#使用变量TOKEN中的token。
EOF

给他加个名称空间test的权限

# same ServiceAccount:" test-a-user " default can contorl my own namespace:" test-a " and config later to contorl other namespace: "test-b"

apiVersion: /v1
kind: Role   #role角色
metadata:
  name: test-user-role  #起个名字  下面rolebinding要引用
  namespace: test       #加入的名称空间
rules:   #以下是权限
- apiGroups: ['', 'extensions', 'apps', '', '']
  resources: ['*']
  verbs: ['*']
- apiGroups: ['batch']
  resources:
  - jobs
  - cronjobs
  verbs: ['*']
---
#下面是将角色权限绑定  rolebinding
apiVersion: /v1
kind: RoleBinding
metadata:
  name: test-and-jsh-user  #给rolebinding起个名字
  namespace: test    #新加的名称空间的名字
roleRef:  #下面是role的信息
  apiGroup: 
  kind: Role 
  name: test-user-role  #这个是上面role的名字 需要对应好 
subjects:
- kind: ServiceAccount   #sa 账号的
  name: jsh-user     #将新建的test权限的rolebinding  加入到jsh-user sa账号里面 这样sa账号就能有这个test名称空间的权限了
  namespace: jsh

3.创建kubeconfig文件管理多个名称空间

1. 创建 ServiceAccount

先创建一个sa账号

cat 1-jsh_test-a_test-b_serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: multi-namespace-user
  namespace: jsh

2. 为每个命名空间创建 Role 和 RoleBinding

jsh 命名空间
cat 2-jsh-role-rolebinding.yaml
# role-jsh.yaml
apiVersion: /v1
kind: Role
metadata:
  name: jsh-user-full-access
  namespace: jsh
rules:
- apiGroups: ['']
  resources: ['*']
  verbs: ['*']
- apiGroups: ['extensions', 'apps', 'batch', '', '']
  resources: ['*']
  verbs: ['*']
---
apiVersion: /v1
kind: RoleBinding
metadata:
  name: jsh-user-full-access-binding
  namespace: jsh
roleRef:
  apiGroup: 
  kind: Role
  name: jsh-user-full-access
subjects:
- kind: ServiceAccount
  name: multi-namespace-user
  namespace: jsh
test-a 命名空间
cat 3-test-a-role-rolebinding.yaml
# role-test-a.yaml
apiVersion: /v1
kind: Role
metadata:
  name: test-a-user-full-access
  namespace: test-a
rules:
- apiGroups: ['']
  resources: ['*']
  verbs: ['*']
- apiGroups: ['extensions', 'apps', 'batch', '', '']
  resources: ['*']
  verbs: ['*']
---
apiVersion: /v1
kind: RoleBinding
metadata:
  name: test-a-user-full-access-binding
  namespace: test-a
roleRef:
  apiGroup: 
  kind: Role
  name: test-a-user-full-access
subjects:
- kind: ServiceAccount
  name: multi-namespace-user
  namespace: jsh
test-b 命名空间
cat 4-test-b-role-rolebinding.yaml
# role-test-b.yaml
apiVersion: /v1
kind: Role
metadata:
  name: test-b-user-full-access
  namespace: test-b
rules:
- apiGroups: ['']
  resources: ['*']
  verbs: ['*']
- apiGroups: ['extensions', 'apps', 'batch', '', '']
  resources: ['*']
  verbs: ['*']
---
apiVersion: /v1
kind: RoleBinding
metadata:
  name: test-b-user-full-access-binding
  namespace: test-b
roleRef:
  apiGroup: 
  kind: Role
  name: test-b-user-full-access
subjects:
- kind: ServiceAccount
  name: multi-namespace-user
  namespace: jsh

3. 应用以上所有 YAML 文件

kubectl apply -f 1-jsh_test-a_test-b_serviceaccount.yaml -f 2-jsh-role-rolebinding.yaml -f 3-test-a-role-rolebinding.yaml  -f 4-test-b-role-rolebinding.yaml

4. 获取 ServiceAccount 的 Token 和 CA 证书

SECRET_NAME=$(kubectl get serviceaccount multi-namespace-user -n jsh -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.data.token}' | base64 --decode)
CA_CERT=$(kubectl get secret $SECRET_NAME -n jsh -o jsonpath='{.\.crt}')
ENDPOINT=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')

5. 生成 kubeconfig 文件

cat <<EOF > multi-namespace-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: $CA_CERT
    server: $ENDPOINT
  name: multi-namespace-cluster
contexts:
- context:
    cluster: multi-namespace-cluster
    user: multi-namespace-user
    namespace: jsh
  name: jsh-context
- context:
    cluster: multi-namespace-cluster
    user: multi-namespace-user
    namespace: test-a
  name: test-a-context
- context:
    cluster: multi-namespace-cluster
    user: multi-namespace-user
    namespace: test-b
  name: test-b-context
current-context: jsh-context
users:
- name: multi-namespace-user
  user:
    token: $TOKEN
EOF
kubectl apply -f multi-namespace-kubeconfig.yaml