自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官留步!聽我跟你侃會(huì)兒Docker原理

云計(jì)算
開發(fā)人員開發(fā)完一個(gè)電商項(xiàng)目,該 Jar 項(xiàng)目包含 Redis、MySQL、ES、Haddop等若干組件。開發(fā)人員自測(cè)無(wú)誤后提交給測(cè)試進(jìn)行預(yù)生產(chǎn)測(cè)試了。

[[376648]]

本文轉(zhuǎn)載自微信公眾號(hào)「sowhat1412」,作者sowhat1412。轉(zhuǎn)載本文請(qǐng)聯(lián)系sowhat1412公眾號(hào)。  

開發(fā)人員開發(fā)完一個(gè)電商項(xiàng)目,該 Jar 項(xiàng)目包含 Redis、MySQL、ES、Haddop等若干組件。開發(fā)人員自測(cè)無(wú)誤后提交給測(cè)試進(jìn)行預(yù)生產(chǎn)測(cè)試了。

測(cè)試:你的這個(gè)服務(wù),我在進(jìn)行單元測(cè)試跟數(shù)據(jù)核對(duì)的時(shí)候總是出現(xiàn)不知名的bug!你要不要來看下啊?

開發(fā):你咋測(cè)試的?是按照操作文檔一步步來的么?

測(cè)試:絕對(duì)是按照文檔來的啊!

開發(fā):你重啟了嗎?清緩存了嗎?代碼是最新版嗎?你用的是Chrome瀏覽器? 你是不是動(dòng)啥東西了?

測(cè)試:這.. 這.. 這.. 我啥也沒干啊!

至此,開發(fā)跟測(cè)試之間的愛恨情仇正式開始!

1 Docker 簡(jiǎn)介

1.1 Docker 由來

Docker 是基于 Go 語(yǔ)言開發(fā)的一個(gè)容器引擎,Docker是應(yīng)用程序與系統(tǒng)之間的隔離層。通常應(yīng)用程序?qū)Π惭b的系統(tǒng)環(huán)境會(huì)有各種嚴(yán)格要求,當(dāng)服務(wù)器很多時(shí)部署時(shí)系統(tǒng)環(huán)境的配置工作是非常繁瑣的。Docker讓應(yīng)用程序不必再關(guān)心主機(jī)環(huán)境,各個(gè)應(yīng)用安裝在Docker鏡像里,Docker引擎負(fù)責(zé)運(yùn)行包裹了應(yīng)用程序的docker鏡像。

Docker的理念是讓開發(fā)人員可以簡(jiǎn)單地把應(yīng)用程序及依賴裝載到容器中,然后輕松地部署到任何地方,Docker具有如下特性。

Docker容器是輕量級(jí)的虛擬技術(shù),占用更少系統(tǒng)資源。

使用 Docker容器,不同團(tuán)隊(duì)(如開發(fā)、測(cè)試,運(yùn)維)之間更容易合作。

可以在任何地方部署 Docker 容器,比如在任何物理和虛擬機(jī)上,甚至在云上。

由于Docker容器非常輕量級(jí),因此可擴(kuò)展性很強(qiáng)。

1.2 Docker 基本組成

 

鏡像(image):

Docker 鏡像就好比是一個(gè)目標(biāo),可以通過這個(gè)目標(biāo)來創(chuàng)建容器服務(wù),可以簡(jiǎn)單的理解為編程語(yǔ)言中的類。

容器(container):

Docker 利用容器技術(shù),獨(dú)立運(yùn)行一個(gè)或者一組應(yīng)用,容器是通過鏡像來創(chuàng)建的,在容器中可執(zhí)行啟動(dòng)、停止、刪除等基本命令,最終服務(wù)運(yùn)行或者項(xiàng)目運(yùn)行就是在容器中的,可理解為是類的實(shí)例。

倉(cāng)庫(kù)(repository):

倉(cāng)庫(kù)就是存放鏡像的地方!倉(cāng)庫(kù)分為公有倉(cāng)庫(kù)和私有倉(cāng)庫(kù),類似Git。一般我們用的時(shí)候都是用國(guó)內(nèi)docker鏡像來加速。

