kubernetes——安全認(rèn)證

訪問控制概述

Kubernetes作為一個(gè)分布式集群的管理工具雷逆,保證集群的安全性是其一個(gè)重要的任務(wù)鞋吉。所謂的安全性其實(shí)就是保證對Kubernetes的各種客戶端進(jìn)行認(rèn)證和鑒權(quán)操作。

客戶端

在Kubernetes集群中,客戶端通常有兩類:

  • User Account:一般是獨(dú)立于kubernetes之外的其他服務(wù)管理的用戶賬號。

  • Service Account:kubernetes管理的賬號,用于為Pod中的服務(wù)進(jìn)程在訪問Kubernetes時(shí)提供身份標(biāo)識麻裁。

認(rèn)證、授權(quán)與準(zhǔn)入控制

ApiServer是訪問及管理資源對象的唯一入口瞻鹏。任何一個(gè)請求訪問ApiServer悲立,都要經(jīng)過下面三個(gè)流程:

  • Authentication(認(rèn)證):身份鑒別,只有正確的賬號才能夠通過認(rèn)證
  • Authorization(授權(quán)): 判斷用戶是否有權(quán)限對訪問的資源執(zhí)行特定的動作
  • Admission Control(準(zhǔn)入控制):用于補(bǔ)充授權(quán)機(jī)制以實(shí)現(xiàn)更加精細(xì)的訪問控制功能新博。

認(rèn)證管理

Kubernetes集群安全的最關(guān)鍵點(diǎn)在于如何識別并認(rèn)證客戶端身份薪夕,它提供了3種客戶端身份認(rèn)證方式:

  • HTTP Base認(rèn)證:通過用戶名+密碼的方式認(rèn)證
    這種認(rèn)證方式是把“用戶名:密碼”用BASE64算法進(jìn)行編碼后的字符串放在HTTP請求中的Header Authorization域里發(fā)送給服務(wù)端。服務(wù)端收到后進(jìn)行解碼赫悄,獲取用戶名及密碼原献,然后進(jìn)行用戶身份認(rèn)證的過程。

  • HTTP Token認(rèn)證:通過一個(gè)Token來識別合法用戶
    這種認(rèn)證方式是用一個(gè)很長的難以被模仿的字符串--Token來表明客戶身份的一種方式埂淮。每個(gè)Token對應(yīng)一個(gè)用戶名姑隅,當(dāng)客戶端發(fā)起API調(diào)用請求時(shí),需要在HTTP Header里放入Token倔撞,API Server接到Token后會跟服務(wù)器中保存的token進(jìn)行比對讲仰,然后進(jìn)行用戶身份認(rèn)證的過程。

  • HTTPS證書認(rèn)證:基于CA根證書簽名的雙向數(shù)字證書認(rèn)證方式
    這種認(rèn)證方式是安全性最高的一種方式痪蝇,但是同時(shí)也是操作起來最麻煩的一種方式鄙陡。

HTTPS認(rèn)證大體分為3個(gè)過程:

    1. 證書申請和下發(fā)
      HTTPS通信雙方的服務(wù)器向CA機(jī)構(gòu)申請證書,CA機(jī)構(gòu)下發(fā)根證書躏啰、服務(wù)端證書及私鑰給申請者
    1. 客戶端和服務(wù)端的雙向認(rèn)證
    • 客戶端向服務(wù)器端發(fā)起請求趁矾,服務(wù)端下發(fā)自己的證書給客戶端,客戶端接收到證書后给僵,通過私鑰解密證書毫捣,在證書中獲得服務(wù)端的公鑰,客戶端利用服務(wù)器端的公鑰認(rèn)證證書中的信息,如果一致蔓同,則認(rèn)可這個(gè)服務(wù)器
    • 客戶端發(fā)送自己的證書給服務(wù)器端饶辙,服務(wù)端接收到證書后,通過私鑰解密證書牌柄,在證書中獲得客戶端的公鑰畸悬,并用該公鑰認(rèn)證證書信息,確認(rèn)客戶端是否合法
  1. 服務(wù)器端和客戶端進(jìn)行通信
    • 服務(wù)器端和客戶端協(xié)商好加密方案后珊佣,客戶端會產(chǎn)生一個(gè)隨機(jī)的秘鑰并加密,然后發(fā)送到服務(wù)器端披粟。
    • 服務(wù)器端接收這個(gè)秘鑰后咒锻,雙方接下來通信的所有內(nèi)容都通過該隨機(jī)秘鑰加密

