【Kubernetes】k8s集群安全機制
機制說明
Kubernetes 作為一個分布式集群的管理工具,保證集群的安全性是其一個重要的任務。API Server 是集群內部各個組件通信的中介, 也是外部控制的入口。所以 Kubernetes 的安全機制基本就是圍繞保護 API Server 來設計的。
比如 kubectl 如果想向 API Server 請求資源,需要過三關,第一關是認證(Authentication),第二關是鑒權(Authorization), 第三關是準入控制(Admission Control),只有通過這三關才可能會被 K8S 創建資源。
一、認證(Authentication)
1.k8s集群內的三種認證方式
●HTTP Token 認證:通過一個 Token 來識別合法用戶
HTTP Token 的認證是用一個很長的特殊編碼方式的并且難以被模仿的 Token 字符串來表達客戶的一種方式。Token 是一個很長的很復雜的字符串,每一個 Token 對應一個用戶名存儲在 API Server 能訪問的文件中。當客戶端發起 API 調用請求時,需要在 HTTP Header 里放入 Token。
●HTTP Base 認證:通過用戶名+密碼的方式認證
用戶名:密碼 用 BASE64 算法進行編碼后的字符串放在 HTTP Request 中的 Heather Authorization 域里發送給服務端, 服務端收到后進行解碼,獲取用戶名及密碼。
●HTTPS 證書認證(最嚴格):基于 CA 根證書簽名的客戶端身份認證方式。
注意:Token 認證和 Base 認證方式只能進行服務端對客戶端的單向認證,而客戶端不知道服務端是否合法;而 HTTPS 證書認證方式 則可以實現雙向認證。
2.k8s集群內的認證說明
1)需要被認證的訪問類型:
●Kubernetes 組件對 API Server 的訪問:kubectl、kubelet、kube-proxy
●Kubernetes 管理的 Pod 對 API Server 的訪問:Pod(coredns,dashborad 也是以 Pod 形式運行)
2)安全性說明:
●Controller Manager、Scheduler 與 API Server 在同一臺機器,所以直接使用 API Server 的非安全端口訪問(比如 8080 端口)
●kubectl、kubelet、kube-proxy 訪問 API Server 就都需要證書進行 HTTPS 雙向認證,端口號使用 6443
3)證書頒發:
●手動簽發:使用二進制部署時,需要先手動跟 CA 進行簽發 HTTPS 證書
●自動簽發:kubelet 首次訪問 API Server 時,使用 token 做認證,通過后,Controller Manager 會為 kubelet 生成一個證書, 以后的訪問都是用證書做認證了
4)kubeconfig
kubeconfig 文件包含集群參數(CA 證書、API Server 地址),客戶端參數(上面生成的證書和私鑰),集群 context 上下文參數 (集群名稱、用戶名)。Kubenetes 組件(如 kubelet、kube-proxy)通過啟動時指定不同的 kubeconfig 文件可以切換到不同的集群 ,連接到 apiserver。
也就是說 kubeconfig 文件既是一個集群的描述,也是集群認證信息的填充。包含了集群的訪問方式和認證信息。kubectl 文件默認位于 ~/.kube/config
5)Service Account
Service Account是為了方便 Pod 中的容器訪問API Server。因為 Pod 的創建、銷毀是動態的,所以要為每一個 Pod 手動生成證書就不可行了。 Kubenetes 使用了 Service Account 來循環認證,從而解決了 Pod 訪問API Server的認證問題。
6)Secret 與 SA 的關系
//Kubernetes 設計了一種資源對象叫做 Secret,分為兩類:
●用于保存 ServiceAccount 的 service-account-token
●用于保存用戶自定義保密信息的 Opaque
3.Service Account 包含三個部分
●Token:是使用 API Server 私鑰簽名的 Token 字符串序列號,用于訪問 API Server 時,Server 端認證
●ca.crt:ca 根證書,用于 Client 端驗證 API Server 發送來的證書
●namespace:標識這個 service-account-token 的作用域名空間
注意:默認情況下,每個 namespace 都會有一個 Service Account,如果 Pod 在創建時沒有指定 Service Account,就會使用 Pod 所屬的 namespace 的 Service Account。每個 Pod 在創建后都會自動設置 spec.serviceAccount 為 default(除非指定了其他 Service Accout)。
二、 鑒權(Authorization)
1.鑒權的方式
之前的認證(Authentication)過程,只是確定通信的雙方都確認了對方是可信的,可以相互通信。而鑒權是確定請求方有哪些資源的權限。API Server 目前支持以下幾種授權策略:(通過 API Server 的啟動參數 “--authorization-mode” 設置)
●AlwaysDeny:表示拒絕所有的請求,一般用于測試
●AlwaysAllow:允許接收所有請求,如果集群不需要授權流程,則可以采用該策略,一般用于測試
●ABAC(Attribute-Based Access Control):基于屬性的訪問控制,表示使用用戶配置的授權規則對用戶請求進行匹配和控制。也就是說定義一個訪問類型的屬性,用戶可以使用這個屬性訪問對應的資源。此方式設置較為繁瑣,每次設置需要定義一長串的屬性才可以。
●Webhook:通過調用外部 REST 服務對用戶進行授權,即可在集群外部對K8S進行鑒權
●RBAC(Role-Based Access Control):基于角色的訪問控制,K8S自1.6版本起默認使用規則
2.RBAC 相對其它訪問控制方式的優勢:
●對集群中的資源(Pod,Deployment,Service)和非資源(元信息或者資源狀態)均擁有完整的覆蓋
●整個 RBAC 完全由幾個 API 資源對象完成,同其它 API 資源對象一樣,可以用 kubectl 或 API 進行操作
●可以在運行時進行調整,無需重啟 API Server,而 ABAC 則需要重啟 API Server
3.RBAC 的 API 資源對象說明
RBAC 引入了 4 個新的頂級資源對象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,4 種對象類型均可以通過 kubectl 與 API Server 操作。
官方文檔:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
4.RBAC的角色與角色綁定
//角色
Role:授權指定命名空間的資源控制權限
ClusterRole:可以授權所有命名空間的資源控制權限
#如果使用 RoleBinding 綁定 ClusterRole,仍會受到命名空間的影響;如果使用 ClusterRoleBinding 綁定 ClusterRole, 將會作用于整個 K8S 集群。
//角色綁定
RoleBinding:將角色綁定到主體(即subject)
ClusterRoleBinding:將集群角色綁定到主體
//主體(subject)
User:用戶
Group:用戶組
ServiceAccount:服務賬號
#User 使用字符串表示,它的前綴 system: 是系統保留的,集群管理員應該確保普通用戶不會使用這個前綴格式;Group 書寫格式與 User 相同,同樣 system: 前綴也為系統保留。
#Pod使用 ServiceAccount 認證時,service-account-token 中的 token(JWT) 會保存用戶信息。 有了用戶信息,再創建一對角色/角色綁定(集群角色/集群角色綁定)資源對象,就可以完成權限綁定了。
5.Role and ClusterRole
在 RBAC API 中,Role 表示一組規則權限,權限只能增加(累加權限),不存在一個資源一開始就有很多權限而通過 RBAC 對其進行減少的操作。也就是說只有白名單權限,而沒有黑名單權限的概念。
Role 只能定義在一個 namespace 中,如果想要跨 namespace 則可以創建 ClusterRole,也就是說定義 ClusterRole 不需要綁定 namespace。
1)Role的字段定義
apiVersion: rbac.authorization.k8s.io/v1 #指定 core API 組和版本 kind: Role #指定類型為 Role metadata: namespace: default #使用默認命名空間 name: pod-reader #Role 的名稱 rules: #定義規則 - apiGroups: [""] #標明 core API 組 resources: ["pods"] #資源對象為 Pod 類型 verbs: ["get","watch","list"] #被授予的操作權限
注意:以上配置的意義是,如果把 pod-reader 這個 Role 賦予給一個用戶,那么這個用戶將在 default 命名空間中具有對 Pod 資源對象 進行 get(獲取)、watch(監聽)、list(列出)這三個操作權限。
2)ClusterRole 示例
apiVersion:rbac.authorization.k8s.io/v1 kind:ClusterRole metadata: #"namespace"被忽略,因為 ClusterRoles 不受名字空間限制 name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] #資源對象為 Secret 類型 verbs: ["get","watch","list"]
3)RoleBinding and ClusterRoleBinding示例
RoloBinding 可以將角色中定義的權限授予用戶或用戶組,RoleBinding 包含一組主體(subject),subject 中包含有不同形式的待授予權限資源類型(User、Group、ServiceAccount);
RoloBinding 同樣包含對被綁定的 Role 引用;
RoleBinding 適用于某個命名空間內授權,而 ClusterRoleBinding 適用于集群范圍內的授權
apiVersion:rbac.authorization.k8s.io/v1 kind:RoleBinding metadata: name: read-pods namespace:default subjects: - kind: User name: zhangsan apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io #將default命名空間的 pod-reader Role 授予 zhangsan 用戶,此后 zhangsan 用戶在default命名空間中將具有 pod-reader 的權限。
6.Resources
Kubernetes 集群內一些資源一般以其名稱字符串來表示,這些字符串一般會在 API 的 URL 地址中出現; 同時某些資源也會包含子資源,例如 log 資源就屬于 pods 的子資源,API 中對 Pod 日志的請求 URL 樣例如下:
GET /api/v1/namespaces/{namespace}/pods/{name}/log kubectl get pods myapp-demo1 -n default HTTP GET https:///api/v1/namespaces/default/pods/myapp-demo1/log #在這里,pods 對應名字空間作用域的 Pod 資源,而 log 是 pods 的子資源。 如果要在 RBAC 授權模型中控制這些子資源的訪問權限,可以通過 / 分隔符來分隔資源和子資源實現。 AI寫代碼
#以下是一個定義允許某主體讀取 pods 同時訪問這些 Pod 的 log 子資源的 Role 定義樣例: apiVersion:rbac.authorization.k8s.io/v1 kind:Role metadata: namespace:default name: pod-and-pod-logs-reader rules: - apiGroups: [""] resources: ["pods","pods/log"] verbs: ["get","list"] #rules.verbs有:"get","list","watch","create","update","patch","delete","exec" #rules.resources有:"services","endpoints","pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs" #rules.apiGroups有:"","apps","autoscaling","batch"
三、準入控制(Admission Control)
1.概念
準入控制是 API Server 的一個準入控制器插件列表,通過添加不同的插件,實現額外的準入控制規則。發送到 API Server 的請求都需要經過這個列表中的每個準入控制器插件的檢查,檢查不通過,則拒絕請求。
一般建議直接采用官方默認的準入控制器。
官方準入控制器推薦列表(不同版本各有不同):
NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction
2.列舉幾個插件的功能
●NamespaceLifecycle:用于命名空間回收,防止在不存在的 namespace 上創建對象,防止刪除系統預置 namespace,刪除 namespace 時,連帶刪除它的所有資源對象。
●LimitRanger:用于配額管理,確保請求的資源量不會超過資源所在 Namespace 的 LimitRange 的限制。
●ServiceAccount:用于在每個 Pod 中自動化添加 ServiceAccount,方便訪問 API Server。
●ResourceQuota:基于命名空間的高級配額管理,確保請求的資源數量不會超過資源的 ResourceQuota 限制。
●NodeRestriction: 用于 Node 加入到 K8S 群集中以最小權限運行。
官方文檔參考:https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/
3.資源限制 - Pod
Kubernetes對資源的限制實際上是通過cgroup來控制的,cgroup是容器的一組用來控制內核如何運行進程的相關屬性集合。針對內存、CPU 和各種設備都有對應的 cgroup。
默認情況下,Pod 運行沒有 CPU 和內存的限額。這意味著系統中的任何 Pod 將能夠像執行該 Pod 所在的節點一樣, 消耗足夠多的 CPU 和內存。一般會針對某些應用的 pod 資源進行資源限制,這個資源限制是通過 resources 的 requests 和 limits 來實現。requests 為創建 Pod 時初始要分配的資源,limits 為 Pod 最高請求的資源值。
示例:
spec: containers: - image: xxxx imagePullPolicy: IfNotPresent name: auth ports: - containerPort: 8080 protocol: TCP resources: limits: cpu: "2" memory: 1Gi requests: cpu: 250m memory: 250Mi
4.資源限制 - 命名空間
1)計算資源配額
apiVersion:v1 kind:ResourceQuota #使用 ResourceQuota 資源類型 metadata: name: compute-resources namespace: spark-cluster #指定命令空間 spec: hard: pods:"20" #設置 Pod 數量最大值 requests.cpu:"2" requests.memory:1Gi limits.cpu:"4" limits.memory:2Gi
2)配置對象數量配額限制
apiVersion: v1 kind: ResourceQuota metadata: name: object-counts namespace: spark-cluster spec: hard: configmaps: "10" persistentvolumeclaims: "4" #設置 pvc 數量最大值 replicationcontrollers: "20" #設置 rc 數量最大值 secrets: "10" services: "10" services.loadbalancers: "2" #如果Pod沒有設置requests和limits,則會使用當前命名空間的最大資源;如果命名空間也沒設置,則會使用集群的最大資源。 K8S 會根據 limits 限制 Pod 使用資源,當內存超過 limits 時 cgruops 會觸發 OOM。 這里就需要創建 LimitRange 資源來設置 Pod 或其中的 Container 能夠使用資源的最大默認值 apiVersion: v1 kind: LimitRange #使用 LimitRange 資源類型 metadata: name: mem-limit-range namespace: test #可以給指定的 namespace 增加一個資源限制 spec: limits: - default: #default 即 limit 的值 memory: 512Mi cpu: 500m defaultRequest: #defaultRequest 即 request 的值 memory: 256Mi cpu: 100m type: Container #類型支持 Container、Pod、PVC
鏈接:https://blog.csdn.net/weixin_68840588/article/details/141318944?spm=1001.2014.3001.5502
-
集群
+關注
關注
0文章
97瀏覽量
17300 -
服務端
+關注
關注
0文章
67瀏覽量
7138 -
kubernetes
+關注
關注
0文章
235瀏覽量
8843
原文標題:【Kubernetes】k8s集群安全機制
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
全面提升,阿里云Docker/Kubernetes(K8S) 日志解決方案與選型對比
K8s 從懵圈到熟練 – 集群網絡詳解
Docker不香嗎為什么還要用K8s
簡單說明k8s和Docker之間的關系
K8S集群服務訪問失敗怎么辦 K8S故障處理集錦

切換k8s上下文有多快

k8s是什么意思?kubeadm部署k8s集群(k8s部署)|PetaExpres
K8s多集群管理:為什么需要多集群、多集群的優勢是什么

k8s云原生開發要求

評論