K8S之安全認證


K8S之安全認證

訪問控制

簡介

K8S 作為一個分布式集群管理工具,其內部部署大量應用,如何保證內部應用的安全性是重中之重,所謂的安全性其實就是保證對 K8S 的各種客戶端進行認證和授權操作

客戶端

在 K8S 集群中客戶端通常分為兩類

  • User Account:一般是獨立於kubernetes之外的其他服務管理的用戶賬號。
  • Service Account:kubernetes管理的賬號,用於為Pod的服務進程在訪問kubernetes時提供身份標識。

acc

認證/授權/准入控制

API Service 是訪問和管理資源的唯一入口,任何一個請求都需要訪問 API Service,經歷如下流程

  • Authentication(認證):身份鑒別,只有正確的賬號才能訪問
  • Authorization(授權):判斷賬號是否有權限執行相應的動作
  • Admission Control(注入控制):用於補充授權機制以實現更加精細的訪問控制功能

acu

認證管理

K8S 客戶端認證方式

上述中說到 K8S 需要對賬戶進行認證,在 K8S 中提供了三種認證方式

  • HTTP Base 認證
    • 通過用戶名 + 密碼進行認證
    • 該方式通過將用戶名與密碼通過 base64 進行編碼之后放入 HTTP 請求的 Header 的 Authorization 域里面發生給服務端,服務端接受到信息,提取用戶名與密碼之后在進行解碼,之后在進行用戶認證
    • 由於使用 base64 進行編碼可以通過反編碼得到用戶名密碼因此該方式不安全
  • HTTP Token
    • 通過一個 Token 來標識一個合法的用戶
    • 在該方式中每個用戶有一個唯一的 Token 用來標識用戶,當客戶端發起請求的時候在 HTTP 的 Header 中放入 Token,當服務端收到客戶端請求之后提取客戶端的 Token 信息,然后與服務器中保存的 Token 進行對比,進而驗證用戶信息
  • HTTPS 證書認證
    • 基於 CA 根證書簽名的雙向證書認證方式
    • 這種認證方式是安全性最高的一種方式,但是同時也是操作起來最麻煩的一種方式。

https

HTTPS 認證

  • 證書申請和下發,HTTPS 通信雙方想 CA 機構進行證書申請,CA機構下發根證書,服務端證書以及私鑰給申請者
  • 客戶端和服務端進行雙向認證
    • 客戶端向服務端發起請求,服務端向客戶端發送自己的證書,客戶端通過自己的私鑰對服務端的證書進行解密獲取服務端的公鑰,客戶端利用服務端的公鑰認證證書信息,如果信息一致則信任服務端
    • 客戶端發送自己的證書給服務端,服務端接受到客戶端的證書之后使用私鑰解密獲取客戶端的公鑰,之后使用客戶的公鑰進行認證證書信息,如果一致則認可客戶端
  • 服務端和客戶端進行通信
    • 服務端和客戶端協商解密方案,並且產生一個隨機的秘鑰進行加密
    • 客戶端將秘鑰發給服務端,之后雙方使用該加密秘鑰進行數據通信

注意: Kubernetes允許同時配置多種認證方式,只要其中任意一個方式認證通過即可

授權管理

概述

  • 授權發生在認證成功之后,通過認證就可以知道請求用戶是誰,然后kubernetes會根據事先定義的授權策略來決定用戶是否有權限訪問,這個過程就稱為授權。

  • 每個發送到API Server的請求都帶上了用戶和資源的信息:比如發送請求的用戶、請求的路徑、請求的動作等,授權就是根據這些信息和授權策略進行比較,如果符合策略,則認為授權通過,否則會返回錯誤。

授權策略

  • AlwaysDeny:表示拒絕所有請求,一般用於測試。

  • AlwaysAllow:允許接收所有的請求,相當於集群不需要授權流程(kubernetes默認的策略)。

  • ABAC:基於屬性的訪問控制,表示使用用戶配置的授權規則對用戶請求進行匹配和控制。

  • Webhook:通過調用外部REST服務對用戶進行授權。

  • Node:是一種專用模式,用於對kubelet發出的請求進行訪問控制。

  • RBAC:基於角色的訪問控制(kubeadm安裝方式下的默認選項)。

RBAC

概述

  • RBAC(Role Based Access Control):基於角色的訪問控制,主要是在描述一件事情:給哪些對象授權了哪些權限。

  • RBAC涉及到了下面幾個概念:

    • 對象:User、Groups、ServiceAccount。
    • 角色:代表着一組定義在資源上的可操作的動作(權限)的集合。
    • 綁定:將定義好的角色和用戶綁定在一起。

rbac

RBAC還引入了4個頂級資源對象

  • Role、ClusterRole:角色,用於指定一組權限。
  • RoleBinding、ClusterRoleBinding:角色綁定,用於將角色(權限的集合)賦予給對象。

Role/ClusterRole

一個角色就是一組權限的集合,這里的權限都是許可形式的(白名單)。

role 資源清單文件

# Role只能對命名空間的資源進行授權,需要指定namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: authorization-role
  namespace: dev
rules:
  - apiGroups: [""] # 支持的API組列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的資源對象列表
    verbs: ["get","watch","list"]

ClusterRole的資源清單文件:

# ClusterRole可以對集群范圍內的資源、跨namespace的范圍資源、非資源類型進行授權
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: authorization-clusterrole
rules:
  - apiGroups: [""] # 支持的API組列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的資源對象列表
    verbs: ["get","watch","list"]