注意: Kubernetes允許同時(shí)配置多種認(rèn)證方式,只要其中任意一個(gè)方式認(rèn)證通過即可

授權(quán)管理

授權(quán)發(fā)生在認(rèn)證成功之后守屉,通過認(rèn)證就可以知道請求用戶是誰惑艇, 然后Kubernetes會根據(jù)事先定義的授權(quán)策略來決定用戶是否有權(quán)限訪問,這個(gè)過程就稱為授權(quán)拇泛。

每個(gè)發(fā)送到ApiServer的請求都帶上了用戶和資源的信息:比如發(fā)送請求的用戶滨巴、請求的路徑、請求的動作等俺叭,授權(quán)就是根據(jù)這些信息和授權(quán)策略進(jìn)行比較恭取,如果符合策略,則認(rèn)為授權(quán)通過熄守,否則會返回錯(cuò)誤蜈垮。

API Server目前支持以下幾種授權(quán)策略:

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

  • AlwaysAllow:允許接收所有請求裕照,相當(dāng)于集群不需要授權(quán)流程(Kubernetes默認(rèn)的策略)

  • ABAC:基于屬性的訪問控制攒发,表示使用用戶配置的授權(quán)規(guī)則對用戶請求進(jìn)行匹配和控制

  • Webhook:通過調(diào)用外部REST服務(wù)對用戶進(jìn)行授權(quán)

  • Node:是一種專用模式,用于對kubelet發(fā)出的請求進(jìn)行訪問控制

  • RBAC:基于角色的訪問控制(kubeadm安裝方式下的默認(rèn)選項(xiàng))

RBAC(Role-Based Access Control) 基于角色的訪問控制晋南,主要是在描述一件事情:給哪些對象授予了哪些權(quán)限

其中涉及到了下面幾個(gè)概念:

  • 對象:User惠猿、Groups、ServiceAccount
  • 角色:代表著一組定義在資源上的可操作動作(權(quán)限)的集合
  • 綁定:將定義好的角色跟用戶綁定在一起

RBAC引入了4個(gè)頂級資源對象:

  • Role负间、ClusterRole:角色偶妖,用于指定一組權(quán)限
  • RoleBinding、ClusterRoleBinding:角色綁定唉擂,用于將角色(權(quán)限)賦予給對象

Role餐屎、ClusterRole
一個(gè)角色就是一組權(quán)限的集合,這里的權(quán)限都是許可形式的(白名單)玩祟。

# Role只能對命名空間內(nèi)的資源進(jìn)行授權(quán)腹缩,需要指定nameapce
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: dev
  name: authorization-role
rules:
- apiGroups: [""]  # 支持的API組列表,"" 空字符串,表示核心API群
  resources: ["pods"] # 支持的資源對象列表
  verbs: ["get", "watch", "list"] # 允許的對資源對象的操作方法列表
# ClusterRole可以對集群范圍內(nèi)資源、跨namespaces的范圍資源藏鹊、非資源類型進(jìn)行授權(quán)
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
 name: authorization-clusterrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

需要詳細(xì)說明的是润讥,rules中的參數(shù):

  • 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

角色綁定用來把一個(gè)角色綁定到一個(gè)目標(biāo)對象上盘寡,綁定目標(biāo)可以是User楚殿、Group或者ServiceAccount。

# RoleBinding可以將同一namespace中的subject綁定到某個(gè)Role下竿痰,則此subject即具有該Role定義的權(quán)限
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: authorization-role-binding
  namespace: dev
subjects:
- kind: User
  name: heima
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: authorization-role
  apiGroup: rbac.authorization.k8s.io
# ClusterRoleBinding在整個(gè)集群級別和所有namespaces將特定的subject與ClusterRole綁定脆粥,授予權(quán)限
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
 name: authorization-clusterrole-binding
subjects:
- kind: User
  name: heima
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: authorization-clusterrole
  apiGroup: rbac.authorization.k8s.io

RoleBinding引用ClusterRole進(jìn)行授權(quán)

RoleBinding可以引用ClusterRole,對屬于同一命名空間內(nèi)ClusterRole定義的資源主體進(jìn)行授權(quán)影涉。

一種很常用的做法就是变隔,集群管理員為集群范圍預(yù)定義好一組角色(ClusterRole),然后在多個(gè)命名空間中重復(fù)使用這些ClusterRole蟹倾。這樣可以大幅提高授權(quán)管理工作效率匣缘,也使得各個(gè)命名空間下的基礎(chǔ)性授權(quán)規(guī)則與使用體驗(yàn)保持一致。

# 雖然authorization-clusterrole是一個(gè)集群角色鲜棠,但是因?yàn)槭褂昧薘oleBinding
# 所以heima只能讀取dev命名空間中的資源
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: authorization-role-binding-ns
  namespace: dev
subjects:
- kind: User
  name: heima
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: authorization-clusterrole
  apiGroup: rbac.authorization.k8s.io

實(shí)戰(zhàn):創(chuàng)建一個(gè)只能管理dev空間下Pods資源的賬號

  • 1肌厨、創(chuàng)建賬號
# 1) 創(chuàng)建證書
[root@master pki]# cd /etc/kubernetes/pki/
[root@master pki]# (umask 077;openssl genrsa -out devman.key 2048)

# 2) 用apiserver的證書去簽署
# 2-1) 簽名申請,申請的用戶是devman,組是devgroup
[root@master pki]# openssl req -new -key devman.key -out devman.csr -subj "/CN=devman/O=devgroup"     
# 2-2) 簽署證書
[root@master pki]# openssl x509 -req -in devman.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out devman.crt -days 3650

# 3) 設(shè)置集群豁陆、用戶柑爸、上下文信息
[root@master pki]# kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.109.100:6443

[root@master pki]# kubectl config set-credentials devman --embed-certs=true --client-certificate=/etc/kubernetes/pki/devman.crt --client-key=/etc/kubernetes/pki/devman.key

[root@master pki]# kubectl config set-context devman@kubernetes --cluster=kubernetes --user=devman

# 切換賬戶到devman
[root@master pki]# kubectl config use-context devman@kubernetes
Switched to context "devman@kubernetes".

# 查看dev下pod,發(fā)現(xiàn)沒有權(quán)限
[root@master pki]# kubectl get pods -n dev
Error from server (Forbidden): pods is forbidden: User "devman" cannot list resource "pods" in API group "" in the namespace "dev"

