kubernetes實戰(八):k8s集群安全機制RBAC


1、基本概念

  RBAC(Role-Based Access Control,基於角色的訪問控制)在k8s v1.5中引入,在v1.6版本時升級為Beta版本,並成為kubeadm安裝方式下的默認選項,相對於其他訪問控制方式,新的RBAC具有如下優勢:

  - 對集群中的資源和非資源權限均有完整的覆蓋

    整個RBAC完全由幾個API對象完成,同其他API對象一樣,可以用kubectl或API進行操作

    可以在運行時進行調整,無需重啟API Server

  要使用RBAC授權模式,需要在API Server的啟動參數中加上--authorization-mode=RBAC

  

2、RBAC原理和用法

2.1 RBAC的API資源對象說明

  RBAC引入了4個新的頂級資源對象:Role、ClusterRole、RoleBinding、ClusterRoleBinding。同其他API資源對象一樣,用戶可以使用kubectl或者API調用等方式操作這些資源對象。

  - 角色(Role)

    一個角色就是一組權限的集合,這里的權限都是許可形式的,不存在拒絕的規則。在一個命名空間中,可以用角色來定義一個角色,如果是集群級別的,就需要使用ClusterRole了。

    角色只能對命名空間內的資源進行授權,下面的例子中定義的角色具備讀取Pod的權限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
    namespace: default
    name: pod-reader

rules:
- apiGroups: [""]  # 空字符串表示核心API群
  resource: ["pods"]
  verbs: ["get", "watch", "list"]

    rules中的參數說明:

    - apiGroup:支持的API組列表,例如:APIVersion: batch/v1、APIVersion: extensions:v1、apiVersion:apps/v1等

      resources:支持的資源對象列表,例如:pods、deployments、jobs等

      verbs:對資源對象的操作方法列表,例如:get、watch、list、delete、replace、patch等

 

  - 集群角色(ClusterRole)

    集群角色除了具有和角色一致的命名空間內資源的管理能力,因其集群級別的范圍,還可以用於以下特殊元素的授權。

    - 集群范圍的資源,例如Node

      非資源型的路徑,例如/healthz

      包含全部命名空間的資源,例如pods

    下面的集群角色可以讓用戶有權訪問任意一個或所有命名空間的secrets:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# name: secret-reader # ClusterRole不受限於命名空間,所以省略了namespace name的定義 rules:
- apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]

  - 角色綁定(RoleBinding)和集群角色綁定(ClusterRoleBinding)

    角色綁定或集群角色綁定用來把一個角色綁定到一個目標上,綁定目標可以是User、Group或者Service Account。使用RoleBinding為某個命名空間授權,ClusterRoleBinding為集群范圍內授權。

    RoleBinding可以引用Role進行授權,下例中的RoleBinding將在default命名空間中把pod-reader角色授予用戶jane,可以讓jane用戶讀取default命名空間的Pod:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default

subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

    RoleBinding也可以引用ClusterRole,對屬於同一命名空間內ClusterRole定義的資源主體進行授權。一種常見的做法是集群管理員為集群范圍預先定義好一組角色(ClusterRole),然后在多個命名空間中重復使用這些ClusterRole。

    使用RoleBinding綁定集群角色secret-reader,使dave只能讀取development命名空間中的secret:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-secrets
  namespace: development

subjects:
- kind: User
  name: dave
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

    集群角色綁定中的角色只能是集群角色,用於進行集群級別或者對所有命名空間都生效的授權。

    允許manager組的用戶讀取任意namespace中的secret

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

 

2.2 對資源的引用方式

  多數資源可以用其名稱的字符串來表達,也就是Endpoint中的URL相對路徑,例如pods。然后,某些Kubernetes API包含下級資源,例如Pod的日志(logs)。Pod日志的Endpoint是GET /api/v1/namespaces/{namespaces}/pods/{name}/log。

  Pod是一個命名空間內的資源,log就是一個下級資源。要在一個RBAC角色中體現,則需要用斜線/來分割資源和下級資源。若想授權讓某個主體同時能夠讀取Pod和Pod log,則可以配置resources為一個數組:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

  資源還可以通過名字(ResourceName)進行引用。在指定ResourceName后,使用get、delete、update、patch動詞的請求,就會被限制在這個資源實例范圍內。例如下面的聲明讓一個主體只能對一個叫my-configmap的configmap進行get和update操作:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

 

