【重識云原生】第六章容器6.1.1節(jié)——容器綜述

??《重識云原生系列》專題索引:

  1. 第一章——不謀全局不足以謀一域
  2. 第二章計算第1節(jié)——計算虛擬化技術總述
  3. 第二章計算第2節(jié)——主流虛擬化技術之VMare ESXi
  4. 第二章計算第3節(jié)——主流虛擬化技術之Xen
  5. 第二章計算第4節(jié)——主流虛擬化技術之KVM
  6. 第二章計算第5節(jié)——商用云主機方案
  7. 第二章計算第6節(jié)——裸金屬方案
  8. 第三章云存儲第1節(jié)——分布式云存儲總述
  9. 第三章云存儲第2節(jié)——SPDK方案綜述
  10. 第三章云存儲第3節(jié)——Ceph統(tǒng)一存儲方案
  11. 第三章云存儲第4節(jié)——OpenStack Swift 對象存儲方案
  12. 第三章云存儲第5節(jié)——商用分布式云存儲方案
  13. 第四章云網(wǎng)絡第一節(jié)——云網(wǎng)絡技術發(fā)展簡述
  14. 第四章云網(wǎng)絡4.2節(jié)——相關基礎知識準備
  15. 第四章云網(wǎng)絡4.3節(jié)——重要網(wǎng)絡協(xié)議
  16. 第四章云網(wǎng)絡4.3.1節(jié)——路由技術簡述
  17. 第四章云網(wǎng)絡4.3.2節(jié)——VLAN技術
  18. 第四章云網(wǎng)絡4.3.3節(jié)——RIP協(xié)議
  19. 第四章云網(wǎng)絡4.3.4節(jié)——OSPF協(xié)議
  20. 第四章云網(wǎng)絡4.3.5節(jié)——EIGRP協(xié)議
  21. 第四章云網(wǎng)絡4.3.6節(jié)——IS-IS協(xié)議
  22. 第四章云網(wǎng)絡4.3.7節(jié)——BGP協(xié)議
  23. 第四章云網(wǎng)絡4.3.7.2節(jié)——BGP協(xié)議概述
  24. 第四章云網(wǎng)絡4.3.7.3節(jié)——BGP協(xié)議實現(xiàn)原理
  25. 第四章云網(wǎng)絡4.3.7.4節(jié)——高級特性
  26. 第四章云網(wǎng)絡4.3.7.5節(jié)——實操
  27. 第四章云網(wǎng)絡4.3.7.6節(jié)——MP-BGP協(xié)議
  28. 第四章云網(wǎng)絡4.3.8節(jié)——策略路由
  29. 第四章云網(wǎng)絡4.3.9節(jié)——Graceful Restart(平滑重啟)技術
  30. 第四章云網(wǎng)絡4.3.10節(jié)——VXLAN技術
  31. 第四章云網(wǎng)絡4.3.10.2節(jié)——VXLAN Overlay網(wǎng)絡方案設計
  32. 第四章云網(wǎng)絡4.3.10.3節(jié)——VXLAN隧道機制
  33. 第四章云網(wǎng)絡4.3.10.4節(jié)——VXLAN報文轉發(fā)過程
  34. 第四章云網(wǎng)絡4.3.10.5節(jié)——VXlan組網(wǎng)架構
  35. 第四章云網(wǎng)絡4.3.10.6節(jié)——VXLAN應用部署方案
  36. 第四章云網(wǎng)絡4.4節(jié)——Spine-Leaf網(wǎng)絡架構
  37. 第四章云網(wǎng)絡4.5節(jié)——大二層網(wǎng)絡
  38. 第四章云網(wǎng)絡4.6節(jié)——Underlay 和 Overlay概念
  39. 第四章云網(wǎng)絡4.7.1節(jié)——網(wǎng)絡虛擬化與卸載加速技術的演進簡述
  40. 第四章云網(wǎng)絡4.7.2節(jié)——virtio網(wǎng)絡半虛擬化簡介
  41. 第四章云網(wǎng)絡4.7.3節(jié)——Vhost-net方案
  42. 第四章云網(wǎng)絡4.7.4節(jié)vhost-user方案——virtio的DPDK卸載方案
  43. 第四章云網(wǎng)絡4.7.5節(jié)vDPA方案——virtio的半硬件虛擬化實現(xiàn)
  44. 第四章云網(wǎng)絡4.7.6節(jié)——virtio-blk存儲虛擬化方案
  45. 第四章云網(wǎng)絡4.7.8節(jié)——SR-IOV方案
  46. 第四章云網(wǎng)絡4.7.9節(jié)——NFV
  47. 第四章云網(wǎng)絡4.8.1節(jié)——SDN總述
  48. 第四章云網(wǎng)絡4.8.2.1節(jié)——OpenFlow概述
  49. 第四章云網(wǎng)絡4.8.2.2節(jié)——OpenFlow協(xié)議詳解
  50. 第四章云網(wǎng)絡4.8.2.3節(jié)——OpenFlow運行機制
  51. 第四章云網(wǎng)絡4.8.3.1節(jié)——Open vSwitch簡介
  52. 第四章云網(wǎng)絡4.8.3.2節(jié)——Open vSwitch工作原理詳解
  53. 第四章云網(wǎng)絡4.8.4節(jié)——OpenStack與SDN的集成
  54. 第四章云網(wǎng)絡4.8.5節(jié)——OpenDayLight
  55. 第四章云網(wǎng)絡4.8.6節(jié)——Dragonflow
  56. ?第四章云網(wǎng)絡4.9.1節(jié)——網(wǎng)絡卸載加速技術綜述

  57. 第四章云網(wǎng)絡4.9.2節(jié)——傳統(tǒng)網(wǎng)絡卸載技術

  58. 第四章云網(wǎng)絡4.9.3.1節(jié)——DPDK技術綜述

  59. 第四章云網(wǎng)絡4.9.3.2節(jié)——DPDK原理詳解

  60. 第四章云網(wǎng)絡4.9.4.1節(jié)——智能網(wǎng)卡SmartNIC方案綜述

  61. 第四章云網(wǎng)絡4.9.4.2節(jié)——智能網(wǎng)卡實現(xiàn)

  62. 第六章容器6.1.1節(jié)——容器綜述

  63. 第六章容器6.1.2節(jié)——容器安裝部署

  64. 第六章容器6.1.3節(jié)——Docker常用命令

  65. 第六章容器6.1.4節(jié)——Docker核心技術LXC

  66. 第六章容器6.1.5節(jié)——Docker核心技術Namespace

  67. 第六章容器6.1.6節(jié)—— Docker核心技術Chroot

  68. 第六章容器6.1.7.1節(jié)——Docker核心技術cgroups綜述

  69. 第六章容器6.1.7.2節(jié)——cgroups原理剖析

  70. 第六章容器6.1.7.3節(jié)——cgroups數(shù)據(jù)結構剖析

  71. 第六章容器6.1.7.4節(jié)——cgroups使用

  72. 第六章容器6.1.8節(jié)——Docker核心技術UnionFS

  73. 第六章容器6.1.9節(jié)——Docker鏡像技術剖析

  74. 第六章容器6.1.10節(jié)——DockerFile解析

  75. 第六章容器6.1.11節(jié)——docker-compose容器編排

  76. 第六章容器6.1.12節(jié)——Docker網(wǎng)絡模型設計

  77. 第六章容器6.2.1節(jié)——Kubernetes概述

  78. 第六章容器6.2.2節(jié)——K8S架構剖析

  79. 第六章容器6.3.1節(jié)——K8S核心組件總述

  80. 第六章容器6.3.2節(jié)——API Server組件

  81. 第六章容器6.3.3節(jié)——Kube-Scheduler使用篇

  82. 第六章容器6.3.4節(jié)——etcd組件

  83. 第六章容器6.3.5節(jié)——Controller Manager概述

  84. 第六章容器6.3.6節(jié)——kubelet組件

  85. 第六章容器6.3.7節(jié)——命令行工具kubectl

  86. 第六章容器6.3.8節(jié)——kube-proxy

  87. 第六章容器6.4.1節(jié)——K8S資源對象總覽

  88. 第六章容器6.4.2.1節(jié)——pod詳解

  89. 第六章容器6.4.2.2節(jié)——Pod使用(上)

  90. 第六章容器6.4.2.3節(jié)——Pod使用(下)

  91. 第六章容器6.4.3節(jié)——ReplicationController

  92. 第六章容器6.4.4節(jié)——ReplicaSet組件

  93. 第六章容器基礎6.4.5.1節(jié)——Deployment概述

  94. 第六章容器基礎6.4.5.2節(jié)——Deployment配置詳細說明

  95. 第六章容器基礎6.4.5.3節(jié)——Deployment實現(xiàn)原理解析

  96. 第六章容器基礎6.4.6節(jié)——Daemonset

  97. 第六章容器基礎6.4.7節(jié)——Job

  98. 第六章容器基礎6.4.8節(jié)——CronJob

?1 Docker簡述

1.1 什么是Docker

????????Docker是一個開源的軟件項目,讓用戶程序部署在一個相對隔離的環(huán)境運行,借此在Linux操作系統(tǒng)上提供一層額外的抽象,以及操作系統(tǒng)層虛擬化的自動管理機制。需要額外指出的是,Docker并不等于容器(containers),Docker只是容器的一種,其他的種類的容器還有Kata container,Rocket container等等。

????????Docker 使用 Google 公司推出的 Go 語言 進行開發(fā)實現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術,對進程進行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術。由于隔離的進程獨立于宿主和其它的隔離的進程,因此也稱其為容器。最初實現(xiàn)是基于 LXC,從 0.7 以后開始去除 LXC,轉而使用自行開發(fā)的 libcontainer,從 1.11 開始,則進一步演進為使用 runC 和 containerd。

????????Docker 在容器的基礎上,進行了進一步的封裝,從文件系統(tǒng)、網(wǎng)絡互聯(lián)到進程隔離等等,極大的簡化了容器的創(chuàng)建和維護。使得 Docker 技術比虛擬機技術更為輕便、快捷。

1.2 為什么使用容器

????????如今的系統(tǒng)在架構上較十年前已經(jīng)變得非常復雜了。以前幾乎所有的應用都采用三層架構(Presentation/Application/Data),系統(tǒng)部署到有限的幾臺物理服務器上(Web Server/Application Server/Database Server)。

