k8s (十七) --- kubernetes訪問控制

一、kubernetes訪問控制原理

在這裏插入圖片描述在這裏插入圖片描述

Authentication(認證)

認證方式現共有8種,可以啓用一種或多種認證方式,只要有一種認證方式通過,就不再進行其它方式的認證。通常啓用X509 Client Certs和Service Accout Tokens兩種認證方式。

Kubernetes集羣有兩類用戶:由Kubernetes管理的Service Accounts (服務賬戶)和(Users Accounts) 普通賬戶。k8s中賬號的概念不是我們理解的賬號,它並不真的存在,它只是形式上存在。

Authorization(授權)

必須經過認證階段,纔到授權請求,根據所有授權策略匹配請求資源屬性,決定允許或拒絕請求。授權方式現共有6種,AlwaysDeny、AlwaysAllow、ABAC、RBAC、Webhook、Node。默認集羣強制開啓RBAC。

Admission Control(准入控制)

用於攔截請求的一種方式,運行在認證、授權之後,是權限認證鏈上的最後一環,對請求API資源對象進行修改和校驗。

注意:以上三個流程必須按照流程走,即先認證,再授權,最後准入控制。

訪問k8s的API Server的客戶端主要分爲兩類:

  • kubectl :用戶家目錄中的 .kube/config 裏面保存了客戶端訪問API Server的密鑰相關信息,這樣當用kubectl訪問k8s時,它就會自動讀取該配置文件,向API Server發起認證,然後完成操作請求。
  • pod:Pod中的進程需要訪問API Server,如果是人去訪問或編寫的腳本去訪問,這類訪問使用的賬號爲:UserAccount;而Pod自身去連接API Server時,使用的賬號是:ServiceAccount,生產中後者使用居多。

kubectl 向apiserver發起的命令,採用的是http方式,其實就是對URL發起增刪改查的操作。

$ kubectl  proxy --port=8888 &
$ curl http://localhost:8888/api/v1/namespaces/default
$ curl http://localhost:8888/apis/apps/v1/namespaces/default/deployments

以上兩種api的區別是:

  • api它是一個特殊鏈接,只有在核心v1羣組中的對象才能使用。
  • apis 它是一般API訪問的入口固定格式名。

UserAccount與serviceaccount:

用戶賬戶是針對人而言的。 服務賬戶是針對運行在 pod 中的進程而言的。

用戶賬戶是全局性的。 其名稱在集羣各 namespace 中都是全局唯一的,未來的用戶資源不會做 namespace 隔離, 服務賬戶是 namespace 隔離的。

通常情況下,集羣的用戶賬戶可能會從企業數據庫進行同步,其創建需要特殊權限,並且涉及到複雜的業務流程。 服務賬戶創建的目的是爲了更輕量,允許集羣用戶爲了具體的任務創建服務賬戶 ( 即權限最小化原則 )。

二、認證示例

serviceaccount示例

創建serviceaccount:

$ kubectl create serviceaccount admin
serviceaccount/admin created

此時k8s爲用戶自動生成認證信息,但沒有授權

$ kubectl describe sa admin             
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-6xfpp
Tokens:              admin-token-6xfpp
Events:              <none>

添加secrets到serviceaccount中:

$ kubectl patch serviceaccount admin -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'

把serviceaccount和pod綁定起來:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
   labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: reg.westos.org/cl/nginx			#私有倉庫
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin

將認證信息添加到serviceAccount中,要比直接在Pod指定imagePullSecrets要安全很多。

UserAccount示例

創建UserAccount:

# cd /etc/kubernetes/pki/
# openssl genrsa -out test.key 2048		#輸出2048位加密的key
# openssl req -new -key test.key -out test.csr -subj "/CN=test"		#製作名爲test.csr的證書請求
# openssl  x509 -req -in test.csr -CA ca.crt -CAkey ca.key  -CAcreateserial -out test.crt -days 365			#申請證書
# openssl x509 -in test.crt -text -noout		#查看證書

使用創建的證書:

$ kubectl config set-credentials test --client-certificate=/etc/kubernetes/pki/test.crt --client-key=/etc/kubernetes		/pki/test.key --embed-certs=true	#注入證書
$ kubectl  config view			#查看配置
$ kubectl config set-context test@kubernetes --cluster=kubernetes --user=test			#將用戶test添加到context中
$ kubectl config use-context test@kubernetes		#切換用戶

切換用戶後查看pod:

$ $ kubectl  get pod
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"

此時用戶通過認證,但還沒有權限操作集羣資源,需要繼續添加授權。

注意授權時需要切換成 kubernetes-admin用戶。

三、RBAC 授權

RBAC(Role Based Access Control):基於角色訪問控制授權。

  • 允許管理員通過Kubernetes API動態配置授權策略。RBAC就是用戶通過角色與權限進行關聯。
  • RBAC只有授權,沒有拒絕授權,所以只需要定義允許該用戶做什麼即可。
  • RBAC包括四種類型:Role、ClusterRole、RoleBinding、ClusterRoleBinding 即角色、角色綁定、集羣角色、集羣角色綁定。
    在這裏插入圖片描述RBAC的三個基本概念:
  • Subject:被作用者,它表示k8s中的三類主體, user, group, serviceAccount
  • Role:角色,它其實是一組規則,定義了一組對 Kubernetes API 對象的操作權限。
  • RoleBinding:定義了“被作用者”和“角色”的綁定關係。

Role 和 ClusterRole

  • Role是一系列的權限的集合,Role只能授予單個namespace 中資源的訪問權限。
  • ClusterRole 跟 Role 類似,但是可以在集羣中全局使用。

RoleBinding和ClusterRoleBinding

  • RoleBinding是將Role中定義的權限授予給用戶或用戶組。它包含一個subjects列表(users,groups,service accounts),並引用該Role。
  • RoleBinding是對某個namespace 內授權,ClusterRoleBinding適用在集羣範圍內使用。

四、RBAC示例

以下這些示例需要注意的是:在執行部署文件時需要切換成管理員,即kubernetes-admin。

Role示例

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: myrole
rules:
- apiGroups: [""] 
  resources: ["pods"]
  verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]

上述部署文件定義可以個名爲myrole的角色,該角色具有對pod一系列操作[“get”, “watch”, “list”, “create”, “update”, “patch”, “delete”]
的權限,並且這個角色是針對默認的namespace。

可以使用 kubectl get role 查看創建的role。

RoleBinding示例

RoleBinding示例:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-read-pods
  namespace: default
subjects:
- kind: User
  name: test
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: myrole
  apiGroup: rbac.authorization.k8s.io

上述部署文件定義了一個名爲test-read-pods的RoleBinding,表示將 用戶test和角色 myrole進行綁定,使test用戶具有角色myrole所擁有的權限。
運行部署文件後切換成test用戶即可查看pod,但是也僅是默認命名空間下的pod,並不能操作svc 或者其他namespace中的pod,這些權限均是在角色中定義好的。

ClusterRole示例

集羣角色示例:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: myclusterrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list", "delete", "create", "update"]
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

該部署文件表示定義一個名爲myclusterrole的集羣角色,並且該即集羣角色對pods和deployments有一系列的權限。

使用角色綁定綁定集羣角色

使用rolebinding綁定clusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rolebind-myclusterrole
  namespace:  default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: test

該部署文件表示使用角色綁定將用戶test與集羣角色myclusterrole進行綁定,使用戶test擁有集羣角色myclusterrole所擁有的權限。

注意該方法需要指定namespace。

運行該文件後test用戶可以對pods和deployments有一系列的操作,但是沒有svc和其他命名空間pod的權限。

clusterrolebinding示例

創建clusterrolebinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterrolebinding-myclusterrole
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: test

該部署文件表示使用集羣角色綁定將用戶test與集羣角色綁定,使用戶test在所有命名空間namespace中擁有對pods和deployments的一系列權限,這些權限在集羣角色的部署文件中定義。

六、服務賬戶的自動化

服務賬戶准入控制器(Service account admission controller)

  • 如果該 pod 沒有 ServiceAccount 設置,將其 ServiceAccount 設爲 default。
  • 保證 pod 所關聯的 ServiceAccount 存在,否則拒絕該 pod。
  • 如果 pod 不包含 ImagePullSecrets 設置,那麼 將 ServiceAccount 中的 ImagePullSecrets 信息添加到 pod 中。
  • 將一個包含用於 API 訪問的 token 的 volume 添加到 pod 中。
  • 將掛載於 /var/run/secrets/kubernetes.io/serviceaccount 的 volumeSource 添加到 pod 下的每個容器中。

Token 控制器(Token controller)

  • 檢測服務賬戶的創建,並且創建相應的 Secret 以支持 API 訪問。

  • 檢測服務賬戶的刪除,並且刪除所有相應的服務賬戶 Token Secret。

  • 檢測 Secret 的增加,保證相應的服務賬戶存在,如有需要,爲 Secret 增加 token。

  • 檢測 Secret 的刪除,如有需要,從相應的服務賬戶中移除引用。

服務賬戶控制器(Service account controller)

  • 服務賬戶管理器管理各命名空間下的服務賬戶,並且保證每個活躍的命名空間下存在一個名爲 “default” 的服務賬戶

Kubernetes 還擁有“用戶組”(Group)的概念:
ServiceAccount對應內置“用戶”的名字是:

system:serviceaccount:<ServiceAccount名字 >

而用戶組所對應的內置名字是:

system:serviceaccounts:<Namespace名字 >

示例1:表示mynamespace中的所有ServiceAccount

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

示例2:表示整個系統中的所有ServiceAccount

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

ubernetes 還提供了四個預先定義好的 ClusterRole 來供用戶直接使用:

  • cluster-amdin 權限最大
  • admin
  • edit
  • view 權限最小

示例:(最佳實踐)

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: readonly-default
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

上述部署文件表示將默認namespace下的默認ServiceAccount與內置的集羣角色view綁定,使這個ServiceAccount擁有查看集羣的權力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章