kubernetes(k8s) 學習 (十三) k8s的訪問控制(認證+授權+准入控制)

訪問控制的簡介

API Server——Kubernetes網關

API爲Kubernetes各類資源對象(如節點、標籤、Pod、服務、部署、secrets、configmaps以及ingress等)提供訪問接口。這些資源對象通過簡單的REST API執行基本的CRUD(增刪改查)操作。

Kubernetes的核心構建塊之一是API Server,它作爲Kubernetes的網關,是訪問和管理資源對象的唯一入口。內部組件(如kubelet、調度程序和控制器)通過API Server訪問API以進行編排和協調。分佈式鍵/值數據庫、etcd只能通過API Server訪問。

客戶端的認證操作是由api server配置的一到多個認證插件完成,授權操作由一到多個授權插件進行,而通過授權檢測的用戶所請求的相關操作還要經由一到多個准入控制插件的遍歷檢測

在這裏插入圖片描述

在這裏插入圖片描述通常我們可以通過命令行工具kubectl來與API Server進行交互。從kubectl發送的任何內容最終都會被API Server所接收。因此,多個工具和插件會直接或間接地使用相同的API。

即使在Kubernetes集羣中訪問或者操作對象之前,該請求也需要由API Server進行身份驗證。REST路徑使用基於X.509證書的TLS協議來保護和加密流量。Kubectl在編碼和發送請求之前查找文件〜/ .kube / config以檢索CA證書和客戶端證書。

k8s訪問控制
在這裏插入圖片描述

訪問控制三部曲

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訪問的入口固定格式名。

1.在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述2.在這裏插入圖片描述3.在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

創建serviceaccount

UserAccount與serviceaccount

用戶賬戶是針對人而言的。
服務賬戶是針對運行在 pod 中的進程而言的。
用戶賬戶是全局性的。 其名稱在集羣各 namespace 中都是全局唯一的,
未來的用戶資源不會做 namespace 隔離, 服務賬戶是 namespace 隔離的。

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

創建serviceaccount:
$ kubectl create serviceaccount admin
serviceaccount/admin created
  
$ kubectl describe sa admin             //此時k8s爲用戶自動生成認證信息,但沒有授權
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-6xfpp
Tokens:              admin-token-6xfpp
Events:              <none>

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

添加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/westos/game2048
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin

在這裏插入圖片描述在這裏插入圖片描述
注意:將認證信息添加到serviceAccount中,要比直接在Pod指定imagePullSecrets要安全很多。

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

創建UserAccount

認證的實現

# cd /etc/kubernetes/pki/
# openssl genrsa -out test.key 2048
# openssl req -new -key test.key -out test.csr -subj "/CN=test"
# 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
$ kubectl config use-context test@kubernetes`在這裏插入代碼片`

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

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

創建用戶並進行認證:創建用戶時需要在root用戶下進行

1.在這裏插入圖片描述在這裏插入圖片描述2.在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述3.切換至kubeadm用戶
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述發現沒有權限,顯示的是權限禁止

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

RBAC 授權的實現

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

允許管理員通過Kubernetes API動態配置授權策略。
RBAC就是用戶通過角色與權限進行關聯。
RBAC只有授權,沒有拒絕授權,所以只需要定義允許該用戶做什麼即可。

RBAC包括四種類型:Role、ClusterRole、RoleBinding、ClusterRoleBinding。

需要理解 RBAC 一些基礎的概念和思路,RBAC 是讓用戶能夠訪問 Kubernetes API 資源的授權方式
在這裏插入圖片描述

在 RBAC 中定義了兩個對象,用於描述在用戶和資源之間的連接權限。
角色

角色是一系列的權限的集合,例如一個角色可以包含讀取 Pod 的權限和列出 Pod 的權限, ClusterRole 跟 Role 類似,但是可以在集羣中到處使用( Role 是 namespace 一級的)。
角色綁定

RoleBinding 把角色映射到用戶,從而讓這些用戶繼承角色在 namespace 中的權限。ClusterRoleBinding 讓用戶繼承 ClusterRole 在整個集羣中的權限。

在這裏插入圖片描述
在這裏插入圖片描述
RBAC的三個基本概念:

Subject:被作用者,它表示k8s中的三類主體, user, group, serviceAccount
Role:角色,它其實是一組規則,定義了一組對 Kubernetes API 對象的操作權限。
RoleBinding:定義了“被作用者”和“角色”的綁定關係。

Role 和 ClusterRole

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

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"]

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

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

1.創建角色
在這裏插入圖片描述在這裏插入圖片描述2.將角色綁定給test用戶
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述3.再次切換至test
在這裏插入圖片描述在這裏插入圖片描述

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"]

使用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

創建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

1.在這裏插入圖片描述2.解決的問題:
在這裏插入圖片描述3.創建集羣角色
在這裏插入圖片描述在這裏插入圖片描述4。創建集羣角色綁定
在這裏插入圖片描述在這裏插入圖片描述當切換至test用戶時
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

服務賬戶的自動化

服務賬戶准入控制器(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

Kubernetes 還提供了四個預先定義好的 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章