隨著各種云服務(wù)的發(fā)展,越來(lái)越多的服務(wù)運(yùn)行在以 Docker 為代表的容器之內(nèi)
容器化技術(shù)簡(jiǎn)介
容器技術(shù)是一種更加輕量級(jí)的操作系統(tǒng)隔離方案
可以將應(yīng)用程序及其運(yùn)行依賴環(huán)境打包到鏡像中
通過(guò)容器引擎進(jìn)行調(diào)度嗅虏,并且提供進(jìn)程隔離和資源限制的運(yùn)行環(huán)境
容器化技術(shù)
在容器技術(shù)中洛姑,最具代表性且應(yīng)用最廣泛的是 Docker 技術(shù)
Docker 是一個(gè)開(kāi)源的應(yīng)用容器引擎
可以打包應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到服務(wù)器上
Docker 容器基于鏡像運(yùn)行皮服,可部署在物理機(jī)或虛擬機(jī)上
通過(guò)容器引擎與容器編排調(diào)度平臺(tái)實(shí)現(xiàn)容器化應(yīng)用的聲明周期管理
使用容器化技術(shù)有哪些好處楞艾?
Docker 只包含應(yīng)用程序以及依賴庫(kù)
處于一個(gè)隔離的環(huán)境中
這使得 Docker 更加輕量高效
兩種虛擬化技術(shù)的對(duì)比
虛擬機(jī)是一個(gè)運(yùn)行在宿主機(jī)之上的完整 操作系統(tǒng)
虛擬機(jī)運(yùn)行自身操作系統(tǒng)會(huì)占用較多的 CPU,內(nèi)存龄广,硬盤資源
虛擬化技術(shù)為用戶提供了一個(gè)完整的虛擬機(jī)硫眯,包括操作系統(tǒng)在內(nèi)
容器化技術(shù)為應(yīng)用程序提供了隔離的運(yùn)行空間,容器之間共享同一個(gè)上層操作系統(tǒng)內(nèi)核
虛擬化技術(shù)有更佳的隔離性和安全性蜀细,但更新和升級(jí)困難
容器化具有快速擴(kuò)展舟铜,靈活性和易用性等優(yōu)勢(shì),但隔離性較差奠衔,安全性相對(duì)較低
實(shí)際部署一般是把兩種技術(shù)結(jié)合起來(lái)谆刨,比如一個(gè)虛擬機(jī)中運(yùn)行多個(gè)容器
容器化的原理
容器技術(shù)的核心是如何實(shí)現(xiàn)容器內(nèi)資源的限制,以及不同容器之間的隔離
Namespace
Namespace 的目的是
通過(guò)抽象方法使得 Namespace 中的進(jìn)程看起來(lái)?yè)碛兴鼈冏约旱母綦x的全局系統(tǒng)資源實(shí)例
Linux 內(nèi)核實(shí)現(xiàn)了六種 Namespace :
- Mount namespace (隔離文件系統(tǒng))
- UTS namespaces (定義 hostname 和 domainame)
- IPC namespaces (特定的進(jìn)程間通信資源)
- PID namespaces (獨(dú)立進(jìn)程ID結(jié)構(gòu))
- Network namespaces (獨(dú)立網(wǎng)絡(luò)設(shè)備)
- User namespaces (用戶和組ID空間)
Cgroups
CGroups (Control Groups) 的功能主要是限制归斤,記錄痊夭,隔離進(jìn)程所使用的物理資源
比如 CPU,Memory脏里,IO她我,Network 等
CGroups 在接收到調(diào)用時(shí),會(huì)給指定的進(jìn)程掛上鉤子迫横,這個(gè)鉤子會(huì)在資源被使用的時(shí)候觸發(fā)
觸發(fā)時(shí)會(huì)根據(jù)資源的類別番舆,比如 CPU,Memory矾踱,IO 等恨狈,然后使用對(duì)應(yīng)的方法進(jìn)行限制
CGroups 中有一個(gè)術(shù)語(yǔ)叫做 Subsystem 子系統(tǒng),也就是一個(gè)資源調(diào)度控制器
CPU Subsystem 負(fù)責(zé) CPU 的時(shí)間分配呛讲,Memory Subsystem 負(fù)責(zé) Memory 的使用量等
Docker 啟動(dòng)一個(gè)容器后禾怠,會(huì)在 /sys/fs/cgroups 目錄下生成帶有此容器的 ID 的文件夾
微服務(wù)如何適配容器化
微服務(wù)的設(shè)計(jì)思想是對(duì)系統(tǒng)功能進(jìn)行解耦返奉,拆分為單獨(dú)的服務(wù),可以獨(dú)立運(yùn)行
應(yīng)用容器技術(shù)可以對(duì)服務(wù)進(jìn)行快速水平擴(kuò)展吗氏,從而到達(dá)彈性部署業(yè)務(wù)的能力
微服務(wù)結(jié)合 Docker 部署芽偏,更加方便微服務(wù)架構(gòu)運(yùn)維部署落地
以 Java 服務(wù)為例,容器的資源限制通過(guò) CGroup 來(lái)實(shí)現(xiàn)
而容器內(nèi)部進(jìn)程如果不感知 CGroup 的限制弦讽,就進(jìn)行內(nèi)存污尉,CPU 分配,則可能會(huì)導(dǎo)致資源沖突的問(wèn)題
Java8 之前的版本無(wú)法跟 Docker 很好的配合
JVM 通過(guò)容器獲取的可用內(nèi)存和 CPU 數(shù)量并不是Docker 允許使用的可用內(nèi)存和 CPU 數(shù)量
Runtime.getRuntime().availaleProcessors()
在 1.8 版本更早的實(shí)現(xiàn)坦袍,在容器內(nèi)獲取的上層物理機(jī)或者虛擬機(jī)的 CPU 核心數(shù)
另一個(gè)影響體現(xiàn)在 GC 中十厢,JVM 垃圾對(duì)象回收對(duì) Java 程序執(zhí)行性能有一定的影響
默認(rèn)的 JVM 使用公式來(lái)計(jì)算并行 GC 的線程數(shù)
ParallelGCThreads = (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8)
ncpus 是 JVM 發(fā)現(xiàn)的系統(tǒng)的 CPU 個(gè)數(shù)
如果 JVM 應(yīng)用了錯(cuò)誤的 CPU 核心數(shù)
會(huì)導(dǎo)致 JVM 啟動(dòng)過(guò)多的 GC 線程
導(dǎo)致 GC 性能下降, Java 服務(wù)的延時(shí)增加
總結(jié)
分享了容器技術(shù)的發(fā)展捂齐,以 Docker 為代表的容器化技術(shù)的實(shí)現(xiàn)原理
以及大規(guī)模容器之下蛮放,微服務(wù)如何適配等問(wèn)題