????????而今天,開發(fā)人員通常使用多種服務(比如 MQ,Cache,DB)構建和組裝應用,而且應用很可能會部署到不同的環(huán)境,比如虛擬服務器,私有云和公有云。

????????一方面應用包含多種服務,這些服務有自己所依賴的庫和軟件包;另一方面存在多種部署環(huán)境,服務在運行時可能需要動態(tài)遷移到不同的環(huán)境中。這就產(chǎn)生了一個問題:如何讓每種服務能夠在所有的部署環(huán)境中順利運行?

????????聰明的技術人員從傳統(tǒng)的運輸行業(yè)找到了答案。

????????幾十年前,運輸業(yè)面臨著類似的問題。

????????每一次運輸,貨主與承運方都會擔心因貨物類型的不同而導致?lián)p失,比如幾個鐵桶錯誤地壓在了一堆香蕉上。另一方面,運輸過程中需要使用不同的交通工具也讓整個過程痛苦不堪:貨物先裝上車運到碼頭,卸貨,然后裝上船,到岸后又卸下船,再裝上火車,到達目的地,最后卸貨。一半以上的時間花費在裝、卸貨上,而且搬上搬下還容易損壞貨物。

????????幸運的是,集裝箱的發(fā)明解決這個難題。

????????打一個比方,集裝箱(容器)對于遠洋運輸(應用運行)來說十分重要。集裝箱(容器)能保護貨物(應用),讓其不會相互碰撞(應用沖突)而損壞,也能保障當一些危險貨物發(fā)生規(guī)模不大的爆炸(應用崩潰)時不會波及其它貨物(應用)但是把貨物(應用)裝載在集裝箱(容器)中并不是一件簡單的事情。而出色的碼頭工人(Docker)的出現(xiàn)解決了這一問題。它(Docker)使得貨物裝載到集裝箱(容器)這一過程變得輕而易舉。對于遠洋運輸(應用運行)而言,用多艘小貨輪(虛擬機)代替原來的大貨輪(實體機)也能保證貨物(應用)彼此之間的安全,但是和集裝箱(容器)比,成本過高,但適合運輸某些重要貨物(應用)。

????????任何貨物,無論鋼琴還是保時捷,都被放到各自的集裝箱中。集裝箱在整個運輸過程中都是密封的,只有到達最終目的地才被打開。標準集裝箱可以被高效地裝卸、重疊和長途運輸?,F(xiàn)代化的起重機可以自動在卡車、輪船和火車之間移動集裝箱。集裝箱被譽為運輸業(yè)與世界貿(mào)易最重要的發(fā)明。