1.3 VM 跟 Docker

 

虛擬機(jī):

傳統(tǒng)的虛擬機(jī)需要模擬整臺(tái)機(jī)器包括硬件,每臺(tái)虛擬機(jī)都需要有自己的操作系統(tǒng),虛擬機(jī)一旦被開啟,預(yù)分配給他的資源將全部被占用。每一個(gè)虛擬機(jī)包括應(yīng)用,必要的二進(jìn)制和庫(kù),以及一個(gè)完整的用戶操作系統(tǒng)。

Docker:

容器技術(shù)是和我們的宿主機(jī)共享硬件資源及操作系統(tǒng)可以實(shí)現(xiàn)資源的動(dòng)態(tài)分配。容器包含應(yīng)用和其所有的依賴包,但是與其他容器共享內(nèi)核。容器在宿主機(jī)操作系統(tǒng)中,在用戶空間以分離的進(jìn)程運(yùn)行。

比對(duì)項(xiàng) Container(容器) VM(虛擬機(jī))
啟動(dòng)速度 秒級(jí) 分鐘級(jí)
運(yùn)行性能 接近原生 有所損失
磁盤占用 MB GB
數(shù)量 成百上千 一般幾十臺(tái)
隔離性 進(jìn)程級(jí)別 系統(tǒng)級(jí)別
操作系統(tǒng) 只支持Linux 幾乎所有
封裝程度 只打包項(xiàng)目代碼和依賴關(guān)系
共享宿主機(jī)內(nèi)核
完整的操作系統(tǒng)

1.4 Docker 跟 DevOps

DevOps 是一組過程、方法與系統(tǒng)的統(tǒng)稱,用于促進(jìn)開發(fā)(應(yīng)用程序/軟件工程)、技術(shù)運(yùn)營(yíng)和質(zhì)量保障(QA)部門之間的溝通、協(xié)作與整合。

 

DevOps 是兩個(gè)傳統(tǒng)角色 Dev(Development) 和 Ops(Operations) 的結(jié)合,Dev 負(fù)責(zé)開發(fā),Ops 負(fù)責(zé)部署上線,但 Ops 對(duì) Dev 開發(fā)的應(yīng)用缺少足夠的了解,而 Dev 來負(fù)責(zé)上線,很多服務(wù)軟件不知如何部署運(yùn)行,二者中間有一道明顯的鴻溝,DevOps 就是為了彌補(bǔ)這道鴻溝。DevOps 要做的事,是偏 Ops 的;但是做這個(gè)事的人,是偏 Dev 的, 說白了就是要有一個(gè)了解 Dev 的人能把 Ops 的事干了。而Docker 是適合 DevOps 的。

1.5 Docker 跟 k8s

k8s 的全稱是 kubernetes,它是基于容器的集群管理平臺(tái),是管理應(yīng)用的全生命周期的一個(gè)工具,從創(chuàng)建應(yīng)用、應(yīng)用的部署、應(yīng)用提供服務(wù)、擴(kuò)容縮容應(yīng)用、應(yīng)用更新、都非常的方便,而且可以做到故障自愈,例如一個(gè)服務(wù)器掛了,可以自動(dòng)將這個(gè)服務(wù)器上的服務(wù)調(diào)度到另外一個(gè)主機(jī)上進(jìn)行運(yùn)行,無(wú)需進(jìn)行人工干涉。k8s 依托于Google自家的強(qiáng)大實(shí)踐應(yīng)用,目前市場(chǎng)占有率已經(jīng)超過Docker自帶的Swarm了。

如果你有很多 Docker 容器要啟動(dòng)、維護(hù)、監(jiān)控,那就上k8s吧!

1.6 hello world

docker run hello-world 的大致流程圖如下:

 

2 Docker 常見指令

官方文檔:

https://docs.docker.com/engine/reference/commandline/build/

 

3 Docker 運(yùn)行原理

