云原生初探
文章目錄
- 什么是云原生?
- 第二講 容器的基本概念
- 什么是容器?
- 容器運(yùn)行時(shí)的生命周期
- 容器項(xiàng)目的架構(gòu)
- 容器和VM的差異
- 第三講 Kubernetes核心概念
- 什么是Kubernetes
- Kubernetes架構(gòu)
- Kubernetes核心概念和API
- 第四講 理解Pod和容器設(shè)計(jì)模式
- 為什么Pod必須是原子調(diào)度單位?
- Pod實(shí)現(xiàn)機(jī)制
什么是云原生?
不同企業(yè)對云原生有不同的解釋,最為廣泛接受的是:云原生是一類技術(shù)的統(tǒng)稱 或者 是一套指導(dǎo)進(jìn)行軟件架構(gòu)設(shè)計(jì)的思想,通過云原生技術(shù),我們可以構(gòu)建出更易于彈性擴(kuò)展的應(yīng)用程序。它包含了當(dāng)前業(yè)界的一些熱門的技術(shù),比如:容器、微服務(wù)、DevOps等。
第二講 容器的基本概念
什么是容器?
容器是一個(gè)視圖隔離(能夠看見部分進(jìn)程等 namespace)、資源可限制(限制資源使用率 cgroup)、獨(dú)立文件系統(tǒng)(chroot)。
容器運(yùn)行時(shí)所需要的所有文件集合稱為容器鏡像。通常采用Dockerfile構(gòu)建鏡像。
容器運(yùn)行時(shí)的生命周期
-
單進(jìn)程模型
啟動(dòng)容器時(shí),會選擇相應(yīng)的文件系統(tǒng)(鏡像來提供),以及指定相應(yīng)的運(yùn)行程序,那么這個(gè)運(yùn)行程序我們稱為init進(jìn)程。在容器運(yùn)行過程中,我們會發(fā)現(xiàn),當(dāng)這個(gè)init進(jìn)程啟動(dòng)了,那么這個(gè)容器也啟動(dòng)了,當(dāng)這個(gè)init進(jìn)程退出了,那么這個(gè)容器也就隨之退出了。所以,init進(jìn)程的生命周期與容器生命周期一致。
-
數(shù)據(jù)持久化
數(shù)據(jù)卷volume,獨(dú)立于容器的生命周期;
容器項(xiàng)目的架構(gòu)
-
moby容器引擎架構(gòu)
moby daemon會提供關(guān)于容器、鏡像、網(wǎng)絡(luò)以及volume的管理。它依賴的最重要的組件是containerd(容器運(yùn)行時(shí)管理引擎),獨(dú)立于moby daemon,containerd-shim管理容器生命周期,可被containerd動(dòng)態(tài)接管。
容器和VM的差異
VM是利用Hypervisor虛擬化技術(shù)來模擬硬件資源,需要Guest OS(裝在VM上的系統(tǒng)),可以提供更好的隔離效果。但是,我們需要將一部分的計(jì)算資源交給虛擬化,導(dǎo)致很難充分利用計(jì)算資源,并且每個(gè)Guest OS需要占用大量的磁盤空間。
容器無需Guest OS,只需要一個(gè)獨(dú)立的文件系統(tǒng)。所有的隔離級別都是進(jìn)程級別的;啟動(dòng)時(shí)間更快;但隔離效果較弱。
第三講 Kubernetes核心概念
什么是Kubernetes
自動(dòng)化的容器編排平臺
核心功能:
- 服務(wù)發(fā)現(xiàn)與負(fù)載均衡;
- 容器自動(dòng)裝箱(把一個(gè)容器放到某個(gè)集群的某個(gè)機(jī)器上);
- 存儲編排;
- 自動(dòng)容器恢復(fù)(節(jié)點(diǎn)健康檢查,將有問題的節(jié)點(diǎn)上的容器遷移到其他節(jié)點(diǎn)上去);
- 自動(dòng)發(fā)布與回滾;
- 配置與密文管理;
- 批量執(zhí)行;
- 水平伸縮(業(yè)務(wù)負(fù)載檢查,可以對負(fù)載過高的服務(wù)進(jìn)行擴(kuò)容);
Kubernetes架構(gòu)
- API Server:消息傳送;
- Controller:完成對集群狀態(tài)的管理;
- Scheduler:調(diào)度;
- etcd:分布式存儲,API Server中所需要的信息都放在etcd中;
用戶可以通過ui或cli向kubernetes提供一個(gè)pod進(jìn)行部署,API Server會將相關(guān)信息存儲到etcd中,Scheduler會通過API Server的watch或者notification機(jī)制得到這個(gè)信息(有一個(gè)pod需要被調(diào)度),Scheduler會根據(jù)它的資源狀態(tài)進(jìn)行一次調(diào)度決策,在完成這次調(diào)度之后,Scheduler會向API Server通知這個(gè)pob需要被調(diào)度到某個(gè)節(jié)點(diǎn)上,API Server會將調(diào)度的結(jié)果再次寫入到etcd中。然后,API Server會通知對應(yīng)的節(jié)點(diǎn)進(jìn)行pob的啟動(dòng)和執(zhí)行。相應(yīng)節(jié)點(diǎn)的kubelet會得到這個(gè)通知,調(diào)用Container runtime來配置、啟動(dòng)這個(gè)容器的運(yùn)行環(huán)境,去調(diào)用Storage Plugin來配置存儲,調(diào)用Network Plugin來配置網(wǎng)絡(luò)。
Kubernetes核心概念和API
-
Pod
- 最小的調(diào)度以及資源單位;
- 由一個(gè)或者多個(gè)容器組成;
- 在Pob中可以定義容器運(yùn)行的方式(Command、環(huán)境變量等);
- 提供給容器共享的運(yùn)行環(huán)境(網(wǎng)絡(luò)、進(jìn)程空間,pob與pob之間是有隔離的);
-
Volume
- 用來聲明容器的訪問目錄(Pob中的容器可以訪問的文件目錄);
- 一個(gè)volume可以被掛載在一個(gè)Pob中的一個(gè)或多個(gè)容器的指定路徑下;
- volume是一個(gè)抽象的概念,它可以支持多種后端的存儲(分布式、云存儲…);
-
Deployment
-
定義一組Pob的副本數(shù)目、版本等;
-
通過Colltroller維持Pob的數(shù)目,Controller可以自動(dòng)恢復(fù)失敗的Pod;Deployment中Pob的數(shù)目是通過Controller來指定的,當(dāng)一個(gè)Pod失敗時(shí),Controller可以檢測到,來生成新的Pob。
-
可以通過Controller以指定的策略控制版本:滾動(dòng)升級、重新生成、回滾;
-
Service
- 提供訪問一個(gè)或多個(gè)Pod實(shí)現(xiàn)的穩(wěn)定訪問地址(負(fù)載均衡);
-
Namespace
- 一個(gè)集群內(nèi)部的邏輯隔離機(jī)制(鑒權(quán)、資源調(diào)度);
- 每個(gè)資源都屬于一個(gè)Namespace;
- 同一個(gè)Namespace中的資源命名唯一;
第四講 理解Pod和容器設(shè)計(jì)模式
由四個(gè)進(jìn)程共同組成的應(yīng)用helloworld,在kubernates中會被定義為擁有四個(gè)容器的Pod。Pob只是一個(gè)邏輯單位,真正啟來的實(shí)際上是四個(gè)容器。
為什么Pod必須是原子調(diào)度單位?
舉例:兩個(gè)緊密協(xié)作(需要部署在一臺機(jī)器上)的容器App和LogCollector;
內(nèi)存要求:App—1G、LogCollector:0.5G;
當(dāng)前可用內(nèi)存:Node_A:1.25G、Node_B:2G;
如果App先被調(diào)度到了Node_A上,那么就會導(dǎo)致LogCollector調(diào)度失敗。
這就是Task co-scheduling問題:
- Mesos的解決辦法:資源囤積;所有設(shè)置了Affinity約束的任務(wù)都到達(dá)時(shí),才開始同一進(jìn)行調(diào)度;帶來的問題是:調(diào)度效率損失、死鎖;
- Google Omega:樂觀調(diào)度;不管沖突,出現(xiàn)沖突之后回滾;
- Kubernetes:Pod;不存在上面的問題;App和LogCollector屬于一個(gè)Pob,一起被調(diào)度;
親密關(guān)系:兩個(gè)應(yīng)用需要運(yùn)行在同一臺宿主機(jī)上(Pod之間);通過調(diào)度解決;
超親密關(guān)系:會發(fā)生直接的文件交換;使用localhost或者socket文件進(jìn)行本地通信;會發(fā)生非常頻繁的RPC調(diào)用;會共享某些Linux Namespace(比如:一個(gè)容器要加入另一個(gè)容器的Network Namespace,就可以看到另一個(gè)容器的網(wǎng)絡(luò)設(shè)備以及網(wǎng)絡(luò)信息);通過Pod解決;
Pod實(shí)現(xiàn)機(jī)制
容器之間原本是被Linux Namespace和cgroups隔離開的,那么如何讓一個(gè)Pod里的多個(gè)容器之間最高效的共享某些資源和數(shù)據(jù)?
-
共享網(wǎng)絡(luò)
在每一個(gè)Pod里會啟動(dòng)一個(gè)Infra container小容器來共享整個(gè)Pod的Network Namespace。Pob內(nèi)部容器直接使用localhost進(jìn)行通信;每個(gè)容器看到的網(wǎng)絡(luò)設(shè)備跟Infra容器看到的一樣;一個(gè)Pod只有一個(gè)IP地址,也就是這個(gè)Pod的Network Namespace對應(yīng)的IP地址;所有網(wǎng)絡(luò)資源都是一個(gè)Pod一份,并且被該P(yáng)od中的所有容器共享;整個(gè)Pod的生命周期跟Infra容器一致,而與內(nèi)部的其他容器無關(guān);
-
共享存儲
掛載到同一個(gè)volume;
總結(jié)