之前了解了k8s到底是什么,接下來看看k8s的組成。
一、Kubernetes架構
學習k8s,最終目的是為了部署應用,部署一個完整的k8s, 就要知道k8s的組成。k8s主要包含兩大部分: 中間包含三個綠色包的是master服務器. 下面是node節點.
1、Master節點
master中有哪些東西?
1)api server
api server是所有服務訪問的統一入口(所有請求的統一的入口).就是一起訪問的入口. 從上圖可以看出. Master中scheduler需要和api server交互, rc要和api server交互, kubectl(客戶端)也要和api sever交互, web UI也要和api server交互, etcd也要和api server交互. apiserver是非常繁忙的.
api server采用的是無狀態http請求,所以,他不會記錄任何數據,所有數據都存儲在etcd上。
Kubernetes API 服務器的主要實現是 kube-apiserver。 kube-apiserver 設計上考慮了水平伸縮,也就是說,我們可以通過部署多個實例進行伸縮。 你可以運行 kube-apiserver 的多個實例,並在這些實例之間平衡流量。
2)scheduler
scheduler是任務調度器, 負責調度任務, 選擇合適的節點來執行任務. 當用戶下達資源請求的時候,任務調度器會把任務分配給后端的多個node節點上,要基於一定的原則,公平的,快速的分發。也就是說,保證每個節點都有事做,不要浪費資源,做到資源利用最大化。所以,scheduler調度區非常關鍵,他是保證整個集群資源利用高不高的核心組件。
舉個例子,一個任務來了, 要部署一個應用,到底應該部署在哪個節點上呢? 這個過程就是通過scheduler進行任務調度的。有的機器繁忙,有的機器空閑,scheduler會找一台空閑的機器進行部署。通過scheduler進行任務調度分發至不同的node.
scheduler會將任務交給api server, 由api server將任務寫入到etcd, 也就是說scheduler不會直接和etcd交互。
3)controller-manager
controller-manager: 控制器, 處理集群中常規后台任務,一個資源對應一個控制器。
舉例來說,有一個訂單服務,我們要部署這個服務,首先是交給任務調度器,任務調度器調用api server,將信息保存到etcd,etcd會創建一個controller-manager來專門管理這個訂單服務。通常來說,一個資源對應一個控制器。
4)etcd:
etcd是鍵值對數據庫, 存儲K8s集群的所有重要信息(持久化). 在Kubernetes集群中起到的了持久化的作用. 對於etcd有兩點說明:
- etcd官方將其定位為一個可信賴的分布式****鍵值存儲服務, 它能夠為整個分布式集群存儲一些關鍵數據, 協助分布式集群的正常運轉.
- etcd的版本

etcd現在有兩個版本, v2和v3版本, v2版本將數據保存到內存, v3版本將數據保存到數據庫. 正常我們都選擇使用v3版本, 但Kubernetes v1.11版本之前使用的是v2版本.
- etcd內部架構圖
-
http Server: 這里采用的是使用http進行構建的c/s服務, k8s也是采用的http協議進行c/s服務的開發. 為什么要這么做呢? 因為http天生支持一系列的操作. 例如: get ,post, put, delete, 授權認證等. 所以, 沒有必要再去采用標准的tcp協議. 開發一系列的認證流程, 所以, 直接采用http協議即可.
-
Raft:共識算法,或者叫最終一致算法。比如:有3台etcd機器在運行的過程中,突然停了,那么3台etcd中的配置可能是不一樣的,但是,一旦運行起來,經過一段時間,最終會達到一致。每一個Raft集群都包含多個服務器,在任意時刻,每一台服務器只可能處於Leader(主節點)、Follower(跟隨者)、Candidater(競選者)三種狀態中的一種。在處於正常狀態(可訪問)時,集群中只會存在一個Leader,其余的服務器都是Follower。
是讀寫的信息, 所有的讀寫信息都被存在Raft里面, 而且, 為了防止這些信息出現損壞, 他還有一個WAL預寫日志
-
WAL: 預寫日志, 吸入到數據庫之前,先保存到日志里。如果要對數據進行更改, 那么先寫入一條日志, 然后定時的對日志進行完整的備份. 也就是完整+臨時. 比如: 我先備份一個大版本, 備份以后, 還會有1個子版本, 兩個子版本....., 然后將這些版本再次進行一個完整備份,把它變成一個大版本. 這樣做的好處, 我們不能始終進行完整備份, 因為消耗的數據量太大. 為什么還要在一定時間內進行完整的備份呢?防止增量備份太多, 還原的時候太費事. 並且, Raft還會實時的把這些數據和日志存入到本地磁盤進行持久化.
-
Store: 試試把WAL中的日志和數據, 寫入磁盤進行持久化.
5)kubectl
命令行管理工具。這個工具我們可以安裝在任何節點上。通常,我們將其安裝在master節點上。可以安裝在安卓手機上,蘋果手機上,windows電腦上,只要能夠通過網絡連接到api server,就能下發請求。
2、Node節點
從圖中可以看出, Node節點包含三個組件 ,kubelet, kube proxy, 以及container. 也就是說我們在node節點需要安裝三個軟件: kebelet, kebu proxy, docker