Docker 只提供一個(gè)運(yùn)行環(huán)境,他跟 VM 不一樣,是不需要運(yùn)行一個(gè)獨(dú)立的 OS,容器中的系統(tǒng)內(nèi)核跟宿主機(jī)的內(nèi)核是公用的。docker容器本質(zhì)上是宿主機(jī)的進(jìn)程。對(duì) Docker 項(xiàng)目來說,它最核心的原理實(shí)際上就是為待創(chuàng)建的用戶進(jìn)程做如下操作:

  1. 啟用 Linux Namespace 配置。
  2. 設(shè)置指定的 Cgroups 參數(shù)。
  3. 切換進(jìn)程的根目錄(Change Root),優(yōu)先使用 pivot_root 系統(tǒng)調(diào)用,如果系統(tǒng)不支持,才會(huì)使用 chroot。

3.1 namespace 進(jìn)程隔離

Linux Namespaces 機(jī)制提供一種進(jìn)程資源隔離方案。PID、IPC、Network 等系統(tǒng)資源不再是全局性的,而是屬于某個(gè)特定的Namespace。每個(gè)namespace下的資源對(duì)于其他namespace 下的資源都是透明,不可見的。系統(tǒng)中可以同時(shí)存在兩個(gè)進(jìn)程號(hào)為0、1、2的進(jìn)程,由于屬于不同的namespace,所以它們之間并不沖突。

 

PS:Linux 內(nèi)核提拱了6種 namespace 隔離的系統(tǒng)調(diào)用,如下圖所示。

 

3.2 CGroup 分配資源

Docker 通過 Cgroup 來控制容器使用的資源配額,一旦超過這個(gè)配額就發(fā)出OOM。配額主要包括 CPU、內(nèi)存、磁盤三大方面, 基本覆蓋了常見的資源配額和使用量控制。

Cgroup 是 Control Groups 的縮寫,是Linux 內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組所使用的物理資源(如 CPU、內(nèi)存、磁盤 IO 等等)的機(jī)制,被 LXC(Linux container)、Docker 等很多項(xiàng)目用于實(shí)現(xiàn)進(jìn)程資源控制。Cgroup 本身是提供將進(jìn)程進(jìn)行分組化管理的功能和接口的基礎(chǔ)結(jié)構(gòu),I/O 或內(nèi)存的分配控制等具體的資源管理是通過該功能來實(shí)現(xiàn)的,這些具體的資源 管理功能稱為 Cgroup 子系統(tǒng)。

 

3.3 chroot 跟 pivot_root 文件系統(tǒng)

chroot(change root file system)命令的功能是 改變進(jìn)程的根目錄到指定的位置。比如我們現(xiàn)在有一個(gè)$HOME/test目錄,想要把它作為一個(gè) /bin/bash 進(jìn)程的根目錄。

首先,創(chuàng)建一個(gè)目錄和幾個(gè)文件夾HOME/test/{bin,lib64,lib}

把bash命令拷貝到test目錄對(duì)應(yīng)的bin路徑下 cp -v /bin/{bash,ls} $HOME/test/bin

把bash命令需要的所有so文件,也拷貝到test目錄對(duì)應(yīng)的lib路徑下

執(zhí)行chroot命令,告訴操作系統(tǒng),我們將使用HOME/test /bin/bash

被chroot的進(jìn)程此時(shí)執(zhí)行 ls / 返回的都是$HOME/test目錄下面的內(nèi)容,Docker就是這樣實(shí)現(xiàn)容器根目錄的。為了能夠讓容器的這個(gè)根目錄看起來更真實(shí),一般在容器的根目錄下掛載一個(gè)完整操作系統(tǒng)的文件系統(tǒng),比如Ubuntu16.04的ISO。這樣在容器啟動(dòng)之后,容器里執(zhí)行l(wèi)s /查看到的就是Ubuntu 16.04的所有目錄和文件。

而掛載在容器根目錄上、用來為容器進(jìn)程提供隔離后執(zhí)行環(huán)境的文件系統(tǒng),就是所謂的容器鏡像。更專業(yè)的名字叫作:rootfs(根文件系統(tǒng))。所以一個(gè)最常見的 rootfs 會(huì)包括如下所示的一些目錄和文件:

  1. $ ls / 
  2. bin dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var 

chroot 只改變當(dāng)前進(jìn)程的 /,pivot_root改變當(dāng)前 mount namespace的 / 。pivot_root 可以認(rèn)為是 chroot 的改良版。

