- Docker是什么承耿?
Docker是一個開源的基于LXC技術(shù)之上構(gòu)建的新一代容器引擎技術(shù)猾骡,它能夠?qū)?yīng)用程序打包成為一個輕量級容器當(dāng)中凰兑,docker化的應(yīng)用可以輕易的在各個環(huán)境中將它運行起來俄精。在容器的基礎(chǔ)上消除了環(huán)境的差異蝗敢,從代碼交付變成了容器交付渡紫。同時岛琼,基于docker hub你可以基于各式各樣的鏡像不斷的擴(kuò)展视卢、組裝雏逾、發(fā)布你的容器嘉裤。docker整體基于go實現(xiàn),源碼地址在https://github.com/docker/docker
Docker使用C/S的架構(gòu)模式校套,架構(gòu)示意圖如下:
Docker Daemond价脾,Docker服務(wù)的守護(hù)進(jìn)程。在安裝了Docker服務(wù)的環(huán)境上笛匙,都有一個相應(yīng)的Docker守護(hù)進(jìn)程在進(jìn)行工作侨把,它會具體進(jìn)行容器、鏡像管理的一系列操作妹孙。
Docker Client秋柄,Docker客戶端,用戶在操作docker時蠢正,并不是直接對容器骇笔、鏡像等進(jìn)行操作,而是需要通過docker客戶端來與docker守護(hù)進(jìn)程進(jìn)行通訊嚣崭,由docker的守護(hù)進(jìn)程來進(jìn)行實際的操作。即為docker命令芦劣。
Docker Registry说榆,Docker的鏡像倉庫虚吟。對docker鏡像進(jìn)行存儲的地方。
Docker Images偏塞,Docker鏡像,每一個Docker鏡像都是一個模板邦鲫,我們可以基于Docker的鏡像創(chuàng)建出相應(yīng)的Docker容器。
Docker Container庆捺,Docker容器疼燥,實際承載應(yīng)用程序的容器,每一個容器都是基于docker鏡像生成但狭。它有著相應(yīng)的運行周期立磁,包含了一個應(yīng)用所需要的所有運行環(huán)境剥槐。
再簡單描述下它們之間的關(guān)系粒竖,Docker Client會與Docker Daemon進(jìn)行通訊。Docker Daemon接收到Docker Client發(fā)過來的指令后沿后,會進(jìn)行一系列容器的創(chuàng)建尖滚、運行瞧柔、停止漆弄、刪除等操作造锅。當(dāng)Docker Client需要基于某個鏡像(如基礎(chǔ)linux環(huán)境)建立起一個應(yīng)用容器時,Docker Daemon會接收到這條命令券坞,并先嘗試從本地加載相應(yīng)鏡像恨锚,若沒有猴伶,則前往遠(yuǎn)程的鏡像倉庫拉取他挎。拉取下載一個linux鏡像到本地捡需,當(dāng)你執(zhí)行run命令后站辉,docker會啟動一個進(jìn)程饰剥,同時會為該進(jìn)程分配相應(yīng)的文件系統(tǒng)汰蓉、網(wǎng)絡(luò)資源和進(jìn)程組顾孽。另外,作為一個擁有28個參數(shù)的命令太颤,它可以根據(jù)相應(yīng)的參數(shù)來決定容器的運行方式龄章、容器運行所能獲取到的資源和網(wǎng)絡(luò)配置等做裙。這意味著一個linux鏡像run出來的容器锚贱,當(dāng)你的參數(shù)配置了支持前臺運行時拧廊,那么你就可以在這個容器的shell中進(jìn)行你想做的任何操作吧碾,比如搭建java的開發(fā)環(huán)境倦春。當(dāng)你對容器做完一系列操作后睁本,你可以選擇保存這個鏡像,每一次保存都意味著一次commit抄瑟,最終锐借,你可以通過這個鏡像id對外發(fā)布提交你的鏡像钞翔。這里再提一下dockerfile布轿,dockerfile的作用就在于我們可以根據(jù)這個文件生成一個自定義的鏡像汰扭,一份dockerfile文件更像是對一個docker鏡像的語言化描述萝毛。根據(jù)dockerfile的語法笆包,基于一個基礎(chǔ)鏡像略荡,之后的每一行代表一個執(zhí)行指令汛兜,最終執(zhí)行生成一個自定義的鏡像。并可直接從該自定義鏡像中創(chuàng)建容器辫塌。
Docker的一些核心技術(shù)臼氨。
Docker的核心是一個在操作系統(tǒng)層面虛擬化的方法,它與虛擬機(jī)技術(shù)不同喉脖。在虛擬機(jī)技術(shù)中树叽,是從底層往上的進(jìn)行虛擬化题诵,完全自己虛擬出了一個硬件平臺性锭,并在此之上可以搭建自己的操作系統(tǒng)草冈。而docker則是依賴于宿主機(jī)的操作內(nèi)核瓮增,屬于操作系統(tǒng)級別的虛擬化,一些系統(tǒng)調(diào)用還是來源于宿主機(jī)拳恋,各個容器之間的隔離依賴于宿主機(jī)的各個進(jìn)程之間的隔離谬运。由于底層內(nèi)核資源是共享的吩谦,因此相較與vm而言式廷,可以節(jié)省出更多的資源滑废。但是在隔離性上面蠕趁,并不像vm這樣實現(xiàn)了徹底的隔離俺陋。隔離技術(shù)
對于docker的各個容器而言腊状,他們是相互隔離缴挖,互不影響的映屋∨锏悖基于linux內(nèi)核提供的namespace隔離的系統(tǒng)調(diào)用做了以下六個方面的隔離瘫析,首先先說說linux namespace颁股。
個人對namespace的理解為甘有,是linux自身的一種資源隔離機(jī)制亏掀。通過不同的namespace之間有著相應(yīng)的資源隔離滤愕。被隔離開的資源只有在同一個namespace下才可見间影。同時我們可以使用clone方法在創(chuàng)建新進(jìn)程時,我們可以指定是使用父進(jìn)程的namespace裙顽,還是建立一個新的namespace愈犹。linxu啟動時會創(chuàng)建一個namespace漩怎,可視為root namespace勋锤,之后可在該root namespace的基礎(chǔ)上建立一系列的子namespace怪得。 子namespace之間有著相應(yīng)的資源隔離,僅能在namespace內(nèi)互相可見欢伏。
因此硝拧,namespace有這幾個特征: 1. 每個namespace都有自己pid=1的進(jìn)程(類似linux的init進(jìn)程)障陶。 2. 每個namespace中的進(jìn)程只能影響同一個namespace下的或子namespace中的進(jìn)程抱究。 3. 因為 /proc下能看到所有正在運行中的進(jìn)程鼓寺,因此妈候,每一個container下的 /proc目錄只能看到自己namespace的進(jìn)程苦银。 4. 因為namespace允許嵌套墓毒,父namespace可以影響子namespace的進(jìn)程所计,所以子namespace的進(jìn)程可以在父namespace中看到主胧,但具有不同的pid(pid映射)
UTS隔離踪栋,該namespace隔離機(jī)制使得每個容器擁有獨立的hostname和網(wǎng)絡(luò)域名夷都,使得該容器能夠在網(wǎng)絡(luò)被視為一個獨立的節(jié)點
PID隔離囤官,在linux系統(tǒng)下党饮,不同的進(jìn)程使用pid進(jìn)行區(qū)分,而在不同的pid namespace下氯窍,則可以存在相同的pid狼讨。docker daemond與container在同一個namespace中(root namespace)政供,而每一個container又單獨維護(hù)一份 pid namespace鲫骗。
IPC隔離执泰,容器中進(jìn)程間常用的通信方式有信號量术吝、消息隊列和共享內(nèi)存沦寂。對于宿主機(jī)而言传藏。容器中進(jìn)程間的通信實際上為同一個pid namespace下的的進(jìn)程間通信毯侦。每一個IPC namespace在新創(chuàng)建時會生成一個自己namespace的表示符侈离,在后續(xù)申請IPC資源(進(jìn)程交互時所需的資源)時卦碾,會帶上該標(biāo)識洲胖,使得該IPC資源自能在該namespace可見
Network隔離腿短,提供了網(wǎng)絡(luò)資源方面的隔離橘忱。每個net namespace有獨立的network devices钝诚,IP Addresses凝颇,IP routing tables等拧略,這樣每個容器的網(wǎng)絡(luò)就能隔離開垫蛆,docker默認(rèn)采用veth的方式將container中的虛擬網(wǎng)卡同host上的一個docker bridge: docker0連接在一起川无。 在docker server啟動時懦趋,就會創(chuàng)建一個叫docker0的網(wǎng)橋仅叫,容器默認(rèn)會連接到該網(wǎng)橋上惑芭。docker0的ip地址即為該server上所有容器的網(wǎng)關(guān)遂跟。docker內(nèi)部有著自己的ip地址分配凯亮,但是我們可以通過自定義網(wǎng)橋的形式劃分ip假消,使得容器和宿主機(jī)在同一網(wǎng)段上富拗。
(eg1:veth pair是用于不同net namespace間的通信方式)
(eg2:host創(chuàng)建了一個虛擬的bridge啃沪,每個container對應(yīng)一個虛擬網(wǎng)絡(luò)設(shè)備,與bridge儀器構(gòu)成了一個虛擬網(wǎng)絡(luò)追驴,并通過虛擬bridge的方式進(jìn)行通信殿雪,整體結(jié)構(gòu)如下)
(eg3: 如何實現(xiàn)容器之間的互連糯崎,1. 通過ip地址訪問沃呢。2. 在docker run時通過 —link建立相應(yīng)的hostname薄霜,通過hostname互相訪問)
(eg4: 容器訪問外網(wǎng),默認(rèn)網(wǎng)絡(luò)模式與宿主機(jī)一致可直接訪問外網(wǎng))
(eg5: 外網(wǎng)訪問容器崎坊,在run時通過配置將容器映射端口到宿主機(jī)奈揍,外網(wǎng)通過端口訪問)
Mount隔離男翰,通過對文件掛載點的隔離實現(xiàn)了對文件系統(tǒng)的隔離
User隔離蛾绎,在新進(jìn)程創(chuàng)建的新user namespace中可以擁有不同的用戶和用戶組。
AUFS文件系統(tǒng)
AUFS是一種Union FS鸦列,它支持將不同的目錄掛載到同一個虛擬文件系統(tǒng)下租冠。AUFS將掛載到同一虛擬文件系統(tǒng)下的多個目錄分別設(shè)置成read-only,read-write以及whiteout-able權(quán)限敛熬,寫操作只能在read-write目錄中進(jìn)行肺稀。在容器生成掛載不同的目錄時应民,會按照不同目錄的增量關(guān)系,將每層增量關(guān)系不斷的進(jìn)行覆蓋夕吻,最后在最上層掛載一個read-write诲锹。即在一個個鏡像的基礎(chǔ)上,不斷的進(jìn)行增量操作涉馅。在最頂層會掛載一個read-write的目錄归园。每一個容器都是在它鏡像的基礎(chǔ)上,多覆蓋一層read-write的目錄稚矿。cgroups
cgroups是linux內(nèi)核提供的一個可以限制庸诱、記錄捻浦、隔離進(jìn)程組所使用到的物理資源(CPU、內(nèi)存桥爽、IO等)朱灿。