????????Docker 將集裝箱思想運用到軟件打包上,為代碼提供了一個基于容器的標準化運輸系統(tǒng)。Docker 可以將任何應用及其依賴打包成一個輕量級、可移植、自包含的容器。容器可以運行在幾乎所有的操作系統(tǒng)上。

????????其實,“集裝箱” 和 “容器” 對應的英文單詞都是 “Container”。

????????“容器” 是國內(nèi)約定俗成的叫法,可能是因為容器比集裝箱更抽象,更適合軟件領域的原故吧。

1.3 Docker的優(yōu)勢

  • 更高效的利用系統(tǒng)資源

????????由于容器不需要進行硬件虛擬以及運行完整操作系統(tǒng)等額外開銷,Docker 對系統(tǒng)資源的利用率更高。無論是應用執(zhí)行速度、內(nèi)存損耗或者文件存儲速度,都要比傳統(tǒng)虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數(shù)量的應用。

  • 更快速的啟動時間

????????傳統(tǒng)的虛擬機技術啟動應用服務往往需要數(shù)分鐘,而 Docker 容器應用,由于直接運行于宿主內(nèi)核,無需啟動完整的操作系統(tǒng),因此可以做到秒級、甚至毫秒級的啟動時間。大大的節(jié)約了開發(fā)、測試、部署的時間。

  • 一致的運行環(huán)境

????????開發(fā)過程中一個常見的問題是環(huán)境一致性問題。由于開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境不一致,導致有些 bug 并未在開發(fā)過程中被發(fā)現(xiàn)。而 Docker 的鏡像提供了除內(nèi)核外完整的運行時環(huán)境,確保了應用運行環(huán)境一致性,從而不會再出現(xiàn) “這段代碼在我機器上沒問題啊” 這類問題。

  • 持續(xù)交付和部署

????????對開發(fā)和運維(DevOps)人員來說,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運行。

????????使用 Docker 可以通過定制應用鏡像來實現(xiàn)持續(xù)集成、持續(xù)交付、部署。開發(fā)人員可以通過 Dockerfile 來進行鏡像構建,并結合 持續(xù)集成(Continuous Integration) 系統(tǒng)進行集成測試,而運維人員則可以直接在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結合 持續(xù)部署(Continuous Delivery/Deployment) 系統(tǒng)進行自動部署。

????????而且使用 Dockerfile 使鏡像構建透明化,不僅僅開發(fā)團隊可以理解應用運行環(huán)境,也方便運維團隊理解應用運行所需條件,幫助更好的生產(chǎn)環(huán)境中部署該鏡像。

  • 更輕松的遷移

????????由于 Docker 確保了執(zhí)行環(huán)境的一致性,使得應用的遷移更加容易。Docker 可以在很多平臺上運行,無論是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環(huán)境的變化導致應用無法正常運行的情況。

  • 更輕松的維護和擴展

????????Docker 使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基于基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質量的官方鏡像,既可以直接在生產(chǎn)環(huán)境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。

1.4 Docker核心概念

1.4.1 鏡像(Image)

????????Docker鏡像(Image)類似于虛擬機的鏡像,可以將他理解為一個面向Docker引擎的只讀模板,包含了文件系統(tǒng)。例如:一個鏡像可以完全包含了Ubuntu操作系統(tǒng)環(huán)境,可以把它稱作一個Ubuntu鏡像。鏡像也可以安裝了Apache應用程序(或其他軟件),可以把它稱為一個Apache鏡像。

????????鏡像是創(chuàng)建Docker容器的基礎,通過版本管理和增量的文件系統(tǒng),Docker提供了一套十分簡單的機制來創(chuàng)建和更新現(xiàn)有的鏡像。用戶可以從網(wǎng)上下載一個已經(jīng)做好的應用鏡像,并通過命令直接使用??傊?,應用運行是需要環(huán)境的,而鏡像就是來提供這種環(huán)境。

1.4.2 容器(Container)