3.4 一致性

由于 rootfs 里打包的不只是應(yīng)用,而是整個(gè)操作系統(tǒng)的文件和目錄,也就意味著應(yīng)用以及它運(yùn)行所需要的所有依賴都被封裝在了一起。有了容器鏡像打包操作系統(tǒng)的能力,這個(gè)最基礎(chǔ)的依賴環(huán)境也終于變成了應(yīng)用沙盒的一部分。這就賦予了容器所謂的一致性:

無(wú)論在本地、云端,還是在一臺(tái)任何地方的機(jī)器上,用戶只需要解壓打包好的容器鏡像,那么這個(gè)應(yīng)用運(yùn)行所需要的完整的執(zhí)行環(huán)境就被重現(xiàn)出來了。

3.5 UnionFS 聯(lián)合文件系統(tǒng)

如何實(shí)現(xiàn)rootfs的高效可重復(fù)利用呢?Docker在鏡像的設(shè)計(jì)中引入了層(layer)的概念。也就是說用戶制作鏡像的每一步操作都會(huì)生成一個(gè)層,也就是一個(gè)增量rootfs。介紹分層前我們先說個(gè)重要知識(shí)點(diǎn),聯(lián)合文件系統(tǒng)。

聯(lián)合文件系統(tǒng)(UnionFS)是一種分層、輕量級(jí)并且高性能的文件系統(tǒng),它支持對(duì)文件系統(tǒng)的修改作為一次提交來一層層的疊加,同時(shí)可以將不同目錄掛載到同一個(gè)虛擬文件系統(tǒng)下。比如現(xiàn)在有水果fruits、蔬菜vegetables兩個(gè)目錄,其中水果中有蘋果和蕃茄,蔬菜有胡蘿卜和蕃茄:

  1. $ tree 
  2. ├── fruits 
  3. │  ├── apple 
  4. │  └── tomato 
  5. └── vegetables 
  6.   ├── carrots 
  7.   └── tomato 

然后使用聯(lián)合掛載的方式將這兩個(gè)目錄掛載到一個(gè)公共的目錄 mnt 上:

  1. $ mkdir mnt 
  2. $ sudo mount -t aufs -o dirs=./fruits:./vegetables none ./mnt 

這時(shí)再查看目錄 mnt 的內(nèi)容,就能看到目錄 fruits 和 vegetables 下的文件被合并到了一起:

  1. $ tree ./mnt 
  2. ./mnt 
  3. ├── apple 
  4. ├── carrots 
  5. └── tomato 

可以看到在 mnt 目錄下有三個(gè)文件,蘋果apple、胡蘿卜carrots和蕃茄tomato。水果和蔬菜的目錄被union到了 mnt 目錄下了。

  1. $ echo mnt > ./mnt/apple 
  2.  $ cat ./mnt/apple 
  3.  mnt 
  4.  $ cat ./fruits/apple 
  5.  mnt 

可以看到./mnt/apple的內(nèi)容改了,./fruits/apple的內(nèi)容也改了。

  1. $ echo mnt_carrots > ./mnt/carrots 
  2. $ cat ./vegetables/carrots 
  3. old 
  4. $ cat ./fruits/carrots 
  5. mnt_carrots 

./vegetables/carrots 并沒有變化,反而是 ./fruits/carrots 的目錄中出現(xiàn)了 carrots 文件,其內(nèi)容是我們?cè)? ./mnt/carrots 里的內(nèi)容。

結(jié)論:

在mount aufs命令時(shí)候,沒有對(duì) vegetables 跟 fruits 設(shè)置權(quán)限,默認(rèn)命令行上第一個(gè)的目錄是可讀可寫的,后面的全都是只讀的。有重復(fù)的文件名,在mount命令行上,越往前的被操作的優(yōu)先級(jí)越高。

3.6 layer 分層

說完聯(lián)合文件系統(tǒng)后我們?cè)僬f下Docker中的分層,鏡像可以通過分層來進(jìn)行繼承,基于基礎(chǔ)鏡像(沒有父鏡像)用戶可以制作各種具體的應(yīng)用鏡像。不同 Docker 容器可以共享一些基礎(chǔ)的文件系統(tǒng)層,同時(shí)再加上自己獨(dú)有的改動(dòng)層,大大提高了存儲(chǔ)的效率。

Docker 中使用一種叫 AUFS(Anothe rUnionFS)的聯(lián)合文件系統(tǒng)。AUFS 支持為每一個(gè)成員目錄設(shè)定不同的讀寫權(quán)限。

  1. rw 表示可寫可讀read-write。
  2. ro 表示read-only,如果你不指權(quán)限,那么除了第一個(gè)外,ro是默認(rèn)值,對(duì)于ro分支,其永遠(yuǎn)不會(huì)收到寫操作,也不會(huì)收到查找whiteout的操作。
  3. rr 表示 real-read-only,與read-only不同的是,rr 標(biāo)記的是天生就是只讀的分支,這樣,AUFS可以提高性能,比如不再設(shè)置inotify來檢查文件變動(dòng)通知。

當(dāng)我們想修改ro層的文件時(shí)咋辦?因?yàn)閞o是不允許修改的啊!Docker中一般ro層還帶個(gè)wh的能力。我們就需要對(duì)這個(gè)ro目錄里的文件作whiteout。AUFS的whiteout的實(shí)現(xiàn)是通過在上層的可寫的目錄下建立對(duì)應(yīng)的whiteout隱藏文件來實(shí)現(xiàn)的。比如我們有三個(gè)目錄和文件如下所示:

  1. $ tree 
  2. ├── fruits 
  3. │   ├── apple 
  4. │   └── tomato 
  5. ├── test #目錄為空 
  6. └── vegetables 
  7.     ├── carrots 
  8.     └── tomato 

執(zhí)行如下:

  1. $ mkdir mnt 
  2. $ mount -t aufs -o dirs=./test=rw:./fruits=ro:./vegetables=ro none ./mnt 
  3. $ ls ./mnt/ 
  4. apple  carrots  tomato 

在權(quán)限為 rw 的 test 目錄下建個(gè) whiteout 的隱藏文件 .wh.apple,你就會(huì)發(fā)現(xiàn) ./mnt/apple 這個(gè)文件就消失了,跟執(zhí)行了 rm ./mnt/apple 是一樣的結(jié)果:

  1. $ touch ./test/.wh.apple 
  2.  $ ls ./mnt 
  3.  carrots  tomato 

對(duì)于AUFS來說鏡像的若干基礎(chǔ)層放置在/var/lib/docker/aufs/diff目錄下,然后通過查詢/sys/fs/aufs 查看被聯(lián)合掛載在一起的各個(gè)層的信息,多個(gè)基礎(chǔ)層最終被聯(lián)合掛載在/var/lib/docker/aufs/mnt里面,這里面存儲(chǔ)的就是一個(gè)成品。

Docker 目前支持的聯(lián)合文件系統(tǒng)包括 OverlayFS, AUFS, Btrfs, VFS, ZFS 和 Device Mapper。推薦使用 overlay2 存儲(chǔ)驅(qū)動(dòng),overlay2 是目前 Docker 默認(rèn)的存儲(chǔ)驅(qū)動(dòng),以前則是 AUFS。

3.6.1 只讀層

我們以Ubuntu為例,當(dāng)執(zhí)行docker image inspect ubuntu:latest 會(huì)發(fā)現(xiàn)容器的rootfs最下面的四層,對(duì)應(yīng)的正是ubuntu:latest鏡像的四層。它們的掛載方式都是只讀的(ro+wh),都以增量的方式分別包含了Ubuntu操作系統(tǒng)的一部分,四層聯(lián)合起來組成了一個(gè)成品。

3.6.2 可讀寫層

rootfs 最上層的操作權(quán)限為 rw, 在沒有寫入文件之前,這個(gè)目錄是空的。而一旦在容器里做了寫操作,你修改產(chǎn)生的內(nèi)容就會(huì)以增量的方式出現(xiàn)在這個(gè)層中。如果你想刪除只讀層里的文件,咋辦呢?這個(gè)問題上面已經(jīng)講解過了。

