基于RBAC使用kubeconfig文件限制不同用户操作k8s集群的权限

基于RBAC使用kubeconfig文件限制不同用户操作k8s集群的权限

Scroll Down

0、场景:

使用kubernetes的过程中,往往会有多套环境,每套环境也会有多个namespace,对应的也会有多种角色来操作集群,比如运维工程师、开发工程师、测试工程师。我司就是这样,开发人员和测试人员会登录服务器( 别问我为什么不用个kubesphere、rancher啥的 0.0 )了解自己应用的运行情况,查看对应的服务日志等等操作。

他们不太熟悉k8s操作,相比让他们不断找我,我更倾向于让他们自己解决问题。所以我写了个简单的shell把常用的k8s命令都包含进去了。

操作k8s集群肯定是需要使用kubectlapiServer进行交互的,那必然会涉及到权限问题,管理员权限自然不能给,毕竟我司开发曾经干掉过线上一整个namespace的业务pod。。。

基于以上描述和应用场景,就可以通过创建指定特定权限的kubeconfig文件,将该config文件分发给不同角色的用户完成权限限制。

个人笔记:kubernetes的安全与认证

官方文档:使用RBAC鉴权

1、原理

学艺不精,就简单介绍一下通过kubeconfig认证的原理。

Kubernetes中所有的访问,无论外部内部,都会通过API Server处理,访问Kubernetes资源前需要经过认证(Authentication)与授权(Authorization)。

Authentication:用于识别用户身份的认证,Kubernetes分外部服务帐号和内部服务帐号,采取不同的认证机制
Authorization:用于控制用户对资源访问的授权,对访问的授权目前主要使用RBAC机制

认证与ServiceAccount

Kubernetes的用户分为服务帐户(ServiceAccount)和普通帐户两种类型。

服务帐户与Namespace绑定,关联一套凭证,存储在Secret中,Pod创建时挂载Secret,从而允许与API Server之间调用。
Kubernetes中没有代表普通帐户的对象,这类帐户默认由外部服务独立管理(一般都是外部IAM),比如在华为云上CCE的用户是由IAM管理的。

如果仅使用k8s原生的rbac模块,那么就需要将Role/ClusterRole定义的资源权限通过RoleBinding/ClusterRoleBinding绑定到某个名称空间下的SA账户;

如果希望借助外部IAM模块,则可以将上述的SA账户替换成外部的IAM用户

2、操作流程

前提条件:

需要能够访问k8s集群apiserver并且对集群有admin操作权限

2.1 限制用户仅具有某个特定名称空间权限

如果你要授予linux用户名称空间级别的权限,那么流程可以是:在相应名称空间下创建一个SA->创建一个ClusterRole或者Role(相应名称空间级别资源权限)->创建一个Rolebinding绑定到该SA,这样以该sa生成的kubeconfig文件就会具有相应名称空间级别资源的权限

创建一个sa(推荐在该特定名称空间中)

创建SA后,会自动创建一个绑定的secret,在后面的kubeconfig文件中,会用到该secret中的token

apiVersion: v1
kind: ServiceAccount
metadata:
  name: develop-sa
  namespace: develop

创建一个roleclusterRole,创建roleclusterRole时,将希望授予使用者的资源和权限都放进去

下面示例创建一个Role,即授予角色develop-roledevelop namespce下对pods、configmaps、secrets、servicescore API资源的读写更新删除权限,以及授予对extensions API等资源的相应权限。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: develop-role
  namespace: develop
rules:
- apiGroups: [""]   # ""为空代表core API组
  resources: 
  - pods
  # 在这里,pods对应名称空间作用域的Pod资源,而log是pods的子资源。在RBAC
  # 在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源
  - pods/log
  - configmaps
  - secrets
  - services
  verbs: 
  - get
  - list
  - watch
  - create
  - update
  - delete
  - patch
- apiGroups:
  - extensions
  - apps
  resources:
  - deployments
  - daemonsets
  - replicationcontrollers
  - replicasets
  - statefulsets
  - horizontalpodautoscalers
  - jobs
  - applications
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - delete
  - patch

创建一个RoleBinding或者ClusterRolebinding,将saRole/ClusterRole绑定起来。绑定之后,该sa就拥有了Role/ClusterRole所对应的那些资源权限了。

ClusterRole的ClusterRolebinding所具有的权限级别是集群级别的,而Role的RoleBinding则是名称空间级别的。当然,ClusterRole的Rolebinding也是名称空间级别的,只不过你可以在多个名称空间下使用该ClusterRole,不需要重复定义新的Role了

kind: RoleBinding
# 此 RoleBinding 允许 develop-sa 读取、删除、更新 "develop"
名称空间下特定资源( develop-role所指定的名称空间和资源 )
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: develop-rolebinding
  namespace: develop
subjects:
- kind: ServiceAccount
  name: develop-sa
roleRef:
  kind: Role
  name: develop-role
  apiGroup: rbac.authorization.k8s.io

创建kubeconfig文件,模板如下:

# <> 标注的地方需要被替换
apiVersion: v1
kind: Config
users:
- name: develop
  user:
    token: <token>
clusters:
- cluster:
    certificate-authority-data: <certificate-authority-data>
    server: <api-server>
  name: develop-cluster
contexts:
- context:
    cluster: develop-cluster
    namespace: develop
    user: develop
  name: develop-cluster
current-context: develop-cluster

kubeconfig中几个参数获取的方法:

# 通过config view拿到 <certificate-authority-data> 和 <api-server> 信息
kubectl config view --flatten --minify

# 通过describe sa拿到sa 绑定的 secret 名称(输出结果的“Tokens”)
kubectl describe sa develop-sa -n develop

# 通过describe secret拿到token信息(输出结果的“token”字段)
kubectl describe secret <key> -n develop

将编辑好的kubeconfig文件加载到linux用户的.bashrc中即可

下面的某些步骤可以根据自己的实际情况选择性使用

su XXXX
mkdir -p /home/XXX/.kube/conf
sudo cp -i /etc/kubernetes/XXXXX.conf /home/XXX/.kube/conf
sudo chown -R XXX:XXX $HOME/.kube/conf/
echo "export KUBECONFIG=/home/XXX/.kube/conf/admin.conf" >> ~/.bashrc

# 配置自动补全
echo "source <(kubectl completion bash)" >> ~/.bashrc
source .bashrc
2.2 限制用户具有多名称空间资源的权限

如果你要授予linux用户集群级别多个名称空间的权限,那么流程可以是:在任意的名称空间创建一个sa -> 创建一个ClusterRole(具有相应的集群级别资源权限 -> 创建一个 ClusterRoleBinding 绑定 ClusterRole 权限给 SA,这样以该sa生成的kubeconfig文件就会具有相应集群级别资源的权限)

参考:
1、华为云CCE
2、kubernetes.io/configure-service-account
3、oracle.com/serviceaccount
4、kubernetes.io/rbac
5、ishells.cn/k8s-rbac-study