在這張系統架構圖中,咱們把服務分爲運行在工做節點上的服務和組成集羣級別控制板的服務。
Kubernetes節點有運行應用容器必備的服務,而這些都是受Master的控制。
每次個節點上固然都要運行Docker。Docker來負責全部具體的映像下載和容器運行。
Kubernetes主要由如下幾個核心組件組成:前端
1. API server[資源操做入口]:是k8s集羣的前端接口,各類各樣客戶端工具以及k8s的其餘組件能夠經過它管理k8s集羣的各類資源。它提供了HTTP/HTTPS RESTful API,即K8S API。node
- 提供了資源對象的惟一操做入口,其餘全部組件都必須經過它提供的API來操做資源數據,只有API Server與存儲通訊,其餘模塊經過API Server訪問集羣狀態。
第一,是爲了保證集羣狀態訪問的安全。web
第二,是爲了隔離集羣狀態訪問的方式和後端存儲實現的方式:API Server是狀態訪問的方式,不會由於後端存儲技術etcd的改變而改變。算法
- 做爲kubernetes系統的入口,封裝了核心對象的增刪改查操做,以RESTFul接口方式提供給外部客戶和內部組件調用。對相關的資源數據「全量查詢」+「變化監聽」,實時完成相關的業務功能。
2. Scheduler[集羣分發調度器]:負責決定將Pod放在哪一個Node上運行。在調度時,會充分考慮集羣的拓撲結構,當前各個節點的負載狀況,以及應對高可用、性能、數據親和性和需求。docker
1.Scheduler收集和分析當前Kubernetes集羣中全部Minion節點的資源(內存、CPU)負載狀況,而後依此分發新建的Pod到Kubernetes集羣中可用的節點。數據庫
2.實時監測Kubernetes集羣中未分發和已分發的全部運行的Pod。後端
3.Scheduler也監測Minion節點信息,因爲會頻繁查找Minion節點,Scheduler會緩存一份最新的信息在本地。centos
4.最後,Scheduler在分發Pod到指定的Minion節點後,會把Pod相關的信息Binding寫回API Server。緩存
4. Controller Manager[內部管理控制中心]:負責管理集羣的各類資源,保證資源處於預期的狀態。它由多種Controller組成,包括Replication Controller、Endpoints Controller、Namespace Controller、Serviceaccounts Controller等。安全
實現集羣故障檢測和恢復的自動化工做,負責執行各類控制器,主要有:
1.endpoint-controller:按期關聯service和pod(關聯信息由endpoint對象維護),保證service到pod的映射老是最新的。
2.replication-controller:按期關聯replicationController和pod,保證replicationController定義的複製數量與實際運行pod的數量老是一致的。
5. Etcd:負責保存k8s集羣的配置信息和各類資源的狀態信息。當數據發生變化時,etcd會快速的通知k8s相關組件。[(第三方組件)它有可替換方案。Consul、zookeeper]()
6. Pod: k8s集羣的最小組成單位。一個Pod內,能夠運行一個或多個容器。大多數狀況下,一個Pod內只有一個Container容器。
7. Flanner:是k8s集羣網絡,能夠保證Pod的跨主機通訊。也有替換方案。
[root@master ~]# kubectl get pod --all-namespaces //查看pod信息
[root@master ~]# kubectl get pod --all-namespaces -o wide //顯示pod的節點信息
Kubelet[節點上的Pod管家]:它是Node的agent(代理),當Scheduler肯定某 個Node上運行Pod以後,會將Pod的具體配置信息發送給該節點的kubelet,kubelet會根據這些信息建立和運行容器,並向Master報告運行狀態。
- 負責Node節點上pod的建立、修改、監控、刪除等全生命週期的管理
- 定時上報本Node的狀態信息給API Server。
- kubelet是Master API Server和Minion之間的橋樑,接收Master API Server分配給它的commands和work,與持久性鍵值存儲etcd、file、server和http進行交互,讀取配置信息。
- 具體的工做以下:
設置容器的環境變量、給容器綁定Volume、給容器綁定Port、根據指定的Pod運行一個單一容器、給指定的Pod建立network 容器。
同步Pod的狀態、同步Pod的狀態、從cAdvisor獲取Container info、 pod info、 root info、 machine info。
在容器中運行命令、殺死容器、刪除Pod的全部容器。
kube-proxy[負載均衡、路由轉發]:負責將訪問service的TCP/UDP數據流轉發到後端的容器。若是有多個
副本,kube-proxy會實現負載均衡。
- Proxy是爲了解決外部網絡可以訪問跨機器集羣中容器提供的應用服務而設計的,運行在每一個Node上。Proxy提供TCP/UDP sockets的proxy,每建立一種Service,Proxy主要從etcd獲取Services和Endpoints的配置信息(也能夠從file獲取),而後根據配置信息在Minion上啓動一個Proxy的進程並監聽相應的服務端口,當外部請求發生時,Proxy會根據Load Balancer將請求分發到後端正確的容器處理。
- Proxy不但解決了同一主宿機相同服務端口衝突的問題,還提供了Service轉發服務端口對外提供服務的能力,Proxy後端使用了隨機、輪循負載均衡算法。
kube-dns負責爲整個集羣提供DNS服務
Ingress Controller爲服務提供外網入口
Heapster提供資源監控
Dashboard提供GUI
Federation提供跨可用區的集羣
Fluentd-elasticsearch提供集羣日誌採集、存儲與查詢
Kubernetes設計理念和功能其實就是一個相似Linux的分層架構,以下圖所示。
核心層:Kubernetes最核心的功能,對外提供API構建高層的應用,對內提供插件式應用執行環境
應用層:部署(無狀態應用、有狀態應用、批處理任務、集羣應用等)和路由(服務發現、DNS解析等)
管理層:系統度量(如基礎設施、容器和網絡的度量),自動化(如自動擴展、動態Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
接口層:kubectl命令行工具、客戶端SDK以及集羣聯邦
生態系統:在接口層之上的龐大容器集羣管理調度的生態系統,能夠劃分爲兩個範疇
Kubernetes外部:日誌、監控、配置管理、CI、CD、Workflow、FaaS、OTS應用、ChatOps等
Kubernetes內部:CRI、CNI、CVI、鏡像倉庫、Cloud Provider、集羣自身的配置和管理等
下面經過運行一個容器應用的過程,來一塊兒理解一下K8s組件是如何協做的。
開發者開發一個應用後,打包Docker鏡像,上傳到Docker registry;而後編寫一個yaml部署描述文件,以描述應用的結構和資源需求。開發者經過kubectl(或其它應用),將部署描述文件提交到API server,API server將部署需求更新到etcd。etcd在K8s管理結點中的做用至關於數據庫,其它組件提交到API server的數據都存儲於etcd。API server很是輕量,並不會直接去建立或管理Pod等資源,在多數場景下甚至不會去主動調用其它的K8s組件發出指令。其它組件經過創建和API server的長鏈接,監視關心的對象,監視到變化後,執行所負責的操做。
繼續咱們的啓動應用之旅,如圖所示,Controller Manager中的控制器監視到新的部署描述後,根據部署描述,建立ReplicaSet、Pod等資源。Scheduler監視到新的Pod資源後,結合集羣的資源狀況,選定一或多個工做結點運行Pod。工做結點上的Kubelet監視到有Pod被計劃在本身的結點後,向Docker等Container runtime發出啓動容器的指令,Docker engineer將按照指令從Docker registy拉取鏡像,而後啓動並運行容器。
經過以前的介紹,咱們看到K8s能夠在多個工做結點上啓動並管理容器,下面來學習一下,如何實現管理結點的高可用部署。
上圖的K8s高可用部署中有3個管理結點。etcd自身是一個分佈式數據存儲系統,按照其多實例部署方案,結點只需在啓動時知道其它結點的IP和端口號便可組成高可用環境。和一般的應用服務器同樣,API Server是無狀態的,能夠運行任意多個實例,且彼此之間無需互相知道。爲了能使kubectl等客戶端和Kubelet等組件鏈接到健康的API Server、減輕單臺API Server的壓力,需使用基礎架構提供的負載均衡器做爲多個API Server實例的入口。如上圖的部署方法,每一個主結點上都運行了一個etcd實例,這樣API Server只需鏈接本地的etcd實例便可,無需再使用負載均衡器做爲etcd的入口。
Controller Manager和Scheduler須要修改K8s集羣,同時修改時可能引起併發問題。假設兩個ReplicaSet Controller同時監視到需建立一個Pod,而後同時進行建立操做,就會建立出兩個Pod。K8s爲了不這個問題,一組此類組件的實例將選舉出一個leader,僅有leader處於活動狀態,其它實例處於待命狀態。Controller Manager和Scheduler也能夠獨立於API server部署,經過負載均衡器鏈接到多個API server實例。
分析各個組件的做用以及架構工做流程:
1) kubectl發送部署 請求到API server
2) APIserver通知Controller Manager建立一個Deployment資源。
3) Scheduler執行調度任務,將兩個副本Pod分發到node01和node02. 上。
4) node01和node02, 上的kubelet在各自節點上建立並運行Pod。補充
1.應用的配置和當前的狀態信息保存在etcd中,執行kubectl get pod時API server會從etcd中讀取這些數據。
2.flannel會爲每一個Pod分配一個IP。 但此時沒有建立Service資源,目前kube-proxy尚未參與進來。
[root@master ~]# kubectl run test-web --image=httpd --replicas=2 //建立一個deployment資源對象。
運行完成以後,若是有鏡像可直接開啓,沒有的話須要等待一下子,node節點要在docker hup上下載
[root@master ~]# kubectl get deployments.或 kubectl get deploy
[root@master ~]# kubectl get pod
[root@master ~]# kubectl get pod -o wide //顯示pod的節點信息
若是,node節點沒有運行test-web服務,須要在節點上重啓一下<systemctl restart kubelet>
[root@master ~]# kubectl delete pod test-web-5b56bdff65-2njqf
[root@master ~]# kubectl get pod -o wide
如今發現容器還存在,由於控制器會自動發現,一旦與以前執行的命令有偏差,他會自動補全。
參考:
http://www.javashuo.com/article/p-efycsmya-ku.html
https://www.jianshu.com/p/18edac81c718