最上面這個(gè)可讀寫層就是專門用來存放修改 rootfs 后產(chǎn)生的增量,無(wú)論是增、刪、改,都發(fā)生在這里。而當(dāng)我們使用完了這個(gè)被修改過的容器之后,還可以使用 docker commit 和 push 指令,保存這個(gè)被修改過的可讀寫層,并上傳到 Docker Hub上,供其他人使用。并且原先的只讀層里的內(nèi)容則不會(huì)有任何變化,這就是增量 rootfs 的好處。

3.6.3 init 層

它是一個(gè)以-init結(jié)尾的層,夾在只讀層和讀寫層之間。Init層是Docker項(xiàng)目單獨(dú)生成的一個(gè)內(nèi)部層,專門用來存放 /etc/hosts 等信息。

需要這樣一層的原因是這些文件本來屬于只讀的Ubuntu鏡像的一部分,但是用戶往往需要在啟動(dòng)容器時(shí)寫入一些指定的值比如 hostname,那就需要在可讀寫層對(duì)它們進(jìn)行修改??墒?,這些修改往往只對(duì)當(dāng)前的容器有效,我們并不希望執(zhí)行 docker commit 時(shí),把 init 層的信息連同可讀寫層一起提交。

最后這6層被組合起來形成了一個(gè)完整的 Ubuntu 操作系統(tǒng)供容器使用。

 

4 Docker 網(wǎng)絡(luò)

由上面的 Docker 原理可知 Docker 使用了 Linux 的 Namespaces 技術(shù)來進(jìn)行資源隔離,如 PID Namespace 隔離進(jìn)程,Mount Namespace 隔離文件系統(tǒng),Network Namespace 隔離網(wǎng)絡(luò)等。一個(gè)Network Namespace 提供了一份獨(dú)立的網(wǎng)絡(luò)環(huán)境(包括網(wǎng)卡、路由、Iptable規(guī)則)與其他的Network Namespace隔離,一個(gè)Docker容器一般會(huì)分配一個(gè)獨(dú)立的Network Namespace。

當(dāng)你安裝Docker時(shí),執(zhí)行docker network ls會(huì)發(fā)現(xiàn)它會(huì)自動(dòng)創(chuàng)建三個(gè)網(wǎng)絡(luò)。

  1. [root@server1 ~]$ docker network ls 
  2. NETWORK ID          NAME                DRIVER              SCOPE 
  3. 0147b8d16c64        bridge              bridge              local 
  4. 2da931af3f0b        host                host                local 
  5. 63d31338bcd9        none                null                local 

我們?cè)谑褂胐ocker run創(chuàng)建Docker容器時(shí),可以用 --net 選項(xiàng)指定容器的網(wǎng)絡(luò)模式,Docker可以有以下4種網(wǎng)絡(luò)模式:

網(wǎng)絡(luò)模式 使用注意
host 和宿主機(jī)共享網(wǎng)絡(luò)
none 不配置網(wǎng)絡(luò)
bridge docker默認(rèn),也可自創(chuàng)
container 容器網(wǎng)絡(luò)連通,容器直接互聯(lián),用的很少

4.1 Host 模式

等價(jià)于Vmware中的橋接模式,當(dāng)啟動(dòng)容器的時(shí)候用host模式,容器將不會(huì)虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。但是容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。

4.2 Container 模式

Container 模式指定新創(chuàng)建的容器和已經(jīng)存在的一個(gè)容器共享一個(gè) Network Namespace,而不是和宿主機(jī)共享。新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的IP,而是和一個(gè)指定的容器共享IP、端口范圍等。同樣,兩個(gè)容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的。兩個(gè)容器的進(jìn)程可以通過lo網(wǎng)卡設(shè)備通信。

4.3 None 模式

None 模式將容器放置在它自己的網(wǎng)絡(luò)棧中,并不進(jìn)行任何配置。實(shí)際上,該模式關(guān)閉了容器的網(wǎng)絡(luò)功能,該模式下容器并不需要網(wǎng)絡(luò)(例如只需要寫磁盤卷的批處理任務(wù))。

4.4 Bridge 模式