rules中的參數說明:

  • apiGroups:

    • 支持的API組列表。
    • “”,”apps”,”autoscaling”,”batch”。
  • resources:

    • 支持的資源對象列表。
    • "services","endpoints","pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs"。
  • verbs:

    • 對資源對象的操作方法列表。
    • "get", "list", "watch", "create", "update", "patch", "delete", "exec"。

RoleBinding、ClusterRoleBinding

角色綁定用來把一個角色綁定到一個目標對象上,綁定目標可以是User、Group或者ServiceAccount。

RoleBinding的資源清單文件:

# RoleBinding可以將同一namespace中的subject對象綁定到某個Role下,則此Subject具有該Role定義的權限
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: authorization-role-binding
  namespace: dev
subjects:
  - kind: User
    name: SR
    apiGroup: rbac.authorization.k8s.io  
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: authorization-role

ClusterRoleBinding的資源清單文件:

# ClusterRoleBinding在整個集群級別和所有namespaces將特定的subject與ClusterRole綁定,授予權限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: authorization-clusterrole-binding
subjects:
  - kind: User
    name: SR
    apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: authorization-clusterrole

RoleBinding引用ClusterRole進行授權

  • RoleBinding可以引用ClusterRole,對屬於同一命名空間內ClusterRole定義的資源主體進行授權。

  • 一種很常用的做法是,集群管理員為集群范圍預定義好一組角色(ClusterRole),然后在多個命名空間中重復使用這些ClusterRole。這樣可以大幅度提高授權管理工作效率,也使得各個命名空間下的基礎性授權規則和使用體驗保持一致。

# 雖然authorization-clusterrole是一個集群角色,但是因為使用了RoleBinding
# 所以SR只能讀取dev命名空間中的資源
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: authorization-clusterrole-binding
subjects:
  - kind: User
    name: SR
    apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: authorization-clusterrole

RBAC實戰

創建一個只能管理dev命名空間下Pods資源的賬號。

創建賬號

# 創建證書
cd /etc/kubernetes/pki/ && (umask 077;openssl genrsa -out devman.key 2048)

# 簽名申請	申請的用戶是devman,組是devgroup
openssl req -new -key devman.key -out devman.csr -subj "/CN=devman/O=devgroup"

# 簽署證書
openssl x509 -req -in devman.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out devman.crt -days 3650

image-20211130210415759

# 設置集群/用戶/上下文
kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://172.16.137.128:6443

kubectl config set-credentials devman --embed-certs=true --client-certificate=/etc/kubernetes/pki/devman.crt --client-key=/etc/kubernetes/pki/devman.key

kubectl config set-context devman@kubernetes --cluster=kubernetes --user=devman


# 切換devman 賬號
kubectl config use-context devman@kubernetes

# 查看
kubectl get pods -n dev

image-20211130210618034

# 切換到 admin 賬戶
kubectl config use-context kubernetes-admin@kubernetes

創建Role和RoleBinding,為devman授權

# 創建配置文件
cat > dev-role.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: dev-role
  namespace: dev
rules:
  - apiGroups: [""] # 支持的API組列表,""空字符串,表示核心API群
    resources: ["pods"] # 支持的資源對象列表
    verbs: ["get","watch","list"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: authorization-role-binding 
  namespace: dev
subjects:
  # 針對用戶類型
  - kind: User
    name: devman
    apiGroup: rbac.authorization.k8s.io 
roleRef:
  # 針對 role
  kind: Role 
  name: dev-role
  apiGroup: rbac.authorization.k8s.io
EOF

# 加載配置文件
[root@master k8s]# kubectl create -f dev-role.yaml

# 切換用戶再次驗證
kubectl config use-context devman@kubernetes

[root@master k8s]# kubectl get -n dev pod -o wide

image-20211130211904653

准入控制

概述

  • 通過了前面的認證和授權之后,還需要經過准入控制通過之后,API Server才會處理這個請求。

  • 准入控制是一個可配置的控制器列表,可以通過在API Server上通過命令行設置選擇執行哪些注入控制器。

--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds

當前可配置的Admission Control(准入控制)

  • AlwaysAdmit:允許所有請求。

  • AlwaysDeny:禁止所有請求,一般用於測試。

  • AlwaysPullImages:在啟動容器之前總去下載鏡像。

  • DenyExecOnPrivileged:它會攔截所有想在Privileged Container上執行命令的請求。

  • ImagePolicyWebhook:這個插件將允許后端的一個Webhook程序來完成admission controller的功能。

  • Service Account:實現ServiceAccount實現了自動化。

  • SecurityContextDeny:這個插件將使用SecurityContext的Pod中的定義全部失效。

  • ResourceQuota:用於資源配額管理目的,觀察所有請求,確保在namespace上的配額不會超標。

  • LimitRanger:用於資源限制管理,作用於namespace上,確保對Pod進行資源限制。

  • InitialResources:為未設置資源請求與限制的Pod,根據其鏡像的歷史資源的使用情況進行設置。

  • NamespaceLifecycle:如果嘗試在一個不存在的namespace中創建資源對象,則該創建請求將被拒 絕。當刪除一個namespace時,系統將會刪除該namespace中所有對象。

  • DefaultStorageClass:為了實現共享存儲的動態供應,為未指定StorageClass或PV的PVC嘗試匹配默認StorageClass,盡可能減少用戶在申請PVC時所需了解的后端存儲細節。

  • DefaultTolerationSeconds:這個插件為那些沒有設置forgiveness tolerations並具有notready:NoExecute和unreachable:NoExecute兩種taints的Pod設置默認的“容忍”時間,為5min。

  • PodSecurityPolicy:這個插件用於在創建或修改Pod時決定是否根據Pod的security context和可用的 PodSecurityPolicy對Pod的安全策略進行控制


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM