抽空讀完了《k8s權威指南》一書,對k8s的總算有了較爲系統的認知。node
好記憶不如多寫字,如下是讀書筆記linux
k8s是什麼: 一個開源的容器集羣管理平臺,可提供容器集羣的自動部署,擴縮容,維護等功能。分爲管理節點Master和工做節點Node
web
核心組件:算法
分層架構:docker
apiVersion : v1
用來標識版本
kind : Pod/Service
類型可選Pod Service等
metadata: name: nameSpace:
後端
靜態pod 是由kubelet進行管理建立的只存在於特定Node上的Pod,kubelet沒法對其進行靜態檢查,且通常只存在於kubelet所在的節點上。
且沒法經過API server進行管理,也不會和ReplicationController Deployment產生關聯。api
建立方式: yml文件【配置文件】或者http請求安全
如何刪除: 沒法經過API server進行管理,因此Master沒法對靜態pod進行刪除【狀態更新爲pending】。刪除只能經過所在的node節點刪除配置文件網絡
在同一個pod內的容器能夠共享pod級別的volume架構
pod能夠經過k8s提供的集羣化配置管理方案 configMap來實現配置信息和程序分離。
建立方式: yaml文件
生命週期 在系統內被定義爲各類狀態。能夠分爲 Pending Running Succeeded Failed Unknow
重啓策略 應用於Pod內的全部容器,並由Pod所在node節點上的kubelet進行狀態判斷和重啓。當容器異常退出或者健康檢查狀態失敗的時候,kubelet會根據所設置的重啓策略從新啓動該container
重啓的間隔時間以設定的間隔時間的2n來計算,且在成功重啓的10分鐘後重置該時間。
不一樣的控制器對Pod的重啓策略的要求是不同的:
pod的健康檢查可以使用2類探針: LivenessProbe 和ReadinessProbe
LivenessProbe 探針的實現方法
全自動調度,用戶配置好應用容器的副本數量後RC會自動調度+持續監控始終讓副本數量爲此在規定的個數當中。
調度算法 系統內置的調度算法/NodeSelector/NodeAffinity
和RC相似,不一樣之處在於DaementSet控制每一臺Node上只容許一個Pod副本實例,適用於須要單個Node運行一個實例的應用:
批處理模型
這裏在項目中的具體應用待更新,如今項目所用的k8s 調度模型【後續會單獨寫篇文章更新】
手動更新 kubectl scale命令更新RC的副本實例數量
自動更新 使用HAP控制器,基於在controller-manager設置好的週期,週期性的對Pod的cup佔用率進行監控,自動的調節RC或者Deployment中副本實例進行調整來達到設定的CPU佔用率。
service能夠爲一組具備相同功能的容器提供一個統一的入口地址,並將請求負載進行分發到後端各個容器應用上。
kubectl create -f name.yaml
kubectl get pods -l app=webapp -o yaml | grep podIP
由於RC配置的副本實例數量爲2 因此可得2個可用的Pod EndPoint 分別爲172.17.172.3:80
172.17.172.4:80
不管任何一個Pod出現問題,kubelet 會根據重啓策略對Pod進行從新啓動,再次查詢PodIP會發現PodIP發生變化
由於Pod的不可靠,從新啓動被k8s調度到其餘Node上會致使實例的endpoint不同。且在分佈式部署的狀況下,多個容器對外提供服務,還須要在Pod前本身動手解決負載均衡的問題,這些問題均可經過SVC解決。
建立方式 : kubectl expose命令/配置文件
kubectl expose命令
kubectl expose rc webapp
此時端口號會根據以前RC設置的containerPort 來進行設置kubectl get SVC
配置文件方式啓動
定義的關鍵在於 selector 和ports
負載分發策略 RoundRobin/SessionAffinity/自定義實現
思路是把SVC或者pod的虛擬端口映射到宿主機的端口,使得客戶端應用能夠經過宿主機端口訪問容器應用。
將容器應用的端口號映射到主機
1 容器級別 設置hostPort = prodNum yaml中的配置表爲hostPort: 8081
,指的是綁定到的宿主機端口。HostPort和containerPort能夠不相等
2 Pod級別 設置hostNetWork = true 這時候設置的全部的containerPort 都會直接映射到宿主機相同的端口上。默認且必須是HostPort = containerPort,若顯示的指定HostPort和containerPort不相等則無效。
將SVC端口號映射到主機
關鍵配置爲 kind = service type = NodePort
nodePort = xxxxx
,同時在物理機上對防火牆作對應的設置便可。
能夠直接完成服務名稱到ClusterIP的解析。由如下部分組成
主要提供了各種資源對象【SVC Pod RC】等的增刪查改以及Watch等Http Rest接口,是各個模塊之間的數據交互和通信的樞紐。
Kubernetes API Server : 提供API接口來完成各類資源對象的建立和管理,自己也是一個SVC 名稱爲Kubernetes
Kubernetes Proxy API :負責把收到的請求轉到對應Node上的kubelet守護進程的端口上,kubelet負責相應,來查詢Node上的實時信息 包括node pod SVC等 多用於集羣外想實時獲取Node內的信息用於狀態查詢以及管理。 【kubelet也會定時和etcd 同步自身的狀態,和直接查詢etcd存在必定的差別,這裏強調實時】
集羣模塊之間的通訊: 都須要經過API Server 來完成模塊之間的通訊,最終會將資源對象狀態同步到etcd,各個集羣模塊根據經過API Server在etcd定時同步信息,來對所管理的資源進行相應處理。
集羣內部的管理中心,負責集羣內部的Node Pod Endpoint Namespace 服務帳號(ServiceAccount)資源定額(ResourceQuota)等的管理。出現故障時候會嘗試自動修復,達到預期工做狀態。
通常咱們把資源對象 Replication Controller 簡寫爲RC 是爲了區別於Controller Manager 中的Replication Controller【副本控制器】,副本控制器是經過管理資源對象RC來達到動態調控Pod的
副本控制器Replication Controller的做用:
Node節點在啓動時候,會同kubelet 主動向API Server彙報節點信息,API Server將節點信息存儲在etcd中,Node Controller經過API Server獲取到Node的相關信息對Node節點進行管理和監控。
節點狀態包括:就緒 未就緒 未知三種狀態
資源配額管理,確保指定資源對象在任一時刻不會超量佔用系統物理資源。支持如下維度的系統資源配額管理
用戶經過API server 設置的Namespace會保存在etcd中,Namespace Controller會定時的獲取namespace狀態,根據所得狀態對不一樣的namespace進行相應的刪除,釋放namespace下對應的物理資源。
Endpoints 表示一個svc對應的全部的pod的訪問地址,Endpoint Controller是負責維護和生成全部endpoint對象的控制器。
每一個Node對應的kube-proxy獲取到svc對應的Endpoints來實現svc的負載均衡。
Scheduler 主要是接受controller Manager建立的pod爲Pod選定目標Node,調度到合適的Node後,由Node中的kubelet負責接下來的管理運維。
過程當中涉及三個對象 待調度的Pod列表,空閒的Node列表,調度算法和策略。
也就是根據調度算法和策略爲待調度的每一個Pod從空閒的Node中選擇合適的。 隨後kubelet經過API Server監聽到Pod的調度事件,獲取對應的Pod清單,下載Image鏡像,並啓動容器。
1【預選調度】遍歷全部的Node節點,選出合適的Node
2優選策略肯定最優節點
每一個Node節點中都會啓動一個Kubelet,該進程用於處理Master節點下發到本節點的任務,管理Pod以及Pod中的容器,每一個Kubelet都會向API Server註冊自身信息,按期和Master節點彙報Node節點資源使用狀況。
使用2類探針LivenessProbe 和ReadinessProbe
使用cAdvisor
總結:kubelet 做爲鏈接K8s Master節點機和Node機器的橋樑,管理運行在Node機器上的Pod和容器,同時從cAdvisor中獲取容器使用統計信息,而後經過API Server上報資源使用信息。
SVC是對一組提供相同服務Pod的抽象,會根據訪問策略來訪問這一組Pod。在每個Node節點上都存在一個Kube-proxy,能夠在任意Node上發起對SVC的訪問請求。
SVC的ClusterIp和NodePort等概念是kube-proxy服務經過IPtables的NAT轉換實現重定向到本地端口,再均衡到後端的Pod
待補充
k8s+docker 網絡原理經常涉及到如下問題
IP-per-Pod:每一個Pod都有本身獨立的IP,不管是否處於同一個Node節點,Pod直接均可以經過IP相互訪問。同時Pod內的容器共享一個網絡堆棧【=網絡命名空間 包括IP地址,網絡設備,配置等】按照這個網絡模型抽象出來的一個Pod對應一個IP也叫IP-per-Pod
Pod內部應用程序看到的本身的IP+port和pod外部的應用程序看到的IP+port是一致的,他們都是Pod實際分配的ip地址,從docker0上分配的。這樣能夠不用NAT來進行轉換,設計的原則是爲了兼容之前的應用 。
K8S對網絡的要求:
因爲網絡命名空間以及Veth設備對是創建在同一個linux內核的基礎上。因此Docker的跨主機通信處理的不夠友好。
--net= host
指定--net = container: Id_or_NAME
指定--net= none
指定--net = bridge
指定bridge模式 : 也是docker默認的網絡模型,在這個模型下Docker第一次啓動會建立一個新的網橋 大名鼎鼎的docker0
,每一個容器獨享一個網絡命名空間,且每個容器具備一個Veth設備對,一端鏈接容器設備eth0一端鏈接網橋,docker0。以下圖:
同一個Pod內的容器共享同一個網絡命名空間,能夠直接使用Localhost進行通信,不一樣Pod之間容器的通信能夠理解爲Pod到Pod OR Pod到SVC之間的通信
能夠分爲同一個Node內Pod之間的通信&不一樣Node內Pod之間的通信
同一Node中Pod的默認路由都是docker0的地址,因爲它們關聯在同一個docker0網橋上,地址網段相同,能夠直接進行通信。
docker0網段和宿主機的網卡是2個不一樣的IP段,Pod地址和docker0處於同一網段。因此爲了使不一樣Node之間的Pod能夠通信,須要將PodIP和所在Node的IP進行關聯且保證惟一性。
SVC是對一組Pod服務的抽象,至關於一組服務的負載均衡。且對外暴露統一的clusterIP,因此Pod到SVC之間的通信能夠理解爲Pod到Pod之間的通信
集羣外和內部組件之間通信,將Pod OR SVC端口綁定到物理機端口便可。