1)kubelet的作用:
pod中安裝的是docker容器,外層環境是k8s,docker和k8s能直接交互么?不能,一個是外國人,只會說英語,一個是中國人,只會說漢語。那如何讓外國人和中國人交流呢?翻譯唄。kubelet的作用就是連接k8s和docker的。kubelet監聽api server,api server下發命令以后,kubelet要去調用docker,去執行指令,比如容器的創建。
直接跟容器交互, 實現容器的生命周期管理.他會和CRI, C是容器, R是runtime, I是interface. CRI就是docker的操作形式. kubelet會和docker交互, 創建需要的容器. kubelet會維持Pod的生命周期.
2)kube proxy的作用:
kube proxy監聽者api server,api server發出請求以后,會調用linux的內核接口,叫做net link接口,這個接口允許我們通過接口調用的方式實現IPVS的創建,實現netfire的管控,就是IPVS和防火牆的管控。負載均衡和數據的轉發都是基於kube proxy組件實現的。
負責寫入規則至IPTABLES, IPVS實現服務映射訪問. 之前說過svc, 可以進行負載操作, 負責的操作就是通過kube proxy完成的. 怎么實現Pod與Pod之間的訪問, 以及負載均衡. 默認操作是操作防火牆, 去實現Pod的映射. 新版本還支持IPVS.
3、其他重要的插件
1)Web UI
Dashboard是 Kubernetes 集群的通用的、基於 Web 的用戶界面。 它使用戶可以管理集群中運行的應用程序以及集群本身並進行故障排除。
2) COREDNS
可以為集群中的SVC創建一個域名IP對應的關系解析. 也就是說,我們在集群中訪問其他Pod的時候, 完全不需要通過Pod的ip地址, 通過CoreDns給他生成的域名去實現訪問. 他是集群中的重要重要組件, 也是實現負載均衡的其中一項功能.
3)DASHBOARD
給K8S集群提供一個 B/S結構訪問體系.
4)Ingress Controller
官方只為我們實現了四層代理. Ingress可以實現七層代理, 也就是可以根據組件名和域名進行負載均衡.
5)Federation
提供一個可以跨集群中心多K8s統一集群管理功能.
6)Prometheus(普羅米修斯)
提供K8S集群的監控能力.
7)ELK
提供k8s集群日志統一接入平台
二、K8S和docker的關系
為什么會說k8s和docker的關系呢?這還要源於k8s發布的一則消息,在后續版本將不再增加墊片這個組件。導致很多人覺得docker不行了,很可能會被k8s遺棄,為什么這個墊片會有這么大的影響呢?這就要從CRI和O-CRI說起了。
先來看看容器是如何創建的?
kubelet監聽了server api,有任何的變化都會下發命令給docker,然后docker操作容器。那么,kubelet調用docker的時候,是使用命令還是調用接口呢?
肯定是直接調用接口。因為調用命令最終也是去執行接口,中間還轉一步,效率太低了。
但是,kubelet能直接調用docker接口么?
我們知道docker采用的是CRI容器運行時接口,
而k8s是google的產品,現在是CNCF雲容器基金會的產品,這是一個開源鏡像,k8s會直接對接到CRI這樣一個私有協議么?我是公共使用的,所以肯定不會對接到私有協議接口。那么,我會對接到O-CRI接口,這時一個共有協議接口。問題來了,docker是CRI私有協議接口,k8s是O-CRI共有協議接口,對接不過去啊。所以,怎么辦?再加一層轉換,這層轉換的作用是承上啟下,上面承的是O-CRI,下面承的是CRI。這個轉換是在kubectl實現的。這一層被叫做墊片。承上啟下用的。
最開始,Docker的名氣要比k8s大的多得多,所以,k8s就承接了墊片的任務。而如今,k8s的名氣已經很大了,它不再需要依賴於docker,於是他要去掉墊片。並且發了公告。
那么docker是不是就完蛋了,k8s沒有墊片做轉換了,就不能調用docker接口了。docker也很機智,隨即發布消息,他會增加墊片功能。這樣k8s依然可以調用docker容器。但是,我們要知道,docker就重了,k8s減負了,k8s可以兼容任何容器,現在市面上有好幾款容器,他不是飛docker不可的了。