Bridge 模式是 Docker 默認(rèn)的網(wǎng)絡(luò)設(shè)置,此模式會(huì)為每一個(gè)容器分配 Network Namespace、設(shè)置IP等。當(dāng)Docker Server啟動(dòng)時(shí),會(huì)在主機(jī)上創(chuàng)建一個(gè)名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動(dòng)的Docker容器會(huì)連接到這個(gè)虛擬網(wǎng)橋上。虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,主機(jī)上的所有容器就通過交換機(jī)連在了一個(gè)二層網(wǎng)絡(luò)中。

 

Docker 會(huì)從RFC1918所定義的私有IP網(wǎng)段中,選擇一個(gè)和宿主機(jī)不同的IP地址和子網(wǎng)分配給docker0,連接到 docker0 的容器從子網(wǎng)中選擇個(gè)未占用 IP 使用。一般 Docker 會(huì)用 172.17.0.0/16 這個(gè)網(wǎng)段,并將172.17.0.1/16 分配給 docker0 網(wǎng)橋(在主機(jī)上使用ifconfig命令是可以看到docker0的,可以認(rèn)為它是網(wǎng)橋的管理接口,在宿主機(jī)上作為一塊虛擬網(wǎng)卡使用)。

網(wǎng)絡(luò)配置的過程大致3步:

在主機(jī)上創(chuàng)建一對(duì)虛擬網(wǎng)卡 veth pair 設(shè)備。veth設(shè)備總是成對(duì)出現(xiàn)的,它們組成了一個(gè)數(shù)據(jù)的通道,數(shù)據(jù)從一個(gè)設(shè)備進(jìn)入,就會(huì)從另一個(gè)設(shè)備出來。因此veth設(shè)備常用來連接兩個(gè)網(wǎng)絡(luò)設(shè)備。

  1. Docker 將 veth pair 設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0。另一端放在主機(jī)中,以veth65f9 這樣類似的名字命名,并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中,可以通過brctl show命令查看。
  2. 從 docker0 子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置 docker0 的IP地址為容器的默認(rèn)網(wǎng)關(guān)。
  3. Bridge 模式下容器的通信

容器訪問外部

假設(shè)主機(jī)網(wǎng)卡為eth0,IP地址10.10.101.105/24,網(wǎng)關(guān)10.10.101.254。從主機(jī)上一個(gè)IP為172.17.0.1/16 的容器中ping百度(180.76.3.151)。首先IP包從容器發(fā)往自己的默認(rèn)網(wǎng)關(guān) docker0,包到達(dá)docker0后,會(huì)查詢主機(jī)的路由表,發(fā)現(xiàn)包應(yīng)該從主機(jī)的 eth0 發(fā)往主機(jī)的網(wǎng)關(guān)10.10.105.254/24。接著包會(huì)轉(zhuǎn)發(fā)給eth0,并從eth0發(fā)出去。這時(shí)Iptable規(guī)則就會(huì)起作用,將源地址換為 eth0 的地址。這樣,在外界看來,這個(gè)包就是從10.10.101.105上發(fā)出來的,Docker容器對(duì)外是不可見的。

外部訪問容器

創(chuàng)建容器并將容器的80端口映射到主機(jī)的80端口。當(dāng)我們對(duì)主機(jī) eth0 收到的目的端口為80的訪問時(shí)候,Iptable規(guī)則會(huì)進(jìn)行DNAT轉(zhuǎn)換,將流量發(fā)往172.17.0.2:80,也就是我們上面創(chuàng)建的Docker容器。所以,外界只需訪問10.10.101.105:80就可以訪問到容器中的服務(wù)。

4.5 --link

容器創(chuàng)建后我們想通過容器名字來ping。此時(shí)需要用到--link,如下:

  1. docker run -d -P --name linux03 --link linux02 linux 
  2. docker exec -it linux03 ping linux02 可ping通。 
  3. docker exec -it linux02 ping linux03 不可ping通。 

追本溯源 看下 linux03 的 /etc/hosts 會(huì)發(fā)現(xiàn)本質(zhì)只是做了個(gè)host映射。

  1. 172.17.0.3 linux03 12ft4tesa # 跟Windows的host文件一樣,只是做了地址綁定 

4.6 自建Bridge

