028.核心組件-API Server
- 2020 年 3 月 17 日
- 筆記
一 Kubernetes API Server原理
1.1 API Server功能
Kubernetes API Server的核心功能是提供Kubernetes各類資源對象(如Pod、RC、Service等)的增、刪、改、查及Watch等HTTP Rest介面,成為集群內各個功能模組之間數據交互和通訊的中心樞紐,是整個系統的數據匯流排和數據中心。同時還有以下一些功能特性。
- 是集群管理的API入口。
- 是資源配額控制的入口。
- 提供了完備的集群安全機制。
1.2 Kubernetes API Server概述
Kubernetes API Server通過一個名為kube-apiserver的進程提供服務,該進程運行在Master上。在默認情況下,kube-apiserver進程在本機的8080埠(對應參數–insecure-port=8080)提供REST服務。同時啟動HTTPS安全埠(–secure-port=6443)來啟動安全機制,加強RESTAPI訪問的安全性。
通常可以通過命令行工具kubectl來與Kubernetes API Server交互,它們之間的介面是RESTful API。也可通過curl直接測試和驗證Kubernetes API Server所提供的介面。
insecure-port非安全方式測試:
1 [root@k8smaster01 study]# curl localhost:8080/api #以JSON方式返回 2 [root@k8smaster01 study]# curl localhost:8080/api/v1 #查看Kubernetes API Server支援的資源對象種類 3 [root@k8smaster01 study]# curl localhost:8080/api/v1/pods 4 [root@k8smaster01 study]# curl localhost:8080/api/v1/services #分別查看集群對應資源列表
secure-port=6443安全方式測試:
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/api/v1/pods
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/api/v1/services
1.3 API Server架構解析
API Server的架構從上到下可以分為以下幾層。
- API層:主要以REST方式提供各種API介面,除了有Kubernetes資源對象的CRUD和Watch等主要API,還有健康檢查、UI、日誌、性能指標等運維監控相關的API。
注意:Kubernetes從1.11版本開始廢棄Heapster監控組件,轉而使用Metrics Server提供Metrics API介面,進一步完善了自身的監控能力。
- 訪問控制層:當客戶端訪問API介面時,訪問控制層負責對用戶身份鑒權,驗明用戶身份,核准用戶對Kubernetes資源對象的訪問許可權,然後根據配置的各種資源訪問許可邏輯(AdmissionControl),判斷是否允許訪問。
- 註冊表層:Kubernetes把所有資源對象都保存在註冊表(Registry)中,針對註冊表中的各種資源對象都定義了:資源對象的類型、如何創建資源對象、如何轉換資源的不同版本,以及如何將資源編碼和解碼為JSON或ProtoBuf格式進行存儲。
- etcd資料庫:用於持久化存儲Kubernetes資源對象的KV資料庫。etcd的watch API介面對於API Server來說至關重要,因為通過這個介面,API Server創新性地設計了List-Watch這種高性能的資源對象實時同步機制,使Kubernetes可以管理超大規模的集群,及時響應和快速處理集群中的各種事件。
本質上看,API Server與常見的MIS或ERP系統中的DAO模組類似,可以將主要處理邏輯視作對資料庫表的CRUD操作。
如下以一個完整的Pod調度過程為例,對API Server的List-Watch機制進行說明。
Pod調度過程中的List-Watch機制:
首先,藉助etcd提供的Watch API介面,API Server可以監聽(Watch)在etcd上發生的數據操作事件,比如Pod創建事件、更新事件、刪除事件等,在這些事件發生後,etcd會及時通知API Server。
如上圖所示API Server與etcd之間的交互:當一個ReplicaSet對象被創建並被保存到etcd中後,etcd會立即發送一個對應的Create事件給API Server,與其類似的6、7、10、11箭頭都是針對Pod的創建、更新事件的。
然後,為了讓Kubernetes中的其他組件在不訪問底層etcd資料庫的情況下,也能及時獲取資源對象的變化事件,API Server模仿etcd的Watch API介面提供了自己的Watch介面,從而,其他組件就能近乎實時地獲取希望獲取的任意資源對象的相關事件通知。
如上圖所示controller-manager、scheduler、kublet等組件與API Server之間的3個標記有List-Watch的虛框表明了此過程。
提示:其他組件在監聽希望獲取的資源事件的時候,可以增加過濾條件,如上圖List-Watch3為例,node1節點上的kubelet進程只希望獲取自己節點上的Pod事件。
最後,Kubernetes List-Watch用於實現數據同步的程式碼邏輯。客戶端首先調用API Server的List介面獲取相關資源對象的全量數據並將其快取到記憶體中,然後啟動對應資源對象的Watch協程,在接收到Watch事件後,再根據事件的類型(比如新增、修改或刪除)對記憶體中的全量資源對象列表做出相應的同步修改。
從實現上來看,這是一種全量結合增量的、高性能的、近乎實時的數據同步方式。
二 Kubernetes Proxy API
2.1 Proxy API介紹
Kubernetes API Server最主要的REST介面是資源對象的增、刪、改、查介面,同時還提供了一類很特殊的REST介面:Kubernetes Proxy API介面。
這類介面的作用是代理REST請求,即Kubernetes API Server把收到的REST請求轉發到某個Node上的kubelet守護進程的REST埠,由該kubelet進程負責響應。
Kubernetes Proxy API里關於Node的REST介面路徑為/api/v1/proxy/nodes/{name},其中{name}為節點的名稱或IP地址,包括以下幾個具體介面:
/api/v1/proxy/nodes/{name}/pods/ #列出指定節點內所有Pod的資訊
/api/v1/proxy/nodes/{name}/stats/ #列出指定節點內物理資源的統計資訊
/api/v1/proxy/nodes/{name}/spec/ #列出指定節點的概要資訊
三 集群模組之間的通訊
3.1 通訊概述
如下圖所示,Kubernetes API Server作為集群的核心,負責集群各功能模組之間的通訊。集群內的各個功能模組通過API Server將資訊存入etcd,當需要獲取和操作這些數據時,則通過API Server提供的REST介面(用GET、LIST或WATCH方法)來實現,從而實現各模組之間的資訊交互。
常見的一個交互場景是kubelet進程與API Server的交互。每個Node上的kubelet每隔一個時間周期,就會調用一次API Server的REST介面報告自身狀態,API Server在接收到這些資訊後,會將節點狀態資訊更新到etcd中。
此外,kubelet也通過API Server的Watch介面監聽Pod資訊,如果監聽到新的Pod副本被調度綁定到本節點,則執行Pod對應的容器創建和啟動邏輯;如果監聽到Pod對象被刪除,則刪除本節點上相應的Pod容器;如果監聽到修改Pod的資訊,kubelet就會相應地修改本節點的Pod容器。
另一個交互場景是kube-controller-manager進程與API Server的交互。kube-controller-manager中的Node Controller模組通過API Server提供的Watch介面實時監控Node的資訊,並做相應處理。
還有一個比較重要的交互場景是kube-scheduler與API Server的交互。Scheduler通過API Server的Watch介面監聽到新建Pod副本的資訊後,會檢索所有符合該Pod要求的Node列表,開始執行Pod調度邏輯,在調度成功後將Pod綁定到目標節點上。
為了緩解集群各模組對API Server的訪問壓力,各功能模組都採用快取機制來快取數據。
各功能模組定時從API Server獲取指定的資源對象資訊(通過List-Watch方法),然後將這些資訊保存到本地快取中,功能模組在某些情況下不直接訪問API Server,而是通過訪問快取數據來間接訪問API Server。