kubernetes 核心技术-集群安全机制 RBAC

123 阅读7分钟

在 Kubernetes 中,基于角色的访问控制(Role-Based Access Control,简称 RBAC) 是一种关键的安全机制,用于管理用户、组和服务账户对集群资源的访问权限。RBAC 通过定义角色(Role)和绑定(RoleBinding)来精细化控制谁可以执行哪些操作,从而增强集群的安全性和管理性。

什么是 RBAC

RBAC(基于角色的访问控制) 是一种授权机制,通过将权限分配给角色,再将角色赋予用户或服务账户,从而实现对 Kubernetes 集群资源的访问控制。RBAC 提供了一种灵活且可扩展的方式来管理复杂的权限需求,确保只有授权的主体能够执行特定的操作。

RBAC 的主要组件

RBAC 主要由以下四个核心组件组成:

  1. Role(角色)

    • 定义了一组权限(即可以执行的操作和可以访问的资源)。
    • 作用域可以是命名空间级别的(Role)或集群级别的(ClusterRole)。
  2. ClusterRole(集群角色)

    • 类似于 Role,但其权限适用于整个集群,而不仅限于某个命名空间。
    • 常用于定义跨命名空间的权限,例如访问节点(Node)、持久卷(PersistentVolume)等集群资源。
  3. RoleBinding(角色绑定)

    • 将 Role 绑定到特定的用户、组或服务账户。
    • 作用域为单个命名空间。
  4. ClusterRoleBinding(集群角色绑定)

    • 将 ClusterRole 绑定到集群范围内的用户、组或服务账户。
    • 作用域为整个集群。

此外,RBAC 还依赖于 Kubernetes 的认证机制,通过 Subject(主体,如用户、组、服务账户)来识别和验证请求的来源。

RBAC 的工作原理

RBAC 通过以下步骤来管理和控制访问权限:

  1. 定义角色

    • 使用 Role 或 ClusterRole 定义一组权限,明确哪些操作(如 getlistcreatedelete 等)可以在特定资源上执行。
  2. 绑定角色

    • 使用 RoleBinding 或 ClusterRoleBinding 将定义好的角色绑定到具体的用户、组或服务账户上。
  3. 权限检查

    • 当用户或服务账户发起请求时,Kubernetes API 服务器会根据 RBAC 策略检查该主体是否具备执行该操作的权限。
  4. 授权决策

    • 如果主体拥有相应的权限,操作被允许;否则,操作被拒绝。

示例:创建 Role 和 RoleBinding

以下示例展示了如何在 Kubernetes 中创建 Role 和 RoleBinding,以授予特定用户在某个命名空间内管理 Pods 的权限。

1. 创建 Role

创建一个名为 pod-manager 的 Role,允许在 default 命名空间内进行 Pods 的创建、查看和删除操作。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-manager
rules:
- apiGroups: [""] # "" 表示核心 API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list", "create", "delete"]

保存为 role-pod-manager.yaml,然后应用:

kubectl apply -f role-pod-manager.yaml

2. 创建 RoleBinding

将上述 Role 绑定到名为 alice 的用户,使其在 default 命名空间内拥有管理 Pods 的权限。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-manager-binding
  namespace: default
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-manager
  apiGroup: rbac.authorization.k8s.io

保存为 rolebinding-pod-manager.yaml,然后应用:

kubectl apply -f rolebinding-pod-manager.yaml

3. 创建 ClusterRole 和 ClusterRoleBinding

如果需要在整个集群范围内授予权限,可以使用 ClusterRole 和 ClusterRoleBinding。例如,授予 bob 用户在所有命名空间内读取 Pods 的权限。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

保存为 clusterrole-pod-reader.yaml,然后应用:

kubectl apply -f clusterrole-pod-reader.yaml

绑定 ClusterRole 到 bob 用户:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-binding
subjects:
- kind: User
  name: bob
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

保存为 clusterrolebinding-pod-reader.yaml,然后应用:

kubectl apply -f clusterrolebinding-pod-reader.yaml

使用 kubectl 管理 RBAC

Kubernetes 提供了一些 kubectl 命令,帮助用户查看和管理 RBAC 资源。

  • 查看当前用户的权限

    kubectl auth can-i <verb> <resource> --namespace=<namespace>
    

    例如,检查当前用户是否可以在 default 命名空间内创建 Pods:

    kubectl auth can-i create pods --namespace=default
    
  • 查看 Role 和 ClusterRole

    kubectl get roles --namespace=<namespace>
    kubectl get clusterroles
    
  • 查看 RoleBinding 和 ClusterRoleBinding

    kubectl get rolebindings --namespace=<namespace>
    kubectl get clusterrolebindings
    
  • 描述具体的 Role 或 ClusterRole

    kubectl describe role <role-name> --namespace=<namespace>
    kubectl describe clusterrole <clusterrole-name>
    
  • 删除 RBAC 资源

    kubectl delete role <role-name> --namespace=<namespace>
    kubectl delete clusterrole <clusterrole-name>
    kubectl delete rolebinding <rolebinding-name> --namespace=<namespace>
    kubectl delete clusterrolebinding <clusterrolebinding-name>
    