????????Docker容器(Container)類似于一個輕量級的沙箱(因為Docker是基于Linux內(nèi)核的虛擬技術,所以消耗資源十分少),Docker利用容器來運行和隔離應用。容器是從鏡像創(chuàng)建的應用運行實例,可以將其啟動、開始、停止、刪除,而這些容器都是相互隔離、互不可見的??梢园衙總€容器看作一個簡易版的Linux系統(tǒng)環(huán)境(包括了root用戶權限、進程空間、用戶空間和網(wǎng)絡空間),以及與運行在其中的應用程序打包而成的應用盒子。鏡像自身是只讀的。容器從鏡像啟動的時候,Docker會在鏡像的最上層創(chuàng)建一個可寫層,鏡像本身將保持不變。就像用ISO裝系統(tǒng)之后,ISO并沒有什么變化一樣。

1.4.3 倉庫(Repository)

????????Docker倉庫(Repository)類似于代碼倉庫,是Docker集中存放鏡像文件的場所。有時候會看到有資料將Docker倉庫和注冊服務器(Registry)混為一談,并不嚴格區(qū)分。實際上,注冊服務器是存放倉庫的地方,其上往往存放著多個倉庫。每個倉庫集中存放某一類鏡像,往往包括多個鏡像文件,通過不同的標簽(tag)來進行區(qū)分。例如存放Ubuntu操作系統(tǒng)鏡像的倉庫,稱為Ubuntu倉庫,其中可能包括14.04,12.04等不同版本的鏡像。根據(jù)存儲的鏡像公開分享與否,Docker倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。

????????目前,最大的公開倉庫是Docker Hub,存放了數(shù)量龐大的鏡像供用戶下載。國內(nèi)的公開倉庫包括Docker Pool等,可以提供穩(wěn)定的國內(nèi)訪問。如果用戶不希望公開分享自己的鏡像文件,Docker也支持用戶在本地網(wǎng)絡內(nèi)創(chuàng)建一個只能自己訪問的私有倉庫。當用戶創(chuàng)建了自己的鏡像之后就可以使用push明亮將它上傳到指定的公有或則私有倉庫。這樣用戶下次在另一臺機器上使用該鏡像時,只需將其從倉庫pull下來就可以了。Docker利用倉庫管理鏡像的設計理念甚至命令和git非常相似,也就意味著非常好上手。

1.5 Docker VS 虛擬機

?????????從上面這幅圖就可以看出,虛擬機是正兒八經(jīng)的存在一層硬件虛擬層,模擬出了運行一個操作系統(tǒng)需要的各種硬件,例如CPU,MEM,IO等設備。然后在虛擬的硬件上安裝了一個新的操作系統(tǒng)Guest OS。所以在Windows宿主機上面可以跑Linux虛擬機。因為多了一層虛擬,所以虛擬機的性能必然會有所損耗。Docker容器是由Docker Deamon(Docker Deamon是運行在宿主機上面的一個后臺進程,負責拉起和設置容器)拉起的一個個進程,通過Docker Deamon設置完Namespace和Cgroup之后,本質上就是一個運行在宿主機上面的進程。因為沒有一層虛擬的Guest OS,所以Docker輕量級很多。但是有利就有弊,由于Docker 容器直接運行在宿主機上面,安全性就相對較差些,另外也沒有辦法在Windows上面運行Linux的容器,如果容器里面的應用對特定系統(tǒng)內(nèi)核有要求也不能運行在不滿足要求的宿主機上面。

????????對比傳統(tǒng)虛擬機總結

1.6 使用場景

????????Docker通常用于如下場景:

  • web應用的自動化打包和發(fā)布;
  • 自動化測試和持續(xù)集成、發(fā)布;
  • 在服務型環(huán)境中部署和調整數(shù)據(jù)庫或其他的后臺應用;
  • 從頭編譯或者擴展現(xiàn)有的OpenShift或Cloud Foundry平臺來搭建自己的PaaS環(huán)境。

2 基本原理

????????Docker利用Linux中的核心分離機制,例如Cgroups,以及Linux的核心Namespace(名字空間)來創(chuàng)建獨立的容器。一句話概括起來Docker就是利用Namespace做資源隔離,用Cgroup做資源限制,利用Union FS做容器文件系統(tǒng)的輕量級虛擬化技術。Docker容器的本質還是一個直接運行在宿主機上面的特殊進程,看到的文件系統(tǒng)是隔離后的,但是操作系統(tǒng)內(nèi)核是共享宿主機OS,所以說Docker是輕量級的虛擬化技術。

2.1 Namespace

????????Linux Namespace 是Linux 提供的一種內(nèi)核級別環(huán)境隔離的方法,使其中的進程好像擁有獨立的操作系統(tǒng)環(huán)境。Linux Namespace 有 Mount Namespace,UTS Namespace, IPC Namespace, PID Namespace, Network Namespace, User Namespace, Cgroup Namespace。詳情看下表:

