觀感度:🌟🌟🌟🌟🌟前端
口味:芝士魚籽linux
烹飪時間:15min編程
有人把Docker比喻成運維人員的一把「瑞士軍刀」,由於他們能夠經過這把軍刀實現終極夢想「一次建立,處處運行」。後端
也有人說Docker是給PaaS世界帶來的「降維打擊」,Docker鏡像完美解決了應用打包這個根本性問題,直接將應用所運行的整個操做系統進行打包,讓你的本地環境和雲端環境高度一致,再也無需在不一樣的運行環境切換之間進行痛苦的試錯。服務器
究其本質,Docker把純後端的技術概念,進行了很是友好的封裝,展示在廣大開發者面前。
網絡
回顧Docker的發展歷史,Google、微軟、IBM、RebHat等巨頭推進着這隻小鯨魚在容器雲的浪潮中掀起了陣陣波濤。雲計算世界的運維方式從SSH的刀耕火種正式邁入了電氣自動化時代。從歷史的本質中能夠看出,運維再也不僅僅是服務器的維護,更重要的是數據、服務與人的溝通。
看來新技術想要獲得承認和發展,就要將開發者羣體擺在最高位置。前端工程師
在技術大爆發的時代,咱們天天接收新知識的時候更多的都是進行快餐式的閱讀,這樣就會形成對待新技術僅僅停留在會用便可、瞭解便可的程度,這樣的惡性循環對咱們自身的技術發展是大大不利的。對於核心的技術咱們必定要作到可以真正理解它的原理和底層實現,這樣才能對技術發展趨勢創建起本身的判斷和預言。
架構
做爲前端工程師,項目裏的Dockerfile通常都是腳手架自動生成配置好的,咱們無需清楚它的內部實現。但當你有機會參與到公司的腳手架項目搭建,有機會和DevOps同事進行深度的交流(我工位離DevOps同事很近,常常找他們扯皮),那麼你必定會感覺到這隻小鯨魚的魔力並想進入它的體內一探究竟。app
來,看看內臟!運維
Docker是一個C/S架構,咱們能夠經過客戶端與服務器創建通訊。
從圖中咱們能夠看到,它的主要模塊有DockerClient、Docker Daemon、Docker Registry、Driver、Graph、libcontainer以及Docker Container。接下來咱們來逐一理解他們。
Docker Daemon是Docker中一個常駐在後臺的守護進程,也就是「運行Docker」。
任務由Engine運行引擎完成,每項任務都由Job形式存在,也就是說Job是引擎內部最基本的工做執行單元。
Docker Registry是一個存儲容器鏡像(Docker Image)的倉庫,能夠以公有和私有的形式存在。Docker Hub就是全球範圍內最大的公有Registry。在Docker的運行過程當中,有三種狀況可以和Docker Registry進行通訊,分別是進行搜索、上傳以及下載鏡像。
對比架構圖,Graph有着保管着容器鏡像的能力。固然它也支持多種不一樣的存儲方式,除了圖中的aufs,還有devicemapper、Btrfs等。
Driver顧名思義,是一個驅動模塊。能夠實現對容器運行環境的定製,包括網絡環境、存儲方式以及容器執行方式。這一層的抽象意義在於,將與Docker容器相關的管理從Docker Daemon的全部邏輯中進行分門別類。
如架構圖中所示,能夠分爲如下三類:
graphdriver主要管理容器鏡像方面的內容。包括存儲從Docker Registry上下載的鏡像以及本地構建的鏡像。
networkdriver負責管理容器網絡環境。在Docker Daemon啓動時爲Docker環境建立網橋,在Docker容器建立前分配相應的網絡接口資源,爲Docker容器分配IP、端口並與宿主機進行NAT端口映射以及設置防火牆策略等。
execdriver是Docker容器的執行驅動,負責建立容器運行時的命名空間、資源使用的統計與限制、負責管理內部進程的真正運行等。
libcontainer抽象出了linux的內核特性,爲Docker Daemon提供了完整的接口。 它是由Go語言設計實現的庫,能夠不依靠任何依賴,直接訪問內核中與容器相關的系統調用。其自己也能夠被上層多種不一樣的編程語言訪問。
如架構圖中所示,最底下離咱們最近的一層,Docker Container就是Docker架構中服務交付的最終體現形式。
containerd核心化,引擎集羣化。
新增containerd和runc,原有的引擎功能下沉到containerd。
containerd負責管理容器的生命週期,向着獨立於Docker做爲通用容器運行時工具方向演進。
除此以外,將集羣編排工具swarm整合進引擎,引擎內部也不斷進行解耦出新模塊buildkit等。
一部分緣由是因爲swarm與kubernetes的競爭失敗,Docker公司爲了不本身在開源社區中被邊緣化,於2017年將containerd捐獻給CNCF基金會,將更多Docker引擎的功能下沉到containerd。另外就是容器世界的標準化在不斷推動。
「沒有集裝箱,就沒有全球化。」
這是《經濟學家》雜誌對集裝箱的評價,看似普通的發明,推進了全球化的進程。這也是Docker的小鯨魚身上揹着的集裝箱的魔力所在。
容器其實就是一種特殊的進程。
Docker的核心功能,就是約束,「喜歡就會放肆,但愛是剋制」。
看來小鯨魚是走心真愛了,真愛三連問:
那麼約束的又是什麼呢?經過什麼來進行約束呢?約束實現了什麼呢?
約束的是進程的動態表現。
經過Cgroups技術(Linux的一種機制)來進行約束。
約束實現了「邊界」。
除了約束之外,Docker還能夠修改進行的動態表現,經過Namespace技術來實現。
Namespace
也是Linux裏面的一種機制,對被隔離應用的進程空間使用了魅惑之術
,使得這些進程只能看到從新計算過的編號,但實際上,他們在宿主機的操做系統裏,仍是原來的編號。
在Linux中使用也特別簡單,就是Linux建立新進程時候的一個可選參數(CLONE_NEWPID)
。除了PID Namespace,Linux操做系統還提供了Network、Mount、User、IPC、UTS等Namespace,來針對不一樣的進程進行魅惑。
Linux Cgroups(Linux Control Group)
,它的功能是限制一個進程組可以使用的資源,包括CPU、內存、磁盤、網絡帶寬等。與Namespce配合起來使用就能夠實現雙劍合璧,隔離進程而且約束進程佔用的資源量。
相比於虛擬機而言,Linux的Namespace機制隔離的並不完全,多個容器仍舊是共享宿主機內核。
時間並不能被隔離。
Cgroups的/proc文件系統問題,/proc文件系統並不受Cgroups的限制(/proc渣男實錘),在生產環境中可使用LXCFS
修正。
LXCFS其實也是一種魅惑之術,經過文件掛載的方式,把Cgroups中關於系統的相關信息讀取出來,再經過Docker的Volume掛載給容器內部的proc系統。魅惑Docker內部應用,讀取proc中信息的時候覺得就是讀取宿主機的真實proc。
參考:
1.看到這裏了就點個贊支持下吧,你的點贊是我創做的動力。
2.關注公衆號前端食堂,你的前端食堂,記得按時吃飯!
3.入冬了,多穿衣服不要着涼~!