2.3 常見的角色(Role)示例

  - 允許讀取核心API組中Pod的資源:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

  - 允許讀寫"extensions"和"apps"兩個API組中的deployment資源

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

  - 允許讀寫pods及讀寫jobs

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
 
        

  - 允許讀取一個名為my-config的ConfigMap(必須綁定到一個RoleBinding來限制到一個namespace下的ConfigMap):

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

  - 讀取核心組的node資源(Node屬於集群級別的資源,必須放在ClusterRole中,並使用ClusterRoleBinding進行綁定):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

   - 允許對非資源端點/healthz及其所有子路徑進行GET/POST操作(必須使用ClusterRole和ClusterRoleBinding):

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"]
  verbs: ["get", "post"]

 

2.4 常用的角色綁定

  - 用戶名Alice@example.com

subjects:
- kind: User
  name: "Alice@example.com"
  apiGroup: rbac.authorization.k8s.io

  - 組名frontend-admins

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

  - kube-system命名空間中的默認Service Account

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

  - qa命名空間中的所有Service Account

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

  - 所有Service Account

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

  - 所有認證用戶

subjects:
- kind: Group
  name: system:authentication
  apiGroup: rbac.authorization.k8s.io

  - 所有未認證用戶

subjects:
- kind: Group
  name: system:unauthentication
  apiGroup: rbac.authorization.k8s.io

  - 全部用戶

subjects:
- kind: Group
  name: system:authentication
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthentication
  apiGroup: rbac.authorization.k8s.io

 

2.5 默認的角色和角色綁定

  API Server會創建一套默認的ClusterRole和ClusterRoleBinding對象,其中很多是以system:為前綴的,以表明這些資源屬於基礎架構,對這些對象的改動可能造成集群故障。

  所有默認的ClusterRole和RoleBinding都會用標簽kubernetes.io/bootstrapping=rbac-defaults進行標記。

  常見的系統角色如下:

  有些默認角色不是以system:為前綴的,這部分角色是針對用戶的,其中包含超級用戶角色cluster-admin,有的用於集群一級的角色cluster-status,還有針對namespace的角色admin、edit、view

  常見的用戶角色如下:

  - 核心Master組件角色

 

 2.6 授權注意事項:預防提權和授權初始化

  RBAC API拒絕用戶利用編輯角色或者角色綁定的方式進行提權。這一限制是在API層面做出的,因此即使RBAC沒有啟用也仍然有效。

  用戶只能在擁有一個角色的所有權限,且與該角色的生效范圍一致的前提下,才能對角色進行創建和更新。例如用戶user-1沒有列出集群中所有secret的權限,就不能創建具有這一權限的集群角色。要讓一個用戶能夠創建或更新角色,需要以下權限:

  - 為其授予一個允許創建/更新Role或ClusterRole資源對象的角色;

    為用戶授予角色,要覆蓋該用戶所能控制的所有權限范圍。用戶如果嘗試創建超出其自身權限的角色或者集群角色,則該API調用會被禁止。

  如果一個用戶的權限包含了一個角色的所有權限,那么就可以為其創建和更新角色綁定;或者如果被授予了針對某個角色的綁定授權,則也有權完成此操作。

  例如:user1沒有列出集群內所有secret的權限,就無法為一個具有這樣權限的角色創建集群角色綁定。要使用戶能夠創建、更新這一角色綁定,則需要有如下做法:

  - 為其授予一個允許創建和更新角色綁定或者集群角色綁定的角色

    為其授予綁定某一角色的權限,有隱式或顯式兩種方法

    - 隱式:讓其具有所有該角色的權限

    - 顯式:讓用戶授予針對該角色或集群角色綁定操作的權限

  讓user-1有對user-1-namespace命名空間中的其他用戶授予admin、edit及view角色

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles"]
  verbs: ["bind"]
  resourceNames: ["admin", "edit", "view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: user-1-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: user-1

  在進行第一個角色和角色綁定時,必須讓初始用戶具備其尚未被授予的權限,要進行初始的角色和角色綁定設置,有以下兩種方法:

  - 使用屬於system:masters組的身份,這一群組默認具有cluster-admin這一超級角色的綁定。

    如果API Server以--insecure-port參數運行,則客戶端通過這個非安全端口進行接口調用,這一端口沒有認證鑒權的限制。

 

贊助作者:

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM