1 Kubelet運行機制
- Kubenetes集群中的每個Node節點都會啟動一個Kubelet服務進程用於處理Master下發到該節點的任務,管理Pod及其中的容器
- Kubelet進程在API Server上注冊信息,定期向Master節點匯報Node資源情況,並通過cAdvise監控容器和節點資源
1.1 節點管理
- Kubelet進程在啟動時設置參數
--register-node=true
設置向APIServer主動注冊節點信息 - 當設置非自動注冊時,需要配置Node的資源信息以及給Kubelet指定API Server位置
- Kubelet啟動參數
--api-server //設置api server位置
--kubeconfig //設置訪問api server的證書
--cloud-provider //如何從雲服務讀取相關元數據
--node-status-update-frequency //向api server報告的間隔時間,默認10s
1.2 Pod管理
- 非API Server方式創建的Pod稱為Static Pod,Kubelet將Static Pod狀態匯報給API Server,而后API Server為該Static Pod創建一個Mirror Pod與其相匹配
- Kubelet監聽etcd中所有對Pod的操作
- Kubelet讀取到創建和修改Pod任務處理:
- 為該Pod創建一個數據目錄
- 從API Server讀取該Pod清單
- 為該Pod掛載外部卷(Extenal Volume)
- 下載Pod用到的Secret
- 檢查已經運行在節點中的Pod,如果Pod沒有容器或Pause容器沒有啟動則停止Pod中所有容器進程。如果Pod中有需要刪除的容器則刪除
- 用Pause鏡像為每個Pod創建一個容器,其用於接管Pod中所有其他容器的網絡
- 為Pod中的每個容器做如下處理:
- 校驗容器的hash值
- 如果容器被中止且容器沒有指定restartPolicy則不做任何處理
- 調用Docker Client下載容器鏡像,運行容器
1.3 容器健康檢查
- LivenessProbe探針用於判斷容器是否健康,如果不健康則Kubelet將刪除該容器並根據重啟策略進行處理,實現方式有:
- ExecAction:在容器內部執行一個命令如果命令退出狀態碼為0則容器健康
- TCPSocketAction:通過容器IP和端口執行TCP檢測
- HTTPGetAction:通過容器IP和端口及路徑調用HTTP Get方法,判斷響應的狀態碼
- Readiness探針用於判斷容器是否啟動完成,且准備接受請求。如果檢測失敗則Pod狀態將被修改,Endpoint Controller將從Service的Endpoint中刪除包含該容器所在Pod的條目
2 安全機制原理
集群的安全性必須考慮如下幾個目標:
- 保證容器與其所在宿主機的隔離
- 限制容器給基礎設施及其他容器帶來的消極影響的能力
- 最小權限原則——合理限制所有組件的權限
- 明確組件間邊界的划分
- 划分普通用戶和管理員用戶
- 在必要時允許將管理員權限賦給普通用戶
- 允許擁有Secret數據(Keys,Certs,Passwords)的應用在集群中運行
2.1 Authentication認證
Kubelet對API的調用使用如下方式:
- CA,使用HTTPS方式,在API Server啟動參數
--client_ca_file=SOMEFILE
設定CA的認證授權文件 - Token,通過API Server啟動參數
--token_auth_file=SOMEFILE
指定存儲Token的文件。Token文件格式為一個包含三列的CSV文件,該文件第一列為Token,第二列為用戶名,第三列為用戶UID。同時訪問時HTTP請求頭中的Authorization域必須包含Bearer SOMETOKEN
指定該用戶的Token - HTTP Base,通過API Server啟動參數
--basic_auth_file=SOMEFILE
指定存儲用戶和密碼的基本認證文件。該文件為CSV文件,第一列為密碼,第二列為用戶名,第三列為UID。HTTP請求頭中的Authorization域必須包含Basic BASE64ENCODEDUSER:PASSWORD
即base64加密后的用戶名和密碼
2.2 Authorization授權
- 授權(Authorization)是認證(Authentication)后的一個獨立步驟,作用於API Server主要端口的所有HTTP訪問
- 授權流程通過訪問策略比較請求上下文屬性,通過API訪問資源之前必須通過訪問策略進行校驗,配置如下:
--authorization_mode=AlwaysDeny //表示拒絕所有請求
--authorization_mode=AlwaysAllow //接受所有請求
--authorization_mode=ABAC //使用用戶配置的授權策略去管理訪問API Server的請求,ABAC(Attribute-Based Access Control)基於屬性的訪問控制
-
Kubernetes中HTTP請求包含如下4個能被授權進程識別的屬性:
- 用戶名
- 是否是只讀請求(REST中的GET操作均為只讀)
- 被訪問的是哪一類資源
- 被訪問對象所屬Namespace
-
如果請求中不帶對應的某個屬性則默認零值
-
選擇ABAC模式則需要在API Server啟動時設置
--authorization_polic_file=SOMEFIME
指定授權策略的JSON文件,文件的每一行為一個JSON的Map對象且不包含List,主要包含以下屬性:- user(用戶名),字符串類型
- readonly,布爾型,為true時表示只接受GET訪問
- resource,字符串來自於URL的資源
- namespace,字符串表明該策略允許訪問的某個Namespace
-
授權文件中一個未設置的屬性表示匹配HTTP請求中該屬性的任何值
-
對請求的4個屬性和授權文件的策略對象逐個匹配,如果至少有一個策略對象被匹配上則該請求被授權通過
2.3 Admission Control准入控制
用於攔截所有經過認證和鑒權后的訪問API Server請求的可插入代碼,這些插件運行在API Server進程中,每個Admission Control插件按照配置順序執行,如果其中任意一個插件拒絕該請求,則API Server將拒絕請求
- 配置API Server啟動參數
admission_control
,該參數中加入需要的插件列表,逗號隔開
2.4 Secret私密憑據
主要作用是保管私密數據,如密碼、OAuth Token、SSH Keys等,將這些私密信息放在Secret對象比直接放入Pod或Docker Image中要安全。
- 如果Pod指定了Service Account則該Pod自動添加包含憑證信息的Secrets,用於訪問API Server和下載Image
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data: //全部是Base64編碼值
password: 123 //Base64編碼值
username: 123
-
Secret被使用的方式:
- 在創建Pod時通過為Pod指定Service Account來自動使用該Secret
- 通過掛載Secret到Pod,spec.volumes.secret指定
- 在創建Pod時,指定Pod的spec.ImagePullSecret來引用
-
目前Secret只支持API Server創建
-
在使用Mount方式掛載Secret時,容器中Secret的data域中的各個key值作為目錄中的文件,value值被Base64編碼后存儲在相應的文件中
-
通過API Server創建Pod時不會校驗引用的Secret是否存在,只有當Pod被調度時將試着去獲取Secret,如果此時獲取不到則將按一定時間間隔定期重試,並發送一個Event解釋Pod沒啟動的原因
-
Secret包括Opaque、ServiceAccount和Dockercfg三種類型
2.5 Service Account
Service Account是多個Secret的集合,包含普通Secret用於訪問API Server和imagePullSecret用於下載容器鏡像
apiVersion: v1
kind: ServiceAccount
metadata:
name: myserviceaccount
secrets:
- kind: Secret
name: secret1
apiVersion: v1
- kind: Secret
name: secret2
apiVersion: v1
imagePullSecrets:
- name: secret1
- 如果創建Pod時沒指定ServiceAccount則將在對應Namespace中制定一個名為default的ServiceAccount