我們之前直接啟動(dòng)的命令 (默認(rèn)是使用--net bridge,可省),這個(gè)bridge就是我們的docker0。下面?zhèn)z是等價(jià)的。

  1. docker run -d -P --name linux01 LinuxSelf 
  2. docker run -d -P --name linux01 --net bridge LinuxSelf 

docker0默認(rèn)不支持域名訪問 , 只能用 --link 打通連接。如果我們使用自定義的網(wǎng)絡(luò)時(shí),docker底層已經(jīng)幫我們維護(hù)好了對(duì)應(yīng)關(guān)系,可以實(shí)現(xiàn)域名訪問。

  1. --driver bridge 網(wǎng)絡(luò)模式定義為 :橋接  
  2. --subnet 192.168.0.0/16 定義子網(wǎng) ,范圍為:192.168.0.2 ~ 192.168.255.255  
  3. --gateway 192.168.0.1 子網(wǎng)網(wǎng)關(guān)設(shè)為: 192.168.0.1  
  4. docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 

接下來

  1. docker run -d -P --name linux-net-01 --net mynet LinuxSelf 
  2. docker run -d -P --name linux-net-02 --net mynet LinuxSelf 
  3. docker exec -it linux-net-01 ping linux-net-02的IP  # 結(jié)果OK 
  4. docker exec -it linux-net-01 ping linux-net-02     # 結(jié)果OK 

5 可視化界面

5.1 Portainer

Portainer 是 Docker 的圖形化管理工具,提供狀態(tài)顯示面板、應(yīng)用模板快速部署、容器鏡像網(wǎng)絡(luò)數(shù)據(jù)卷的基本操作(包括上傳下載鏡像,創(chuàng)建容器等操作)、事件日志顯示、容器控制臺(tái)操作、Swarm集群和服務(wù)等集中管理和操作、登錄用戶管理和控制等功能。功能十分全面,基本能滿足中小型單位對(duì)容器管理的全部需求。

5.2 DockerUI

DockerUI基于Docker API,提供等同Docker命令行的大部分功能,支持container管理,image管理。不過DockerUI一個(gè)致命的缺點(diǎn)就是 不支持多主機(jī)。

5.3 Shipyard

Shipyard 是一個(gè)集成管理docker容器、鏡像、Registries的系統(tǒng),它可以簡(jiǎn)化對(duì)橫跨多個(gè)主機(jī)的Docker容器集群進(jìn)行管理. 通過Web用戶界面,你可以大致瀏覽相關(guān)信息,比如你的容器在使用多少處理器和內(nèi)存資源、在運(yùn)行哪些容器,還可以檢查所有集群上的事件日志。

6 Docker 學(xué)習(xí)指南

本來也想寫常見指令、Dockerfile、Docker Compose、Docker Swarm的,不過感覺還是拉閘吧,官方文檔他不香啊!推薦幾個(gè)學(xué)習(xí)指南。

官方文檔:https://docs.docker.com/engine/reference/commandline/build/

從入門到實(shí)踐:https://github.com/yeasy/docker_practice

 

在線教程:https://vuepress.mirror.docker-practice.com

 

責(zé)任編輯:武曉燕 來源: sowhat1412
相關(guān)推薦

2021-05-17 08:37:46

GETPOSTHTTP

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring編程

2025-03-07 00:00:10

2020-12-09 10:29:53

SSH加密數(shù)據(jù)安全

2024-02-29 16:49:20

volatileJava并發(fā)編程

2024-11-19 15:13:02

2024-08-29 16:30:27

2023-12-27 18:16:39

MVCC隔離級(jí)別幻讀

2025-04-16 00:00:01

JWT客戶端存儲(chǔ)加密令

2024-08-12 17:36:54

2024-03-14 14:56:22

反射Java數(shù)據(jù)庫(kù)連接

2024-03-28 10:37:44

IoC依賴注入依賴查找

2024-07-31 08:28:37

DMAIOMMap

2024-12-06 07:00:00

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2021-05-20 08:34:03

CDN原理網(wǎng)絡(luò)

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2024-03-22 06:56:24

零拷貝技術(shù)數(shù)據(jù)傳輸數(shù)據(jù)拷貝

2024-06-04 09:02:03

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)