1. 程式人生 > >kubernetes實戰(八):k8s叢集安全機制RBAC

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
/v1betal metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # 空字串表示核心API群 resource: ["pods"] verbs: ["get", "watch", "list"]

    rules中的引數說明:

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

      resources:支援的資源物件列表,例如:pods、deployments、jobs等

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

  - 叢集角色(ClusterRole)

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

    - 叢集範圍的資源,例如Node

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

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

    下面的叢集角色可以讓使用者有權訪問任意一個或所有名稱空間的secrets:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1betal
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/v1betal
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/v1betal
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/v1betal
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/v1betal
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/v1betal
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 常用的角色繫結

  - 使用者名稱[email protected]

subjects:
- kind: User
  name: "[email protected]"
  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/v1betal
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/v1betal
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引數執行,則客戶端通過這個非安全埠進行介面呼叫,這一埠沒有認證鑑權的限制。