一 Kubernetes API Server
Kubernetes API Server 提供了以下幾種功能:
- 提供集群管理的 API 接口
- 成為集群內(nèi)各個模塊之間數(shù)據(jù)交互和通信的中心樞紐
- 擁有完備的集群安全機(jī)制
?訪問 Kubernetes API
Kubernetes API 通過一個叫 Kubernetes apiserver 的進(jìn)程提供服務(wù),這個進(jìn)程運(yùn)行在 kubernetes-master 節(jié)點(diǎn)上。該進(jìn)程包含兩個端口:
本地端口
- 該端口用于接受 HTTP 請求
- 該端口的默認(rèn)值是 8080缸濒,IP 是 localhost
- 非認(rèn)證或授權(quán)的 HTTP 請求可以通過該端口進(jìn)行訪問
安全端口
- 該端口默認(rèn)為 6443,默認(rèn)的 IP 為非本地(Non-localhost)網(wǎng)絡(luò)端口
- 該端口用于接受 HTTPS 請求
- 用于基于 Token 文件或客服端證書以及 HTTP Base 進(jìn)行認(rèn)證
- Kubernetes 默認(rèn)不啟動該安全訪問機(jī)制
Kubernetes 提供了一個代理 —— kubectl proxy播急,它即能作為 Kubernetes API 的反向代理,也可以作為普通的 client 來訪問 Kubernetes API 的代理售睹。Kubernetes 給我們提供來一個客戶端工具 kubectl桩警,用它將 kubernetes 提供的API 包裝成命令集來使用:
kubectl [command] [options]
?通過 API Server 訪問 Node、Pod昌妹、Service
訪問 Node
/api/v1/proxy/nodes/{name} // name 為節(jié)點(diǎn)的名稱或者IP地址(REST 接口捶枢,支持CURD)
/api/v1/proxy/nodes/{name}/pods //列出該 Node 下所有 Pod 的信息
/api/v1/proxy/nodes/{name}/stats //列出該 Node 內(nèi)物理資源的統(tǒng)計信息
/api/v1/proxy/nodes/{name}/spec //列出該 Node 概要信息
后面三個接口只有在該 Node 的 Kubelet 啟動時包含 --enable-server=true
參數(shù)時才會開始。如果在啟動時還包含了 --enbale-debugging-handlers=true
飞崖,那么 API Server 還會包含以下訪問接口
/api/v1/proxy/nodes/{name}/run //在節(jié)點(diǎn)內(nèi)運(yùn)行一個 container柱蟀,run 命令和 Docker 的 run 用法一致
/api/v1/proxy/nodes/{name}/exec //用法同上
/api/v1/proxy/nodes/{name}/attach //用法同上
/api/v1/proxy/nodes/{name}/logs //列出該 Node 的各類 log 信息
訪問 Pod 提供的服務(wù)
/api/v1/namespaces/{namespace}/pods/{name}/proxy //訪問Pod
/api/v1/namespaces/{namespace}/pods/{name}/proxy/{path:*} // 訪問該 Pod 的某個服務(wù)的接口
訪問 Service
如果 Service 包含 kubernetes.io/cluster-service:true
和 kubernetes.io/name:$CLUSTERSERVICENAME
(集群 Service 的名稱) 標(biāo)簽,那么用戶可以通過 API Server 的/api/v1/namespaces/{namespace}/services/{service}
接口來訪問 Service蚜厉,通過 /api/v1/namespaces/{namespace}/services/{service}/{path:*}
來訪問該 Service 中的 Pod 中的 containers 提供的服務(wù)长已;
?集群功能模塊之間的通信
API Server 作為集群的核心,負(fù)責(zé)集群各功能模塊之間的通信昼牛。各功能模塊會通過 API Server 將信息存入 etcd 术瓮,其它模塊可以(get、list贰健、watch)讀取這些信息胞四,從而實(shí)現(xiàn)模塊之間的通信;比如 Node 上的 kubelet 會定期的將自身的狀態(tài)報告給 API Server伶椿,API Server 接收到信息之后會存入到 etcd 中辜伟,Controller Manager 中的 Node Manager 會定期的通過 API Server 讀取 Node 的信息并做相應(yīng)的處理;
二 調(diào)度器控制原理
Controller Manager 作為集群內(nèi)部的管理控制中心脊另,主要負(fù)責(zé)對 Node(Node Controller)导狡、Pod 副本(Replication Controller)、Endpoint(Endpoint Controller)偎痛、Namespace(Namespace Controller)旱捧、服務(wù)賬號(ServiceAccount Controller)、資源定額(ResourceQuota Controller)等管理并自動化修復(fù)。每種都對應(yīng)了一個 Controller 進(jìn)行管理枚赡,通過 API Server 監(jiān)聽共享狀態(tài)氓癌,從而自動化實(shí)現(xiàn)從”現(xiàn)有狀態(tài)“修復(fù)到”期望狀態(tài)“。
? Replication Controller
為了區(qū)分 Controller Manager 中的 Replication Controller(副本控制器)和資源對象 Replication Controller贫橙,一般把資源對象 Replication Controller 簡寫為 RC贪婉。
Replication Controller 的核心作用就是確保在任何時候集群中的一個 RC 所關(guān)聯(lián)的 Pod 都保持在一定的數(shù)量 Pod 副本處于正常運(yùn)行的狀態(tài);以多退少補(bǔ)的原則對 Pod 副本進(jìn)行管理卢肃,根據(jù) RC 的定義谓松,實(shí)現(xiàn)自動創(chuàng)建、補(bǔ)足践剂、替換、刪除 Pod 副本娜膘。
Pod 的幾種狀態(tài)
- pending:API Server 已經(jīng)創(chuàng)建該 Pod逊脯,Pod 內(nèi)還有一個or多個 container 的 image 還沒有創(chuàng)建
- running:Pod 內(nèi)所有的 container 都已創(chuàng)建,且至少有一個 container 處于運(yùn)行狀態(tài)或正在重啟or啟動
- succeeded:Pod 內(nèi)所有的 container 都成功中止竣贪,且不會再重啟
- failed:Pod 內(nèi)所有 container 均已退出军洼,且至少有一個 container 應(yīng)為發(fā)生錯誤而退出
通常情況下,Pod 對象創(chuàng)建后不會消失演怎,即使手動刪除 Pod匕争,除了使用 Replication Controller進(jìn)行刪除外唯一的例外是當(dāng) Pod 處于 succeeded 或 failed 狀態(tài)的時間過長,該 Pod 會被回收爷耀。
RC 的使用
RC 可以被認(rèn)為是一個模版文件甘桑,里面定義的是 Pod 的模版,里面包含 Pod 的標(biāo)簽屬性歹叮,同時 RC 也包含了一個標(biāo)簽選擇器(Label Selector)跑杭,Selector 的值表明了該 RC 所關(guān)聯(lián)的 Pod,從而篩選出該 RC 管理的 Pod咆耿。
kind: ReplicationController
apiVersion: v1
metadata:
name: teciplsrc
labels:
name: teciplsrc
spec:
replicas: 3
selector:
name: teciplsrc
template:
metadata:
labels:
name: teciplsrc
spec:
containers:
- image: xxxx
name: teciplsrc-01
這個 RC 創(chuàng)建了一個包含一個 container 的 Pod —— teciplsrc德谅,包含三個副本。一旦 Pod 創(chuàng)建出來后萨螺,無論 RC 怎么改變都不會影響到 Pod窄做,即使是刪除,Pod 也可以通過修改 Label 來實(shí)現(xiàn)脫離該 RC 的控制慰技,如果想要刪除 Pod椭盏,則需要修改 RC 的副本數(shù)為0,這樣所有的副本都會被干掉吻商。
Replication Controller 的職責(zé)
- 確保當(dāng)前集群中存在且僅有N個 Pod 實(shí)例
- 通過調(diào)整 RC 的 sprc.replicas 屬性來控制 Pod 的副本數(shù)量(以此實(shí)現(xiàn) 重新調(diào)度庸汗、彈性收縮、滾動更新等功能)
? Node Controller
Node Controller 負(fù)責(zé)發(fā)現(xiàn)手报、管理和監(jiān)控集群中的各 Node 節(jié)點(diǎn)蚯舱,Node 節(jié)點(diǎn)的 kubelet 在啟動時通過 API Server 注冊節(jié)點(diǎn)信息改化,并定時向 API Server 發(fā)送節(jié)點(diǎn)信息,API Server 接受到信息后會存到 etcd 中枉昏。這些信息包括了節(jié)點(diǎn)的健康狀況(就緒 True陈肛、未就緒False、未知Unknow)兄裂、節(jié)點(diǎn)資源句旱、節(jié)點(diǎn)名稱、節(jié)點(diǎn)地址晰奖、操作系統(tǒng)谈撒、Docker 版本等。
? ResourceQuota Controller
ResourceQuota Controller 確保指定的對象在任何時候都不會超量占用系統(tǒng)資源匾南,避免了某些業(yè)務(wù)的進(jìn)程設(shè)計或?qū)崿F(xiàn)的缺陷導(dǎo)致整個系統(tǒng)運(yùn)行紊亂的問題啃匿。ResourceQuota Controller 支持以下三個層次的資源配額管理:
- container 級別,可以對 CPU 和Memory 進(jìn)行限制
- Pod 級別蛆楞,可以對一個 Pod 內(nèi)所有容器的可用資源進(jìn)行限制
-
Namespace 級別溯乒,同一 Namespace 下的資源進(jìn)行限制,包括 Pod 數(shù)量豹爹、Replication Controller 數(shù)量裆悄、Service 數(shù)量、ResourceQuota Controller 數(shù)量臂聋、Secret 數(shù)量光稼、PV 數(shù)量等。
流程
? Namespace Controller
用戶通過 API Server 來創(chuàng)建新的 Namespace 并保存在 etcd 中孩等,Namespace Controller 定時通過 API Server 讀取 Namespace 信息钟哥。
如果 Namespace 被標(biāo)記為刪除,那么會將 Namespace 的狀態(tài)置為 “Terminating” 并保存到 etcd 中瞎访,同時 Namespace Controller 會刪除該 Namespace 下的所有的資源腻贰;在這種狀態(tài)下,Adminssion Controller 的 NamespaceLifecycle 插件會阻止為該 Namespace 創(chuàng)建新的資源扒秸;當(dāng)該 Namespace 下的資源被刪干凈后播演,Namespace Controller 會執(zhí)行 finalize 操作,刪除 spec.finalizers 域中的信息伴奥。當(dāng) Namespace Controller 檢測到 Namespace 設(shè)置來刪除期限写烤,且 spec.finalzers 域值為空,那么就會通過 API Server 刪除該 Namespace拾徙。
? Service Controller 與 Endpoint Controller
Kubernetes 中的 Service 同 Pod 類似也是一種資源洲炊,可以通過 API Server 中國中 POST 接口創(chuàng)建。
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: myApp
ports:
- port: 80
targetPort:9999
protocol: TCP
上面創(chuàng)建了一個名稱為 my-service 的 Service,包含了一個選擇器暂衡,通過這個選擇器會選擇所有包含該標(biāo)簽的 Pod 作為該 Service 的 Pod 集合询微。Pod 集合中每個 Pod 的80端口都會映射到該節(jié)點(diǎn)的 9999 端口,同時 Kubernetes 會指派一個集群 IP 給該 Service狂巢。
在創(chuàng)建 Service 時撑毛,如果指定了 selector,那么系統(tǒng)會自動創(chuàng)建一個和該 Service 同名的 Endpoint 資源對象唧领,該 Endpoint 包含了一個地址和端口集合藻雌,分配給服務(wù)該選擇器的 Pod 。
通過虛擬IP訪問 Pod
每個 Node 節(jié)點(diǎn)上都運(yùn)行了一個叫 kube-proxy 的進(jìn)程斩个,該進(jìn)程會監(jiān)控 Kubernetes Master 節(jié)點(diǎn)添加or刪除 Service 和 Endpoint 的操作胯杭,kube-proxy 會為每個 Service 在當(dāng)前所在 Node 上開一個端口(隨機(jī)),任何訪問該端口的連接都會代理到該 Service 中的某個 Pod 上受啥。
集群外部訪問 Service
Kubernetes 提供了兩種方式來實(shí)現(xiàn)做个,一種是 NodePort ,另一種是 LoadBalancer腔呜。每個 Service 定義的 spec.type 域作為定于 Service 類型的地兒,有三個選項(xiàng)
- ClusterIP:默認(rèn)值再悼,僅使用集群內(nèi)部虛擬IP
- NodePort:使用虛擬IP核畴,同時通過在每個節(jié)點(diǎn)暴露相同的端口來暴露 Service
- LoadBalancer:使用虛擬IP和NodePort,并擁有負(fù)載均衡的功能
在 Kubernetes 1.0 中冲九,NodePort 支持 TCP 和 UDP谤草,而 LoadBalancer 僅支持 TCP。
Endpoint Controller 通過 store 緩存 Service 和 Pod 信息莺奸。如果監(jiān)聽到 Service 被刪除丑孩,則會刪除該 Service 和 同名的 Endpoint 對象;根據(jù) Service 信息獲取相關(guān)的 Pod 列表灭贷,創(chuàng)建新的 Endpoint 的 subset 對象温学。如果監(jiān)聽到新建or修改 Service,那么會根據(jù) Service 的 name 和 labels 新建一個新的 Endpoint 對象甚疟,并同步到 etcd仗岖。
如果 Endpoint Controller 監(jiān)聽到添加 or 刪除 Pod,則會從本地找到與該 Pod 相關(guān)的 Service 列表并更新相關(guān)的 Service 的 Endpoint 且保存到 etcd 中览妖。
? Kubernetes Scheduler
Kubernetes Scheduler 負(fù)責(zé)對 Pod 的調(diào)度工作轧拄,起到了承上啟下的作用。承上:接收 Controller Manger 創(chuàng)建的新 Pod讽膏;啟下:安置好 Pod 后檩电,會將對 Pod 管理的工作交給目標(biāo) Node 上的 Kubelet 服務(wù)進(jìn)程。
- Scheduler 監(jiān)聽到 Pod Queue 有新的 Pod 需要創(chuàng)建
- 通過檢測 NodeList 以及相應(yīng)的調(diào)度算法和策略綁定到集群中某個合適 Node 上,并將綁定信息保存到 etcd 中
- Node 上的 kubelet 通過 API Server 監(jiān)聽到 Kubernetes Scheduler 產(chǎn)生的 Pod 綁定事件俐末,獲取到對應(yīng)的 Pod 清單料按,下載 image 鏡像,啟動容器鹅搪。