# 切換到admin賬戶
[root@master pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
  • 2献联、創(chuàng)建Role和RoleBinding竖配,為devman用戶授權(quán)
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: dev
  name: dev-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
  
---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: authorization-role-binding
  namespace: dev
subjects:
- kind: User
  name: devman
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: dev-role
  apiGroup: rbac.authorization.k8s.io
[root@master pki]# kubectl create -f dev-role.yaml
role.rbac.authorization.k8s.io/dev-role created
rolebinding.rbac.authorization.k8s.io/authorization-role-binding created
  • 3、切換賬戶里逆,再次驗(yàn)證
# 切換賬戶到devman
[root@master pki]# kubectl config use-context devman@kubernetes
Switched to context "devman@kubernetes".

# 再次查看
[root@master pki]# kubectl get pods -n dev
NAME                                 READY   STATUS             RESTARTS   AGE
nginx-deployment-66cb59b984-8wp2k    1/1     Running            0          4d1h
nginx-deployment-66cb59b984-dc46j    1/1     Running            0          4d1h
nginx-deployment-66cb59b984-thfck    1/1     Running            0          4d1h

# 為了不影響后面的學(xué)習(xí),切回admin賬戶
[root@master pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

準(zhǔn)入控制

通過了前面的認(rèn)證和授權(quán)之后进胯,還需要經(jīng)過準(zhǔn)入控制處理通過之后,apiserver才會處理這個(gè)請求原押。

準(zhǔn)入控制是一個(gè)可配置的控制器列表胁镐,可以通過在Api-Server上通過命令行設(shè)置選擇執(zhí)行哪些準(zhǔn)入控制器:

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,
                      DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds

只有當(dāng)所有的準(zhǔn)入控制器都檢查通過之后,apiserver才執(zhí)行該請求诸衔,否則返回拒絕盯漂。

當(dāng)前可配置的Admission Control準(zhǔn)入控制如下:

  • AlwaysAdmit:允許所有請求
  • AlwaysDeny:禁止所有請求,一般用于測試
  • AlwaysPullImages:在啟動容器之前總?cè)ハ螺d鏡像
  • DenyExecOnPrivileged:它會攔截所有想在Privileged Container上執(zhí)行命令的請求
  • ImagePolicyWebhook:這個(gè)插件將允許后端的一個(gè)Webhook程序來完成admission controller的功能笨农。
  • Service Account:實(shí)現(xiàn)ServiceAccount實(shí)現(xiàn)了自動化
  • SecurityContextDeny:這個(gè)插件將使用SecurityContext的Pod中的定義全部失效
  • ResourceQuota:用于資源配額管理目的就缆,觀察所有請求,確保在namespace上的配額不會超標(biāo)
  • LimitRanger:用于資源限制管理谒亦,作用于namespace上竭宰,確保對Pod進(jìn)行資源限制
  • InitialResources:為未設(shè)置資源請求與限制的Pod空郊,根據(jù)其鏡像的歷史資源的使用情況進(jìn)行設(shè)置
  • NamespaceLifecycle:如果嘗試在一個(gè)不存在的namespace中創(chuàng)建資源對象,則該創(chuàng)建請求將被拒絕切揭。當(dāng)刪除一個(gè)namespace時(shí)狞甚,系統(tǒng)將會刪除該namespace中所有對象。
  • DefaultStorageClass:為了實(shí)現(xiàn)共享存儲的動態(tài)供應(yīng)廓旬,為未指定StorageClass或PV的PVC嘗試匹配默認(rèn)的StorageClass哼审,盡可能減少用戶在申請PVC時(shí)所需了解的后端存儲細(xì)節(jié)
  • DefaultTolerationSeconds:這個(gè)插件為那些沒有設(shè)置forgiveness tolerations并具有notready:NoExecute和unreachable:NoExecute兩種taints的Pod設(shè)置默認(rèn)的“容忍”時(shí)間,為5min
  • PodSecurityPolicy:這個(gè)插件用于在創(chuàng)建或修改Pod時(shí)決定是否根據(jù)Pod的security context和可用的PodSecurityPolicy對Pod的安全策略進(jìn)行控制

參考:
https://www.cnblogs.com/huiyichanmian/p/15130174.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孕豹,一起剝皮案震驚了整個(gè)濱河市涩盾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌励背,老刑警劉巖旁赊,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異椅野,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)籍胯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門竟闪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杖狼,你說我怎么就攤上這事炼蛤。” “怎么了蝶涩?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵理朋,是天一觀的道長。 經(jīng)常有香客問我绿聘,道長嗽上,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任熄攘,我火速辦了婚禮兽愤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挪圾。我一直安慰自己浅萧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布哲思。 她就那樣靜靜地躺著洼畅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棚赔。 梳的紋絲不亂的頭發(fā)上帝簇,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天徘郭,我揣著相機(jī)與錄音,去河邊找鬼己儒。 笑死崎岂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闪湾。 我是一名探鬼主播冲甘,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼途样!你這毒婦竟也來了江醇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤何暇,失蹤者是張志新(化名)和其女友劉穎陶夜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裆站,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡条辟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宏胯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羽嫡。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肩袍,靈堂內(nèi)的尸體忽然破棺而出杭棵,到底是詐尸還是另有隱情,我是刑警寧澤氛赐,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布魂爪,位于F島的核電站,受9級特大地震影響艰管,放射性物質(zhì)發(fā)生泄漏滓侍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一蛙婴、第九天 我趴在偏房一處隱蔽的房頂上張望粗井。 院中可真熱鬧,春花似錦街图、人聲如沸浇衬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耘擂。三九已至,卻和暖如春絮姆,著一層夾襖步出監(jiān)牢的瞬間醉冤,已是汗流浹背秩霍。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚁阳,地道東北人铃绒。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像螺捐,于是被迫代替她去往敵國和親颠悬。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容