RBAC 的最佳实践

为了确保 Kubernetes 集群的安全性和管理的有效性,以下是一些 RBAC 的最佳实践:

  1. 最小权限原则

    • 只授予用户或服务账户执行其职责所需的最少权限,避免过度授权。
  2. 细粒度的角色定义

    • 根据具体需求定义细粒度的 Role 或 ClusterRole,确保权限的精准分配。
  3. 使用命名空间隔离权限

    • 利用命名空间为不同的团队或应用隔离权限,提升安全性和管理性。
  4. 定期审计和回顾权限

    • 定期检查和审查 RBAC 配置,确保权限设置符合当前的需求和安全策略。
  5. 版本控制 RBAC 配置

    • 将 RBAC 的 YAML 文件纳入版本控制系统,便于追踪和回滚配置变更。
  6. 避免使用过于宽泛的 ClusterRole

    • 尽量避免为普通用户分配具有广泛权限的 ClusterRole,如 cluster-admin,除非确有必要。
  7. 利用组进行权限管理

    • 将用户按角色或部门划分到不同的组,通过组绑定角色,简化权限管理。
  8. 使用命名约定和标签

    • 为 Role 和 RoleBinding 采用一致的命名约定和标签,便于管理和查找。

RBAC 与其他安全机制的对比

RBAC vs ABAC

ABAC(基于属性的访问控制) 是另一种授权机制,通过定义策略基于用户、资源和环境的属性来控制访问。与 RBAC 相比:

  • 灵活性:ABAC 提供了更高的灵活性,能够基于多种属性进行复杂的访问控制决策。
  • 复杂性:ABAC 的策略通常更复杂,配置和管理难度较大。
  • 使用场景:RBAC 适用于大多数常见的访问控制需求,而 ABAC 适用于需要基于多维度属性进行动态决策的复杂场景。

RBAC vs OAuth

OAuth 是一种用于授权的协议,常用于第三方应用访问用户资源。与 RBAC 相比:

  • 功能:OAuth 主要用于授权,而 RBAC 用于细化资源访问控制。
  • 集成:在 Kubernetes 中,RBAC 可以与 OAuth 等认证机制结合使用,共同提供完整的安全解决方案。

结合 Service Account 使用 RBAC

Service Account(服务账户) 是 Kubernetes 中用于进程间通信的身份标识,常用于 Pod 内的应用程序与 Kubernetes API 交互。通过 RBAC,可以为不同的 Service Account 分配不同的权限,确保应用程序只能访问其所需的资源。

示例:为 Service Account 分配权限

  1. 创建 Service Account

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: myapp-sa
      namespace: default
    

    保存为 serviceaccount.yaml,然后应用:

    kubectl apply -f serviceaccount.yaml
    
  2. 创建 ClusterRole

    假设应用程序需要读取 ConfigMap:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: configmap-reader
    rules:
    - apiGroups: [""]
      resources: ["configmaps"]
      verbs: ["get", "list", "watch"]
    

    保存为 clusterrole-configmap-reader.yaml,然后应用:

    kubectl apply -f clusterrole-configmap-reader.yaml
    
  3. 创建 ClusterRoleBinding

    将 ClusterRole 绑定到 Service Account:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: configmap-reader-binding
    subjects:
    - kind: ServiceAccount
      name: myapp-sa
      namespace: default
    roleRef:
      kind: ClusterRole
      name: configmap-reader
      apiGroup: rbac.authorization.k8s.io
    

    保存为 clusterrolebinding-configmap-reader.yaml,然后应用:

    kubectl apply -f clusterrolebinding-configmap-reader.yaml
    
  4. 在 Pod 中使用 Service Account

    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
      namespace: default
    spec:
      serviceAccountName: myapp-sa
      containers:
      - name: myapp-container
        image: myapp-image
        # 应用程序可以通过 Kubernetes API 访问 ConfigMap
    

    保存为 pod.yaml,然后应用:

    kubectl apply -f pod.yaml
    

通过上述配置,myapp-pod 中的应用程序将以 myapp-sa 服务账户的身份运行,并具备读取 ConfigMap 的权限。

总结

RBAC(基于角色的访问控制) 是 Kubernetes 中管理集群安全性的重要工具,通过定义角色和绑定关系,实现对用户、组和服务账户的精细化权限管理。正确配置和使用 RBAC,可以有效地保护集群资源,防止未授权的访问和操作,提升集群的安全性和可管理性。在实际应用中,结合其他安全机制(如认证、网络策略)和工具(如 Helm、Kustomize),可以构建更加安全和高效的 Kubernetes 集群环境。