- 訪問控制概述
- 用戶賬號與服務賬號
- 用戶組
- 認證
- 授權
- Service Account的管理與應用
- Service Account自動化
- 創建服務賬戶
- 呼叫imagePullSecret資源物件
- RBAC:基于角色的訪問控制
- Role和RoleBinding
- ClusterRole和ClusterRoleBinding
- 準入控制器
- LimitRanger準入控制器
- ResourceQuota資源與準入控制器
訪問控制概述
API Server作為Kubernetes集群系統的網關,是訪問及管理資源物件的唯一入口,其余所有需要訪問集群資源的組件,包括kube-controller-manager、kube-scheduler、kubelet和kube-proxy等集群基礎組件、CoreDNS等集群的附加組件以及此前使用的kubectl命令等都要經由此網關進行集群訪問和管理,
API Server會對每一次的訪問請求進行合法性檢驗,包括用戶身份鑒別、操作權限驗證以及操作是否符合全域規范的約束等,
Kubernetes以插件的方式進行對請求的認證、授權:通過認證插件來識別客戶端身份;然后通過一到多個授權插件來檢查用戶是否有權限執行其發出的資源操作請求;最后還要通過一到多個準入控制插件的遍歷檢測,例如檢查目標Namespace資源物件是否存在、是否違反系統資源限制等等,
用戶賬號與服務賬號
認證插件從客戶端請求中提取出的用戶及所屬組的資訊并不會被保存,它們僅僅用于檢驗用戶是否有權限執行其所請求的操作,客戶端訪問API服務的途徑通常有三種:kubectl、客戶端庫或者直接使用REST介面進行請求,而可以執行此類請求的主體也被Kubernetes分為兩類:
- Pod物件,對應Service Account(服務賬號),是指由Kubernetes API管理的賬號,用于為Pod之中的服務行程在訪問Kubernetes API時提供身份標識(identity),Service Account通常要系結于特定的名稱空間,它們由API Server創建,或者通過API呼叫手動創建,附帶著一組存盤為Secret的用于訪問API Server的憑據,
- 操作人員,對應User Account(用戶賬號),是指由獨立于Kubernetes之外的其他服務管理的用戶賬號,例如由管理員分發的密鑰,
用戶組
User Account用于人工操控,作用于系統全域,其名稱必須全域唯一;Service Account隸屬于名稱空間,僅用于實作某些特定的操作任務,更輕量,這兩類賬號都可以隸屬于一個或多個用戶組,用戶組只是用戶賬號的邏輯集合,它本身并沒有操作權限,但附加于組上的權限可由其內部的所有用戶繼承,以實作高效的授權管理機制,
Kubernetes內建了一些特殊用途的組:
- system:unauthenticated,未能通過任何一個授權插件檢驗的賬號,即未通過認證測驗的用戶所屬的組,?
- system:authenticated,認證成功后的用戶自動加入的一個組,用于快捷參考所有正常通過認證的用戶賬號,?
- system:serviceaccounts,當前系統上的所有ServiceAccount物件,
- system:serviceaccounts:(namespace) 特定名稱空間內所有的Service Account物件,
認證
身份驗證插件負責對API請求的認證,支持的認證方式有:客戶端證書、承載令牌(bearer tokens)、 身份驗證代理(authenticating proxy)、HTTP basic認證等,
API Server接收到訪問請求時,它將呼叫認證插件嘗試提取如下資訊:
- Username:用戶名,如kubernetes-admin等,?
- UID:用戶的數字標簽符,用于確保用戶身份的唯一性,?
- Groups:用戶所屬的組,用于權限指派和繼承,?
- Extra:鍵值資料型別的字串,用于提供認證時需要用到的額外資訊,
API Server支持同時啟用多種認證機制,但至少應該分別為ServiceAccount和User Account各自啟用一個認證插件,同時啟用多種認證機制時,認證程序會以串行的方式進行,直到一種認證機制成功完成即結束,
授權
成功通過身份認證后的操作請求還需要轉交給授權插件進行許可權限檢查,以確保其擁有執行相應的操作的許可,主要支持使用四類內建的授權插件:
- Node:基于Pod資源的目標調度節點來實作的對kubelet的訪問控制,?
- ABAC:attribute-based access control,基于屬性的訪問控制,?
- RBAC:role-based access control,基于角色的訪問控制,?
- Webhook:基于HTTP回呼機制通過外部REST服務檢查確認用戶授權的訪問控制,
此外還有AlwaysDeny和AlwaysAllow兩個特殊的授權插件,其中AlwaysDeny僅用于測驗,而AlwaysAllow則用于關閉授權檢查,
Service Account的管理與應用
API Server是訪問及管理資源物件的唯一入口,它會對每一次訪問請求進行合法性檢驗,每個Pod物件都會對應一個Service Account,若創建Pod資源時未予以明確指定,則名為ServiceAccount的準入控制器會為其自動附加當前名稱空間中默認的服務賬戶,其名稱通常為default:
? kubectl describe serviceaccount default
Namespace: default
...
Mountable secrets: default-token-m6bz5
Tokens: default-token-m6bz5
Pod通過存盤卷掛載的方式使用這些資訊,位置在/var/run/secrets/kubernetes.io/serviceaccount
? kubectl describe pod configmap-vol
...
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-m6bz5 (ro)
...
Volumes:
default-token-m6bz5:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-m6bz5
Optional: false
掛載點目錄中存在三個檔案:ca.crt、namespace和token,其中,token檔案保存了Service Account的認證token,容器中的行程使用它向API Server發起連接請求,進而由認證插件完成用戶認證并將其用戶名傳遞給授權插件,
Service Account自動化
Kubernetes系統通過三個獨立的組件間的相互協作來實作服務賬戶的自動化,三個組件具體為:Service Account準入控制器、令牌控制器(token controller)和Service Account賬戶控制器,
ServiceAccount賬戶控制器負責為名稱空間管理相應的資源,并確保每個名稱空間中都存在一個名為“default”的Service Account物件,
ServiceAccount準入控制器是API Server的一部分,負責在創建或更新Pod時對其按需進行Service Account物件相關資訊的修改,包括如下操作:
- 若Pod沒有明確定義使用的ServiceAccount物件,則將其設定為“default”
- 確保Pod明確參考的ServiceAccount已存在,否則請求將被拒絕
- 若Pod物件中不包含ImagePullSecerts,則把ServiceAccount的ImagePullSecrets添加于其上
- 為帶有訪問API的令牌的Pod添加一個存盤卷
- 為Pod物件中的每個容器添加一個volumeMounts,掛載至/var/run/secrets/kubernetes.io/serviceaccount
令牌控制器是controller-manager的子組件,作業于異步模式,其負責的任務有:?
- 監控Service Account的創建操作,并為其添加用于訪問API的Secret物件
- 監控Service Account的洗掉操作,并洗掉其相關的所有Service Account令牌密鑰
- 監控Secret物件的添加操作,確保其參考的Service Account已存在,并在必要時為Secret物件添加認證令牌
- 監控Secret物件的洗掉操作,以確保洗掉每個ServiceAccount中對此Secret的參考,
創建服務賬戶
Service Account是Kubernetes API上的一種資源型別,它隸屬于名稱空間,每個名稱空間都有一個名為default的默認資源物件,可通過kubectl get serviceaccounts --all-namespaces查看,
每個Pod物件只能附加其所屬名稱空間中的一個Service Account資源,但一個Service Account資源可由多個Pod物件共享使用,創建Pod資源時,可使用“spec.serviceAccountName”屬性直接指定要使用的Service Account物件,如果省略則使用默認資源物件,
下面的配置清單創建名為sa-demo的服務賬戶,其余的資訊則交由系統自動生成,包括認證令牌的Secret物件:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-demo
呼叫imagePullSecret資源物件
ServiceAccount資源還可以基于spec.imagePullSecret欄位附帶一組docker-registry資源串列,用于在進行容器創建時,從某私有鏡像倉庫下載鏡像檔案之前進行服務認證,比如下面的清單指定了在Kubernetes筆記(8) - ConfigMap和Secret中創建的local-registry:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-demo
imagePullSecrets:
- name: local-registry
RBAC:基于角色的訪問控制
在RBAC訪問控制機制中,User是一個可以獨立訪問計算機系統中的資料或者用資料表示的其他資源的主體;Role是指一個組織或任務中的作業或者位置,它代表了一種權利、資格和責任;Permission是允許執行的操作,
K8s使用的RBAC授權插件支持Role和ClusterRole兩類角色,其中Role作用于名稱空間級別,用于定義名稱空間內的資源權限集合,而ClusterRole則用于組織集群級別的資源權限集合,它們都是標準的API資源型別,
Role和RoleBinding
Role僅是一組許可(permission)權限的集合,它描述了對哪些資源可執行何種操作,資源配置清單中使用rules欄位嵌套授權規則,下面的Role物件的配置清單示例,設定了讀取、列出及監視Pod物件的權限:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pods-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
沒有指定namespace,默認創建到了default下,role需要“系結”(Role-Binding)到主體(如user、group或service account)之上才能發生作用,
RoleBinding用于將Role中定義的權限賦予一個或一組用戶,它由一組主體,以及一個要參考來賦予這組主體的Role或ClusterRole組成,比如下面的RoleBinding配置清單將pods-reader角色賦給了用戶kube-user1,于是kube-user1就有了對應的權限:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: role-binding-1
subjects:
- kind: User
name: kube-user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
ClusterRole和ClusterRoleBinding
ClusterRole的許可授權作用于整個集群,因此常用于控制Role無法生效的資源型別,這包括集群級別的資源(如Nodes)、非資源型別的端點(如/healthz)和作用于所有名稱空間的資源(例如,跨名稱空間獲取任何資源的權限),
集群級別的角色資源ClusterRole資源除了能夠管理與Role資源一樣的許可權限之外,還可以用于集群級組件的授權,配置方式及其在rules欄位中可內嵌的欄位也與Role資源類似,kind為ClusterRole,
對于namespace級別的資源的訪問控制來說,RoleBinding也能夠將主體系結至ClusterRole資源之上,但僅能賦予用戶訪問Role-Binding資源本身所在的名稱空間之內可由ClusterRole賦予的權限,若借助ClusterRoleBinding進行系結,則用戶就具有了所有相關名稱空間中的資源的訪問權限,
但對于非namespace級別的資源,如nodes、persistentvolumes等資源,以及非資源型的URL(/api、/apis、/healthz、/swaggerapi和/version),則無法通過RoleBinding系結來授權給用戶,它們也只能定義在ClusterRole中,且需要基于ClusterRoleBinding進行授權,不過,對此類資源的讀取權限已經由系統默認的名稱同為system:discovery的ClusterRole和ClusterRoleBinding兩個資源自動設定,
執行kubectl get clusterrole system:discovery -o yaml可以查看:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:discovery
...
rules:
- nonResourceURLs:
- /api
- /api/*
- /apis
- /apis/*
- /healthz
- /livez
- /openapi
- /openapi/*
- /readyz
- /version
- /version/
verbs:
- get
準入控制器
在完成身份認證和權限檢查之后,將由準入控制器進一步驗證,比如執行物件的語意驗證、設定缺失欄位的默認值、限制所有容器使用的鏡像檔案必須來自某個特定的Registry、檢查Pod物件的資源需求是否超出了指定的限制范圍等,
準入控制器分為Mutating-AdmissionWebhook和ValidatingAdmissionWebhook兩種型別,分別用于在API中執行物件配置的“變異”和“驗證”操作,變異控制器可以修改他們許可的物件,而驗證控制器則一般不會,在具體的代碼實作上,一個準入控制器可以兼具驗證、變異兩項功能,
在運行時準入控制可分為兩個階段,第一個階段串行運行各變異型控制器,第二個階段串行運行各驗證型控制器,一旦任一階段中的任何控制器拒絕請求,則立即拒絕整個請求,并向用戶回傳錯誤提示,
LimitRanger準入控制器
對于沒有指定資源需求及資源限制的容器來說,其應用有因故障吞掉所在作業節點上的所有可用計算資源的風險,使用LimitRange資源可以為某個名稱空間中的每個容器指定計算資源用量,或者設定默認的計算資源需求和計算資源限制,定義了LimitRange物件后,客戶端提交創建或修改的資源物件將受到LimitRanger控制器的檢查,
LimitRange資源支持限制容器、Pod和PersistentVolumeClaim三種資源物件的系統資源用量,其中Pod和容器主要用于定義可用的CPU和記憶體資源范圍,而PersistentVolume-Claim則主要定義存盤空間的限制范圍,
下面的配置清單在default空間中定義了容器的資源限制:
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limit-range
spec:
limits:
- default:
cpu: 1
defaultRequest:
cpu: 1
max:
cpu: 2000m
maxLimitRequestRatio:
cpu: 4
type: Container
在創建Pod物件時,如果沒有指定資源限制,則LimitRange資源會自動為其設定,而且如果Request超出max的限制后會被block,
ResourceQuota資源與準入控制器
盡管LimitRange資源能限制單個容器、Pod及PVC等相關計算資源或存盤資源的用量,但多個物件占用資源的總和仍然可能超出系統的限制,ResourceQuota資源用于定義名稱空間的物件數量或系統資源配額,它支持限制每種資源型別的物件總數,以及所有物件所能消耗的計算資源及存盤資源總量等,一個命名空間可以創建一個ResourceQuota物件,
ResourceQuota物件可限制指定名稱空間中非終止狀態的所有Pod物件的計算資源需求及計算資源限制總量,比如
- requests.cpu:CPU資源需求的總量限額
- requests.cpu:記憶體資源需求的總量限額,?
- limits.cpu:CPU資源限制的總量限額,?
- limits.memory:記憶體資源限制的總量限額,
還可以限制特定名稱空間中可以使用的PVC數量和這些PVC資源的空間大小總量,一部分舉例:
- persistentvolumeclaims:可以創建的PVC總數
- requests.storage:所有PVC存盤需求的總量限額
在1.9版本起支持以count/<resource>.<group>的格式對所有資源型別物件的計數配額,如count/deployments.apps count/services等,
apiVersion: v1
kind: ResourceQuota
metadata:
name: resource-quota-1
spec:
hard:
pods: 2
requests.cpu: 500m
requests.memory: 1Gi
limits.cpu: 2
limits.memory: 2Gi
count/deployments.apps: 1
persistentvolumeclaims: 2
apply上述資源清單后執行kubectl describe quota resource-quota-1:
Name: resource-quota-1
Namespace: default
Resource Used Hard
-------- ---- ----
count/deployments.apps 0 1
limits.cpu 0 2
limits.memory 0 2Gi
persistentvolumeclaims 1 2
pods 4 2
requests.cpu 0 500m
requests.memory 0 1Gi
從列印結果可以看出在創建ResourceQuota前pod數量為4個,所以創建ResourceQuota后就無法添加新的pod了,
此外一旦啟用了計算資源需求和計算資源限制配額,那么創建的任何Pod物件都必須設定此兩類屬性,否則會被block,
學習資料
《Kubernetes實戰進階》 馬永亮著
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/288157.html
標籤:其他
上一篇:Centos7安裝Jenkins