分類

系統(tǒng)調用參數(shù)

隔離內(nèi)容

內(nèi)核版本

Mount Namespace

CLONE_NEWNS

文件系統(tǒng)掛載點

Linux 2.4.19(2002年)

UTS Namespace

CLONE_NEWUTS

Hostname和domain name

Linux 2.6.19

IPC Namespace

CLONE_NEWIPC

進程間通信方式,例如消息隊列

Linux 2.6.19

PID Namespace

CLONE_NEWPID

進程ID編號

Linux 2.6.24

Network Namespace,

CLONE_NEWNET

網(wǎng)絡設備,協(xié)議棧,路由表,防火墻規(guī)則,端口等

Linux 2.6.24 start Linux 2.6.29 end

User Namespace

CLONE_NEWUSER

用戶及組ID

Linux 2.6.23 start Linux 3.8 end

Cgroup Namespace

CLONE_NEWCGROUP

Cgroup根目錄

Linux 4.6

????????上述系統(tǒng)調用參數(shù)CLONE_NEWNS等主要應用于以下三個系統(tǒng)調用:

  • clone 創(chuàng)建新進程并設置它的Namespace,類似于fork系統(tǒng)調用,可創(chuàng)建新進程并且指定子進程將要執(zhí)行的函數(shù),通過上述CLONE_NEWNS等參數(shù)使某類資源處于隔離狀態(tài)。

函數(shù)聲明 :

#include int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );

例如:

