Kubernetes集群安全機制說明
Kubernetes作為一個分布式集群的管理工具瞭稼,保證集群的安全性是其中一個重要的任務(wù),API Server是集群內(nèi)部各個組件通信的中介环肘,也是外部控制的入口。所以Kubernetes的安全機制基本就是圍繞保護API Server來設(shè)計的复哆。Kubernetes使用了認(rèn)證(Authentication)欣喧、鑒權(quán)(Authorization)梯找、準(zhǔn)入控制(Admission Control)三步來保證API Server的安全。
認(rèn)證(Authentication)
-
HTTP Token認(rèn)證:通過一個Token來識別合法用戶
- HTTP Token的認(rèn)證是用一個很長的特殊編碼方式的并且難以被模仿的字符串-Token來表達客戶端的方式酷鸦,Token是一個很長的很復(fù)雜的字符串牙咏,每一個Token對應(yīng)一個用戶名存儲在API Server能訪問的文件中,當(dāng)客戶端發(fā)起API請求調(diào)用時妄壶,需要在HTTP Header里放入Token。
-
HTTP Base認(rèn)證:通過用戶名+密碼的方式認(rèn)證
用戶名:密碼
用BASE64算法進行編碼后的字符串放在HTTP Request中的Header Authorization域里發(fā)送給服務(wù)端丁寄,服務(wù)端收到后進行解碼,獲取用戶名和密碼盛正。 - HTTPS 證書認(rèn)證:基于CA證書簽名的數(shù)字證書認(rèn)證
HTTPS 證書認(rèn)證
需要認(rèn)證的節(jié)點
兩種類型
- Kubernetes組件對API Server的訪問:kubectl屑埋、Controller Manager、Scheduler摘能、kubelet、kube-proxy
- Kubernetes管理的Pod對容器的訪問:Pod(dashborad也是以Pod形式運行)
安全性說明
- Controller Manager团搞、Scheduler與API Server在同一臺機器,所以直接使用API Server的非安全端口訪問
--insecure-bind-address=127.0.0.1
- kubectl像吻、kubelet梢莽、kube-proxy訪問API Server都需要證書進行HTTPS雙向認(rèn)證
證書頒發(fā)
- 手動簽發(fā):通過K8s集群跟ca進行簽發(fā)HTTPS證書
- 自動簽發(fā):kubelet首次訪問API Server時萧豆,使用token做認(rèn)證昏名,通過后Controller Manager會為kubelet生成一個證書以后的訪問都是用證書做認(rèn)證了。
kubeconfig
kubeconfig文件包含集群參數(shù)(CA證書轻局、API Server地址)样刷,客戶端參數(shù)(上面生成的證書和私鑰)览爵、集群Context信息(集群名稱、用戶名)蜓竹。Kubernetes組件通過啟動時指定不同的kubeconfig文件可以切換到不同的集群。
ServiceAccount
Pod中的容器訪問API Server嘶是,因為Pod的創(chuàng)建、銷毀是動態(tài)的聂喇,所以要為它手動生成證書就不可行了蔚携,Kubernetes使用了Service Account解決Pod訪問API Server的認(rèn)證問題。
Secret和CA的關(guān)系
Kubernetes設(shè)計了一種資源叫做Secret酝蜒,分為兩類,一種是用于ServiceAccount的service-account-token秕硝,另一種是用于保存用戶自定義保密信息的Oqaque洲尊,ServiceAccount中用到包含三個部分:Token、ca.crt坞嘀、namespace
- Token:是使用了API Server私鑰簽名的JWT,用于訪問API Server時棺滞,Server端認(rèn)證
- ca.crt:根證書,用于Client端驗證API Server發(fā)送的證書
-
namespace:標(biāo)識這個service-account-token的作用域名空間
默認(rèn)情況下继准,每個namespace都會有一個ServiceAccount矮男,如果Pod在創(chuàng)建時沒有指定ServiceAccount,就會使用Pod所屬的namespace的ServiceAccount毡鉴。
鑒權(quán)(Authorization)
上面的認(rèn)證過程秒赤,只是確認(rèn)通信的雙方都確認(rèn)對方是可信的憎瘸,進而可以互相通信。
鑒權(quán)是確定請求方有哪些資源權(quán)限幌甘,API Server 內(nèi)部通過用戶認(rèn)證后,然后進入授權(quán)流程锅风。對合法用戶進行授權(quán)并且隨后在用戶訪問時進行鑒權(quán),是權(quán)限管理的重要環(huán)節(jié)盆均。API Server目前支持以下幾種授權(quán)策略(通過API Server的啟動參數(shù)--authorization-mode
設(shè)置)
- Always Deny: 表示拒絕所有的請求,一般用于測試泪姨。
- Always Allow:允許接收所有請求饰抒,如果集群不需要授權(quán)流程,則可以采用該策略袋坑。
- ABAC: 基于屬性的訪問控制,表示使用用戶配置的授權(quán)規(guī)則對用戶請求進行匹配和控制枣宫。
- Webhook:通過調(diào)用外部REST服務(wù)對用戶進行授權(quán)。
- RBAC:Role-Base Access Control也颤, 基于角色的訪問控制。
RBAC授權(quán)模式
RBAC(Role-Based Access Control文留,基于角色的訪問控制)在Kubernetes v1.5引入竭沫,在v1.6版本時升級為Beta版本燥翅,并成為kubeadm安裝方式下的默認(rèn)選項蜕提,組建其重要程度。相對于其他的訪問控制方式,RBAC具有如下優(yōu)勢躲查。
- 對集群中的資源和非資源權(quán)限均有完整的覆蓋译柏。
- 整個RBAC完全由幾個API對象完成镣煮,同其他API對象一樣鄙麦,可以用kubectl或API進行操作。
- 可以在運行時進行調(diào)整胯府,無須重新啟動API Server。
要使用RBAC授權(quán)模式炎咖,則需要在API Server的啟動參數(shù)中加上--authorization-mode=RBAC
寒波。
角色
- Role:授權(quán)特定命名空間的訪問權(quán)限
- ClusterRole:授權(quán)所有命名空間的訪問權(quán)限
角色綁定
- RoleBinding:將角色綁定到主體(即subject)
- ClusterRoleBinding:將集群角色綁定到主體
主體(subject)
- User:用戶
- Group:用戶組
- ServiceAccount:服務(wù)賬號
1、RBAC的API資源對象說明
BAC引入了4個新的頂級資源對象:Role俄烁、ClusterRole、RoleBinding页屠、ClusterRoleBinding。同其他API資源對象一樣风纠,用戶可以使用kubectl或者API調(diào)用方式操作這些資源對象。
需要注意的是Kubernetes并不會提供用戶管理议忽,那么User十减、Group愤估、ServiceAccount指定的用戶又是從哪里來的呢帮辟?Kubernetes組件(kubectl玩焰、kube-proxy)或是其他自定義的用戶在向CA申請證書時,需要提供一個證書請求文件蔓榄。
[root@k8s-master1 ~]# vim jane-csr.json
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
- API Server會把客戶端證書的
CN
字段作為User并炮,把names.O
字段作為Group - kubelet使用TLS Bootstaping認(rèn)證時甥郑,API Server可以使用 Bootstrap Tokens或者Token authentication file驗證=token,無論哪一種伍俘,Kubernetes都會為token綁定一個默認(rèn)的User和Group
- Pod使用ServiceAccount認(rèn)證時,service-account-token中的JWT會保存User信息
- 有了用戶信息癌瘾,在創(chuàng)建一對角色/角色綁定(集群角色/集群角色綁定)資源對象饵溅,就可以完成權(quán)限綁定了妨退。
Role and ClusterRole
在RBAC API中Role表示一組規(guī)則權(quán)限蜕企,權(quán)限只會增加(累加權(quán)限),不存在一個資源一開始就有很多權(quán)限而通過RBAC對其進行減少的操作糖赔;Role可以定義在一個namespace中,如果想要跨namespace則可以創(chuàng)建ClusterRole
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # ""空字符串逝变,表示核心API群
resources: ["pods"]
verbs: ["get", "watch", "list"]
rules中的參數(shù)說明:
- apiGroups: 支持的API組列表奋构,例如“apiVersion: batch/v1”壳影、“apiVersion: extensions:v1beta1”弥臼、“apiVersion: apps/v1beta1”等。
- resources:支持的資源對象列表径缅,例如pods、deployments氧卧、jobs等。
- verbs:對資源對象的操作方法列表沙绝,例如get、watch闪檬、list、delete粗悯、replace、patch等邮丰。
ClusterRole
ClusterRole處理具有和Role一致的命名空間內(nèi)資源的管理能力,因其集群級別的范圍剪廉,還可以用于以下特殊元素的授權(quán)炕檩。
- 集群級別的資源控制斗蒋,例如Node(節(jié)點)笛质。
- 非資源類型的路徑,例如“/healthz”妇押。
- 包含全部命名空間的資源,例如pods(用于kubectl get pods --all-namespaces這樣的操作授權(quán))俊马。
下面的ClusterRole可以讓用戶有權(quán)訪問任意一個或所有命名空間的secrets(視其綁定方式而定):
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
# ClusterRole不受限于命名空間肩杈,所以省略了namespace name的定義
name: secret-reader
rules:
- apiGroups: [""] # ""空字符串柴我,表示核心API群
resources: ["secrets"]
verbs: ["get", "watch", "list"]
角色綁定(RoleBinding)和集群角色綁定(ClusterRoleBinding)
RoleBinding可以將角色中定義的權(quán)限授予用戶或用戶組扩然,RoleBinding包含一組權(quán)限列表(subjects),權(quán)限列表中包含有不同形式的待授予權(quán)限資源類型(users夫偶、groups、Service Account)晕窑;RoleBinding同樣包含對被Bind的Role引用卵佛,RoleBinding適用于某個命名空間內(nèi)授權(quán),ClusterRoleBinding適用于集群范圍內(nèi)授權(quán)截汪。
下面例子中的RoleBinding將在default命名空間中把pod-reader角色授予用戶jane,這一操作讓jane可以讀取default命名空間中的Pod:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: read-pods
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding也可以引用ClusterRole衙解,來對當(dāng)前namespace內(nèi)用戶、用戶組或ServiceAccount進行授權(quán)蚓峦,這種操作允許集群管理員在整個集群內(nèi)定義一些通用ClusterRole,然后在不同的namespace中使用RoleBinding來引用
例如暑椰,以下RoleBinding引用一個ClusterRole,這個ClusterRole具有整個集群內(nèi)對secrets的訪問權(quán)限一汽,但是其授權(quán)用戶dave只能訪問development空間中的secrets(因為RoleBinding定義在development命名空間)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: development
name: read-secret
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
集群角色綁定中的角色只能是集群角色,用于進行集群級別或者對所有命名空間都生效的授權(quán)召夹。下面的例子允許manager組的用戶讀取任意namespace中的secret:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: development
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
資源(resources)與主體(subjects)
資源(resources)介紹
- 在Kubernets中,主要的資源包括:Pods监憎、Nodes、Services鲸阔、Deployment、Replicasets腾它、Statefulsets死讹、Namespace瞒滴、Persistents赞警、Secrets和ConfigMaps等。
- 同時愧旦,有些資源下面存在子資源,例如:Pod下就存在log子資源笤虫。
# logs資源就屬于pods的子資源祖凫,API中URL樣例如下
Get /api/v1/namespaces/{namespace}/pods/{name}/log
示例1:普通角色的資源列表:
[root@k8smaster01 study]# vi pod-and-pod_log.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
verbs: ["get","list"]
解釋:如上限定在default的命名空間的名為pod-and-pod-logs-reader的普通角色酬凳,對pod和pods/log資資源就有g(shù)et和list的權(quán)限。
示例2:更精細(xì)粒度的資源控制稠屠,可通過resourceNamess指定特定的資源實例,以限制角色只能夠?qū)唧w的某個實例進行訪問控制权埠。
[root@k8smaster01 study]# vi updater_configmap.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update","get"]
解釋:如上限定在default的命名空間的名為configmap-updater的普通角色煎谍,對名為my-configmap的configmaps類型的特定資源攘蔽,具有update和get權(quán)限粱快。
主體(subjects)介紹
- RBAC授權(quán)中的主體可以是組,用戶或者服務(wù)帳戶事哭。用戶通過字符串表示,比如“alice”降盹、“bob@example.com”等,具體的形式取決于管理員在認(rèn)證模塊中所配置的用戶名蓄坏。
- system: 被保留作為用來Kubernetes系統(tǒng)內(nèi)部使用丑念,因此不能作為用戶的前綴涡戳。組也有認(rèn)證模塊提供脯倚,格式與用戶類似。
示例1:類型為user(用戶)恍涂。
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
示例2:類型為group(組)。
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
示例3:查看default的服務(wù)賬戶再沧。
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
準(zhǔn)入控制
Kubernetes系統(tǒng)通過三個獨?的組件間的相互協(xié)作來實現(xiàn)服務(wù)賬戶的?動化尊残,三個組件具體為:Admission Controllers準(zhǔn)?控制器、令牌控制器(token controller)和Service Account賬戶控制器。Service Account控制器負(fù)責(zé)為名稱空間管理相應(yīng)的資源,并確保每個名稱空間中都存在?個名為“default”的Service Account對象。
當(dāng)請求通過了前面的認(rèn)證和授權(quán)之后钩蚊,還需要經(jīng)過準(zhǔn)入控制處理通過之后,apiserver 才會處理這個請求技俐。Admission Control 有一個準(zhǔn)入控制列表统台,我們可以通過命令行設(shè)置選擇執(zhí)行哪幾個準(zhǔn)入控制器。只有所有的準(zhǔn)入控制器都檢查通過之后井赌,apiserver 才執(zhí)行該請求贵扰,否則返回拒絕戚绕。
為什么需要Admission Control
在kubernetes中,一些高級特性正常運行的前提條件為耘子,將一些準(zhǔn)入模塊處于enable狀態(tài)球切。總結(jié)下捍歪,對于kubernetes apiserver怀骤,如果不適當(dāng)?shù)呐渲脺?zhǔn)入控制模塊蒋伦,他就不能稱作是一個完整的server,某些功能也不會正常的生效韧献。
主要的準(zhǔn)入控制器介紹
AlwaysAdmit
允許所有請求
AlwaysDeny
拒絕所有請求
AlwaysPullImages
強制設(shè)置Pod拉取鏡像策略為Always。這樣能夠保證私有鏡像只能被有拉取權(quán)限的使用者使用锤窑。
DenyExecOnPrivileged
它會攔截所有想在privileged container上執(zhí)行命令的請求。(如果自己的集群支持privileged container渊啰,自己又希望限制用戶在這些privileged container上執(zhí)行命令,那么強烈推薦使用它绘证。)
DenyEscalatingExec
這個插件禁止那些通過主機執(zhí)行而獲得privileges去執(zhí)行exec和attach Pod的命令。
ImagePolicyWebhook
通過webhook決定image策略嚷那,需要同時配置–admission-control-config-file
ServiceAccount
一個serviceAccount為運行在pod內(nèi)的進程添加了相應(yīng)的認(rèn)證信息胞枕。當(dāng)準(zhǔn)入模塊中開啟了此插件(默認(rèn)開啟),如果pod沒有serviceAccount屬性魏宽,將這個pod的serviceAccount屬性設(shè)為“default”腐泻;確保pod使用的serviceAccount始終存在;如果LimitSecretReferences 設(shè)置為true队询,當(dāng)這個pod引用了Secret對象卻沒引用ServiceAccount對象派桩,棄置這個pod;如果這個pod沒有包含任何ImagePullSecrets娘摔,則serviceAccount的ImagePullSecrets被添加給這個pod;如果MountServiceAccountToken為true凳寺,則將pod中的container添加一個VolumeMount 鸭津。
ResourceQuota
它會觀察所有的請求,確保在namespace中ResourceQuota對象處列舉的container沒有任何異常肠缨。如果在kubernetes中使用了ResourceQuota對象逆趋,就必須使用這個插件來約束container。(推薦在admission control參數(shù)列表中晒奕,這個插件排最后一個闻书。)
LimitRanger
實現(xiàn)配額控制。他會觀察所有的請求脑慧,確保沒有違反已經(jīng)定義好的約束條件魄眉,這些條件定義在namespace中LimitRange對象中。如果在kubernetes中使用LimitRange對象闷袒,則必須使用這個插件坑律。
SecurityContextDeny
禁止創(chuàng)建設(shè)置了 Security Context 的 pod。這個插件將會將使用了 SecurityContext的pod中定義的選項全部失效囊骤。關(guān)于 SecurityContext的描述:SecurityContext 在container中定義了操作系統(tǒng)級別的安全設(shè)定(uid, gid, capabilities, SELinux等等)晃择。
NamespaceLifecycle
確保處于termination狀態(tài)的namespace不再接收新的對象創(chuàng)建請求冀值,并拒絕請求不存在的namespace。
InitialResources
根據(jù)鏡像的歷史使用記錄宫屠,為容器設(shè)置默認(rèn)資源請求和限制
DefaultStorageClass
為PVC設(shè)置默認(rèn)StorageClass
DefaultTolerationSeconds
設(shè)置Pod的默認(rèn)forgiveness toleration為5分鐘
PodSecurityPolicy
使用Pod Security Policies時必須開啟
NodeRestriction
限制kubelet僅可訪問node列疗、endpoint、pod浪蹂、service以及secret抵栈、configmap、PV和PVC等相關(guān)的資源(v1.7版本以上才支持)
推薦的設(shè)置控制器順序:
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds
參考:
https://www.cnblogs.com/xzkzzz/p/9909468.html
https://www.cnblogs.com/Dev0ps/p/10852445.html
https://www.kubernetes.org.cn/1995.html
https://www.kubernetes.org.cn/4061.html
http://www.reibang.com/p/5a6e9ee8ab5a
http://www.reibang.com/p/fd61330596eb