int pid = clone(call_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

????????會讓新創(chuàng)建的該進程執(zhí)行call_function,例如/bin/bash,且該進程的PID進程編號是隔離狀態(tài),也就是新的PID編號,該進程ps將會看到它的PID是1。

????????如果多次執(zhí)行上述clone就會創(chuàng)建多個PID Namespace,而每個Namespace里面的應用進程都認為自己是當前容器里的1號進程,它們既看不到宿主機里的真實進程空間,也看不到其他PID Namespace里面的具體情況。

  • int unshare(int flags) 使進程脫離某個Namespace,flags參數(shù)和clone的用法一致。
  • int setns(int fd, int nstype)?使進程進入某個已經(jīng)存在的Namespace。經(jīng)常用于從宿主機進入已經(jīng)啟動的容器Network Namespace,然后設置它的網(wǎng)絡。

2.2 Cgroup

????????上面已經(jīng)講過Docker 容器運行起來是一個直接運行在宿主機上面的進程,那么如果限定每個容器最多消耗多少CPU資源呢?如果一個容器瘋狂的消耗資源豈不是會影響同一宿主機上面其他的容器?所以Docker就需要一個限制容器能夠使用資源上限的機制,那就是Linux Cgroup技術。Linux Cgroup 全稱是Linux Control Group。它最主要的作用是限制一個進程組能夠使用的資源上限,包括CPU,MEM,DISK,NET等等。

????????下面我將演示一個利用Cgroup限制進程CPU的例子:

[root@nginx-1 /sys/fs/cgroup/cpu]# ll

total 0

-rw-r--r-- 1 root root 0 Sep 26 2018 cgroup.clone_children

--w--w--w- 1 root root 0 Sep 26 2018 cgroup.event_control

-rw-r--r-- 1 root root 0 Sep 26 2018 cgroup.procs

-r--r--r-- 1 root root 0 Sep 26 2018 cgroup.sane_behavior

-r--r--r-- 1 root root 0 Sep 26 2018 cpuacct.stat

-rw-r--r-- 1 root root 0 Sep 26 2018 cpuacct.usage

-r--r--r-- 1 root root 0 Sep 26 2018 cpuacct.usage_percpu

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.cfs_period_us

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.cfs_quota_us

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.cfs_relax_thresh_sec

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.rt_period_us

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.rt_runtime_us

-rw-r--r-- 1 root root 0 Sep 26 2018 cpu.shares

-r--r--r-- 1 root root 0 Sep 26 2018 cpu.stat

drwxr-xr-x 9 root root 0 Jun 6 17:03 docker

-rw-r--r-- 1 root root 0 Sep 26 2018 notify_on_release

-rw-r--r-- 1 root root 0 Sep 26 2018 release_agent

-rw-r--r-- 1 root root 0 Sep 26 2018 tasks

[root@nginx-1 /sys/fs/cgroup/cpu]# mkdir mytest #創(chuàng)建mytest目錄,系統(tǒng)會自動添加以下文件

[root@nginx-1 /sys/fs/cgroup/cpu/mytest]# ll

total 0

-rw-r--r-- 1 root root 0 Jun 13 16:55 cgroup.clone_children

--w--w--w- 1 root root 0 Jun 13 16:55 cgroup.event_control

-rw-r--r-- 1 root root 0 Jun 13 16:55 cgroup.procs

-r--r--r-- 1 root root 0 Jun 13 16:55 cpuacct.stat

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpuacct.usage

-r--r--r-- 1 root root 0 Jun 13 16:55 cpuacct.usage_percpu

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.cfs_period_us

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.cfs_quota_us

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.cfs_relax_thresh_sec

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.rt_period_us

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.rt_runtime_us

-rw-r--r-- 1 root root 0 Jun 13 16:55 cpu.shares

-r--r--r-- 1 root root 0 Jun 13 16:55 cpu.stat

-rw-r--r-- 1 root root 0 Jun 13 16:55 notify_on_release

-rw-r--r-- 1 root root 0 Jun 13 16:55 tasks

[root@nginx-1 /sys/fs/cgroup/cpu/mytest]# while : ; do : ; done & # 運行一個死循環(huán)命令

[1] 2459615

????????op觀察會發(fā)現(xiàn)該進程CPU跑到了100%,符合預期

?????????主要的限制參數(shù)來源自文件cpu.cfs_quota_us,默認是-1,不做限制,如果改成20000說明限定20%的CPU上限。因為總量存在于cpu.cfs_period_us,是100000,意思cpu時間總量是100000us,20000/100000=20%。然后將bash命令的PID寫到tasks文件中,改完之后的CPU占用是20%,符合預期:

?????????同理可限制MEM,DISK和NET,需要特殊指出的是MEM是硬限制,當容器的內(nèi)存使用量超過了Cgroup限定值會被系統(tǒng)OOM。

2.3 Union FS

????????每個容器運行起來后都有一個獨立的文件系統(tǒng),例如Ubuntu鏡像的容器能夠看到Ubuntu的文件系統(tǒng),Centos能夠看到Centos的文件系統(tǒng), 不是說容器是運行在宿主機上面的進程嗎,為什么能夠看到和宿主機不一樣的文件系統(tǒng)呢?那就要歸功于Union FS,全稱是Union File System,聯(lián)合文件系統(tǒng)。將多個不同位置的目錄聯(lián)合掛載到同一個目錄,將相同的部分合并。Docker利用這種聯(lián)合掛載能力,將容器鏡像里面的多層內(nèi)容呈現(xiàn)為統(tǒng)一的rootfs(根文件系統(tǒng)),即root用戶能夠看到的根目錄底下所有的目錄文件。rootfs打包了整個操作系統(tǒng)的文件和目錄,是應用運行時所需要的最完整的“依賴庫”,也就是我們說的“鏡像”。

????????鏡像分為基礎鏡像只讀層,和Init層,和讀寫層。

????????Init 層存放的是/etc/hostname,/etc/resolv.conf 等, docker commit的時候不提交。

????????讀寫層一開始的時候為空,用戶如果修改了文件系統(tǒng),比如說增刪改了文件,docker commit的時候就會提交這一層信息。

3 總結

????????Docker 容器總結起來就是利用Linux Namespace做資源隔離,Cgroup做資源上限限制,rootfs做文件系統(tǒng) 運行在宿主機上面的一個特殊進程。

參考鏈接

Docker基礎原理 - 我是碼客 - 博客園

開始學習Docker啦--容器理論知識(一) - 小水滴18 - 博客園

聊聊Docker理論知識(二) - 小水滴18 - 博客園

Docker與Kubernetes系列(一): Docker的基本概念_沈鴻斌的博客-CSDN博客_docker kubernet

Docker與Kubernetes系列(二): Docker的基本用法_沈鴻斌的博客-CSDN博客

docker容器技術入門知識及思維導圖_adorable_的博客-CSDN博客_docker學習思維導圖


?

?最新文章歡迎關注筆者公眾號“暢游云?!?/p>

本文由[mdnice](https://mdnice.com/?platform=6)多平臺發(fā)布
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容