萬(wàn)字長(zhǎng)文深入理解Docker鏡像分層原理啡捶、容器數(shù)據(jù)卷、網(wǎng)絡(luò)通信架構(gòu)(Docker系列第2章奸焙,共3章)

鏡像分層的簡(jiǎn)單直觀體現(xiàn)

在執(zhí)行docker pull時(shí)瞎暑,會(huì)發(fā)現(xiàn)多個(gè)Pull complete 字樣彤敛,就能體現(xiàn)分層,如果是一個(gè)文件了赌,只會(huì)有一個(gè)Pull complete 墨榄。

docker pull redis
Using default tag: latest
latest: Pulling from library/redis
a2abf6c4d29d: Already exists 
c7a4e4382001: Pull complete 
4044b9ba67c9: Pull complete 
c8388a79482f: Pull complete 
413c8bb60be2: Pull complete 
1abfd3011519: Pull complete 
Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

文件系統(tǒng)

  • 概念:文件系統(tǒng)是計(jì)算機(jī)系統(tǒng)中用于組織和管理數(shù)據(jù)存儲(chǔ)的一種方式。它定義了數(shù)據(jù)如何存儲(chǔ)勿她、命名袄秩、訪問(wèn)和修改的方式。
  • 舉例:如Windows自帶的NTFS逢并、FAT32之剧、EXFAT,和Linux中的EXT3砍聊、EXT4這種的背稼。
  • FAT32:有著很好的兼容性,但是不支持單個(gè)大于4GB的文件玻蝌,U盤空間充足卻放不下大文件蟹肘,就是這個(gè)原因「┦鳎可以格式化后換一個(gè)文件系統(tǒng)解決帘腹。
  • NTFS:NTFS是Windows操作系統(tǒng)中最常用的文件系統(tǒng)之一,它支持大容量硬盤和大文件聘萨,提供了較好的安全性竹椒、穩(wěn)定性和恢復(fù)能力。
  • EXFAT:為了解決FAT32不支持單個(gè)大于4GB的文件而誕生米辐。

操作系統(tǒng)的引導(dǎo)

  • 概括:操作系統(tǒng)的引導(dǎo)(Bootstrapping)是指在計(jì)算機(jī)啟動(dòng)時(shí)胸完,通過(guò)加載操作系統(tǒng)的核心組件和必要的驅(qū)動(dòng)程序,使得計(jì)算機(jī)能夠進(jìn)入操作系統(tǒng)的運(yùn)行狀態(tài)翘贮。引導(dǎo)過(guò)程通常包括以下幾個(gè)步驟:
  1. 加電自檢(Power-On Self-Test赊窥,POST):計(jì)算機(jī)啟動(dòng)時(shí),會(huì)執(zhí)行自檢程序狸页,檢查硬件是否正常锨能。如果自檢過(guò)程中發(fā)現(xiàn)硬件故障,計(jì)算機(jī)可能會(huì)發(fā)出警報(bào)或者停止啟動(dòng)芍耘。
  2. BIOS/UEFI初始化:計(jì)算機(jī)啟動(dòng)后址遇,會(huì)加載基本輸入/輸出系統(tǒng)(Basic Input/Output System,BIOS)或統(tǒng)一可擴(kuò)展固件接口(Unified Extensible Firmware Interface斋竞,UEFI)倔约,進(jìn)行硬件初始化和系統(tǒng)設(shè)置。
  3. 引導(dǎo)加載程序(Bootloader)啟動(dòng):BIOS/UEFI會(huì)尋找引導(dǎo)加載程序坝初,一般位于硬盤的引導(dǎo)扇區(qū)(Boot Sector)或其他可引導(dǎo)的介質(zhì)(如USB閃存驅(qū)動(dòng)器)浸剩。引導(dǎo)加載程序的主要任務(wù)是加載操作系統(tǒng)的內(nèi)核鏡像到內(nèi)存中钾军,并執(zhí)行操作系統(tǒng)的初始化。
  4. 內(nèi)核初始化:一旦操作系統(tǒng)的內(nèi)核鏡像被加載到內(nèi)存中绢要,引導(dǎo)加載程序?qū)⒖刂茩?quán)轉(zhuǎn)交給操作系統(tǒng)內(nèi)核吏恭。內(nèi)核開始初始化系統(tǒng)的各個(gè)部分,包括設(shè)備驅(qū)動(dòng)程序重罪、文件系統(tǒng)等樱哼。
  5. 用戶空間初始化:內(nèi)核完成初始化后,操作系統(tǒng)開始啟動(dòng)用戶空間的進(jìn)程蛆封,包括系統(tǒng)服務(wù)和用戶登錄界面唇礁。

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

聯(lián)合文件系統(tǒng)(UFS),是一種分層的高性能文件系統(tǒng)惨篱,支持對(duì)文件系統(tǒng)的修改作為一次提交來(lái)層層疊加盏筐。
docker用它作為鏡像的存儲(chǔ)方式,使得容器在運(yùn)行時(shí)只需存儲(chǔ)修改過(guò)的部分砸讳,而不是整個(gè)文件系統(tǒng)琢融,從而節(jié)省存儲(chǔ)空間并提高效率。

為什么docker用UFS

  • 共享和復(fù)用:UFS 允許多個(gè)容器共享相同的基礎(chǔ)鏡像層簿寂,這樣可以節(jié)省存儲(chǔ)空間漾抬,并減少容器的創(chuàng)建和啟動(dòng)時(shí)間。當(dāng)多個(gè)容器共享相同的文件系統(tǒng)層時(shí)常遂,這些層中的文件和資源只需存儲(chǔ)一次纳令,而不是每個(gè)容器都存儲(chǔ)一份。這和代碼是一樣的克胳,封裝的方法拆分的越小平绩,可復(fù)用性就會(huì)更好。
  • 寫時(shí)復(fù)制(Copy-on-Write):UFS 允許容器在運(yùn)行時(shí)進(jìn)行讀寫操作漠另,同時(shí)保留了鏡像的不可變性捏雌。當(dāng)容器對(duì)文件系統(tǒng)進(jìn)行修改時(shí),UFS 會(huì)將修改的內(nèi)容寫入新的層中笆搓,而不會(huì)直接修改原始鏡像層性湿,這樣可以確保容器之間的隔離性,并且不會(huì)影響其他容器或原始鏡像满败。
  • 快速啟動(dòng)和部署:由于 UFS 允許容器共享文件系統(tǒng)層并利用寫時(shí)復(fù)制機(jī)制肤频,因此容器的創(chuàng)建和啟動(dòng)速度非常快算墨。Docker 可以快速地在現(xiàn)有鏡像的基礎(chǔ)上創(chuàng)建新的容器實(shí)例宵荒,并立即啟動(dòng)運(yùn)行,這對(duì)于實(shí)現(xiàn)快速部署和橫向擴(kuò)展至關(guān)重要。
  • 輕量級(jí):UFS 提供了一種輕量級(jí)的文件系統(tǒng)封裝方式骇扇,它不需要完整地復(fù)制整個(gè)文件系統(tǒng),而是在需要修改文件時(shí)才進(jìn)行復(fù)制和修改面粮,這樣可以節(jié)省存儲(chǔ)空間并減少資源消耗少孝,下文會(huì)講。

深入理解Docker鏡像分層加載原理

  • 簡(jiǎn)易概括:在BootFS(宿主機(jī)提供)的基礎(chǔ)上熬苍,利用UFS封裝RootFS稍走,使用鏡像層的數(shù)據(jù),疊加出一個(gè)可寫的容器層柴底。
    所以說(shuō)婿脸,docker pull下來(lái)的CentOS、Ubuntu發(fā)行版柄驻,才很小狐树,一個(gè)原因是省掉了BootFS,另一個(gè)原因是拋棄了很多非核心的組件鸿脓,如vim等抑钟。


  • BootFS:引導(dǎo)文件系統(tǒng)(boot filesystem)是指用于引導(dǎo)操作系統(tǒng)的文件系統(tǒng)。這個(gè)文件系統(tǒng)通常包含了引導(dǎo)加載程序(boot loader)所需的文件野哭,例如引導(dǎo)配置文件在塔、內(nèi)核以及其他引導(dǎo)所需的文件,docker用宿主機(jī)的內(nèi)核拨黔,出處就是這里蛔溃。

  • RootFS:在 Linux 中,rootfs(root file system)是指操作系統(tǒng)啟動(dòng)后的根文件系統(tǒng)篱蝇,它包含了整個(gè)文件系統(tǒng)的目錄結(jié)構(gòu)和文件贺待,提供了用戶空間程序運(yùn)行所需的基本文件和資源,例如根目錄下的幾個(gè)目錄态兴。

  • 鏡像層:只讀的狠持,包含了應(yīng)用程序運(yùn)行所需的所有文件和依賴項(xiàng)。

  • 容器層:可寫的瞻润,當(dāng)容器啟動(dòng)時(shí)喘垂,一個(gè)新的容器層被加載到容器的頂部,用來(lái)支撐數(shù)據(jù)變化的存儲(chǔ)绍撞。

上下層級(jí)關(guān)系是這樣的:
docker的UFS管理了最上面的3層正勒,利用寫時(shí)復(fù)制(Copy-on-Write)的機(jī)制,當(dāng)容器需要修改文件時(shí)傻铣,UFS 會(huì)在容器層中進(jìn)行寫操作章贞,而不會(huì)直接修改鏡像層中的文件。這樣可以保證鏡像的不可變性非洲,同時(shí)允許容器進(jìn)行靈活的讀寫操作鸭限。
新的容器又可以commit成一個(gè)新的鏡像蜕径,這個(gè)新的鏡像基礎(chǔ)上,又可以堆疊更多的容器败京,層層累加兜喻。

              --容器層--
           -----鏡像層------
      ----------RootFS----------
----------------BootFS----------------

容器數(shù)據(jù)卷

  • 極簡(jiǎn)概括:容器數(shù)據(jù)卷,容器卷赡麦、數(shù)據(jù)卷朴皆、一個(gè)概念,將宿主機(jī)中的目錄或文件掛載到容器中泛粹,從而讓容器和宿主機(jī)共同讀寫這塊的數(shù)據(jù)遂铡。并且在容器銷毀時(shí),容器卷的數(shù)據(jù)不會(huì)丟失晶姊。
  • 用法:docker run --name name1 [-it/-d] -v /宿主機(jī)絕對(duì)路徑:/容器內(nèi)絕對(duì)路徑 --privileged=true 鏡像id [/bin/bash]
  • 備注:-v是volume的首字母扒接,掛載目錄默認(rèn)是讀寫權(quán)限,但是目錄本身容器內(nèi)部刪不掉(極少需要?jiǎng)h除),如果宿主機(jī)沒有這個(gè)目錄们衙,只要權(quán)限充足珠增,它會(huì)自動(dòng)創(chuàng)建。
  • 適用場(chǎng)景:
    • 數(shù)據(jù)備份:當(dāng)容器被誤刪砍艾,或者容器內(nèi)的組件因故障無(wú)法運(yùn)行時(shí)蒂教,容器卷的數(shù)據(jù)保留的好好的,這算是一種容災(zāi)脆荷。
    • 數(shù)據(jù)互通:容器內(nèi)的組件凝垛,和容器外的系統(tǒng),可以共享這塊數(shù)據(jù)的讀寫蜓谋,實(shí)時(shí)的梦皮,這對(duì)開發(fā)者、運(yùn)維人員很友好桃焕。
    • 同步日志和數(shù)據(jù):很多組件剑肯,應(yīng)用、日志观堂、數(shù)據(jù)是可以分開的让网,所以就可以把日志,數(shù)據(jù)师痕,放進(jìn)多個(gè)數(shù)據(jù)卷溃睹。
  • 優(yōu)點(diǎn):
    • 上文的適用場(chǎng)景,就是兩個(gè)優(yōu)點(diǎn)胰坟。
    • 易于備份:通過(guò)使用容器卷因篇,可以輕松地備份和恢復(fù)數(shù)據(jù),而不需要備份整個(gè)容器。
  • 缺點(diǎn):
    • 復(fù)雜化:對(duì)于新手竞滓,或者剛接觸新服務(wù)器的運(yùn)維人員咐吼,多容器下的容器卷管理,使得運(yùn)維工作錯(cuò)綜復(fù)雜商佑。
    • 高可用問(wèn)題:MySQL不推薦在docker中汽烦,其中一個(gè)就是數(shù)據(jù)的高可用問(wèn)題,MySQL減少保障故障時(shí)數(shù)據(jù)丟失問(wèn)題和維護(hù)高可用帶來(lái)的性能問(wèn)題莉御,使用了3種不同的redo log刷盤機(jī)制作為保障,但是又加了一個(gè)容器卷環(huán)節(jié)俗冻,多了一個(gè)環(huán)節(jié)礁叔,就有可能在這上面出故障,尤其是MySQL這種需要環(huán)境極度穩(wěn)定的組件迄薄。

使用容器卷記得添加--privileged=true

使容器具有完全可控的權(quán)限琅关,防止出現(xiàn)Permission denied的錯(cuò)誤。
注意是等號(hào)讥蔽,不是空格涣易,有個(gè)d。

容器數(shù)據(jù)卷實(shí)操

對(duì)數(shù)據(jù)同步的測(cè)試

docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
進(jìn)入ubuntu容器后
cd /test
touch a
開啟另一個(gè)宿主機(jī)終端
touch b
容器和宿主機(jī)互相l(xiāng)s冶伞,發(fā)現(xiàn)都有a新症、b兩個(gè)文件

使用inspect命令查看掛載相關(guān)配置

docker inspect 容器id
找到Mounts段,
"Mounts": [
    {
        "Type": "bind",
        "Source": "/test",
        "Destination": "/test",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],


Type: 指定了數(shù)據(jù)卷的類型响禽,這里是bind徒爹,表示這是一個(gè)綁定掛載,即將宿主機(jī)上的一個(gè)目錄掛載到容器內(nèi)部芋类。
Source: 指定了數(shù)據(jù)卷的來(lái)源隆嗅,這里是/test,表示宿主機(jī)上的目錄路徑侯繁。
Destination: 指定了數(shù)據(jù)卷在容器內(nèi)的掛載目標(biāo)路徑胖喳,這里也是/test,表示容器內(nèi)部的路徑贮竟。
Mode: 這個(gè)字段可以用來(lái)指定掛載的權(quán)限模式丽焊,但在這個(gè)配置中為空,表示使用默認(rèn)權(quán)限咕别。
RW: 表示是否以讀寫模式掛載粹懒,這里是true,表示掛載為讀寫模式顷级。
Propagation: 指定了掛載點(diǎn)的傳播屬性凫乖,這里是rprivate,表示掛載點(diǎn)將會(huì)被私有化傳播,即只會(huì)影響到當(dāng)前容器的進(jìn)程帽芽,不會(huì)傳播到其他容器删掀。

故障情況下,容器卷內(nèi)容的情況

停止容器
docker stop ea03c5ef1025
在宿主機(jī)內(nèi)导街,創(chuàng)建文件
touch /test/c
開啟
docker start ea03c5ef1025
進(jìn)入容器
docker exec -it ea03c5ef1025 /bin/bash
此時(shí)發(fā)現(xiàn)c依舊存在
ls /test


宿主機(jī)誤刪容器(強(qiáng)制)
docker rm -f ea03c5ef1025
發(fā)現(xiàn)a披泪、b、c3個(gè)文件都在搬瑰。
ls /
重新創(chuàng)建新的容器
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
進(jìn)入容器后款票,發(fā)現(xiàn)a、b泽论、c 3個(gè)文件都在艾少。
ls /

容器數(shù)據(jù)卷的rw與ro兩種讀寫權(quán)限

rw:默認(rèn)值,雙方各有讀寫權(quán)限翼悴。

執(zhí)-v命令時(shí)缚够,默認(rèn)是讀寫權(quán)限,以下兩個(gè)命令是相等的鹦赎。
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test:rw b3797fa08f5b /bin/bash

ro:宿主機(jī)的文件可以同步給容器谍椅,但容器無(wú)法更改。

某些情況下古话,需要將宿主機(jī)映射的目錄雏吭,讓容器只有只讀權(quán)限,read only陪踩,可以這樣做:
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test:ro b3797fa08f5b /bin/bash

進(jìn)入容器思恐,測(cè)試容器內(nèi)寫入
touch /test/d
touch: cannot touch 'd': Read-only file system

進(jìn)入宿主機(jī)終端,測(cè)試文件寫入:
touch /test/d
宿主機(jī)成功寫入

進(jìn)入容器膊毁,查看容器是否同步胀莹,發(fā)現(xiàn)已經(jīng)同步
ls /test/d
a  b  c  d

容器數(shù)據(jù)卷的繼承

卷的繼承需要“--volumes-from 父容器卷” 來(lái)聲明,具有父子關(guān)系的容器卷還是互相共享關(guān)系婚温,父子間并沒有強(qiáng)關(guān)聯(lián)描焰,意味著父容器停了或被刪除,不影響子容器栅螟。

請(qǐng)空容器荆秦,方便測(cè)試。
docker rm -f 4432fa5f2d07
并刪除/test下所有文件
rm -f /test/*
啟動(dòng)一個(gè)父容器
docker run --name parent --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
啟動(dòng)一個(gè)子容器
docker run --name son --privileged=true -it --volumes-from parent b3797fa08f5b /bin/bash
宿主機(jī)查看正在運(yùn)行的容器實(shí)例
docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
5ff477d6b3ec   b3797fa08f5b   "/bin/bash"   5 minutes ago   Up 4 minutes             son
a4da63aca520   b3797fa08f5b   "/bin/bash"   6 minutes ago   Up 6 minutes             parent

宿主機(jī)創(chuàng)建a文件
touch /test/a
兩個(gè)容器上查看力图,發(fā)現(xiàn)a文件都存在步绸。
touch /test

父級(jí)故障模擬,測(cè)試父子關(guān)聯(lián)性吃媒,結(jié)果得出父子間沒有強(qiáng)關(guān)聯(lián)性瓤介。

在宿主機(jī)上停止父級(jí)容器
docker stop a4da63aca520
在宿主機(jī)上創(chuàng)建文件
touch /test/b
在son容器上執(zhí)行l(wèi)s吕喘,發(fā)現(xiàn)有a、b兩個(gè)文件
ls /test
a b


在宿主機(jī)上刪除父級(jí)容器
docker rm a4da63aca520
在宿主機(jī)上創(chuàng)建文件
touch /test/c
在son容器上執(zhí)行l(wèi)s刑桑,發(fā)現(xiàn)有a氯质、b、c兩個(gè)文件
ls /test
a b c

容器卷的多樣化共享

多容用一卷:

強(qiáng)制刪除所有容器祠斧,能不用則不用闻察。
docker rm -f $(docker ps -aq)
刪除宿主機(jī)下,容器卷目錄所有文件
rm -f /test/*

開3個(gè)終端琢锋,創(chuàng)建3個(gè)容器
docker run --name one --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name two --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name three --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash

查看是否開啟成功
docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
8ed7a2356d5c   b3797fa08f5b   "/bin/bash"   17 seconds ago   Up 10 seconds             three
ff2b2a92d984   b3797fa08f5b   "/bin/bash"   26 seconds ago   Up 25 seconds             two
220539fdf650   b3797fa08f5b   "/bin/bash"   54 seconds ago   Up 53 seconds             one

宿主機(jī)創(chuàng)建a文件
touch /test/a

三個(gè)容器分別執(zhí)行l(wèi)s /test辕漂,發(fā)現(xiàn)都有a
ls /teset
a

一容用多卷:

強(qiáng)制刪除所有容器,能不用則不用吴超。
docker rm -f $(docker ps -aq)
刪除宿主機(jī)下钉嘹,容器卷目錄所有文件
rm -f /test/*
并額外創(chuàng)建2個(gè)目錄
touch /test2 /test3
如下
ll / | grep test
drwxr-xr-x.   2 root root    6 4月  12 03:07 test
drwxr-xr-x    2 root root    6 4月  12 03:07 test2
drwxr-xr-x    2 root root    6 4月  12 03:07 test3

創(chuàng)建一個(gè)容器,并映射3個(gè)目錄
docker run --name test --privileged=true -it -v /test:/test -v /test2:/test2 -v /test3:/test3 b3797fa08f5b /bin/bash
發(fā)現(xiàn)容器內(nèi)也有3個(gè)目錄
ll / | grep test
drwxr-xr-x.   2 root root    6 Apr 11 19:07 test/
drwxr-xr-x    2 root root    6 Apr 11 19:07 test2/
drwxr-xr-x    2 root root    6 Apr 11 19:07 test3/

容器內(nèi)執(zhí)行
touch /test/a /test2/a /test3/a
宿主機(jī)查看烛芬,發(fā)現(xiàn)文件依然共享
ls /test /test2 /test3
/test:
a

/test2:
a

/test3:
a

網(wǎng)卡相關(guān)

安裝docker后,執(zhí)行ifconfig飒责,會(huì)看到以下內(nèi)容:

  • ens33(老版本的叫eth0)是配置宿主機(jī)網(wǎng)絡(luò)用的赘娄。
  • lo是本地回環(huán)地址,用于本地主機(jī)內(nèi)部通信的虛擬網(wǎng)絡(luò)接口。
  • docker就是安裝docker時(shí)虛擬出來(lái)的網(wǎng)卡宏蛉,用于docker容器間和宿主機(jī)的通信:
    • flags=4099<UP,BROADCAST,MULTICAST> mtu 1500: 這部分顯示了網(wǎng)絡(luò)接口的名稱(docker0)遣臼、標(biāo)志和 MTU(最大傳輸單元)值(1500)。
    • inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255: 這部分顯示了網(wǎng)絡(luò)接口的 IPv4 地址(172.17.0.1)拾并、子網(wǎng)掩碼(255.255.0.0)和廣播地址(172.17.255.255)揍堰。這個(gè)地址范圍是 Docker 橋接網(wǎng)絡(luò)的默認(rèn)范圍。
    • inet6 fe80::42:37ff:fef9:25d7 prefixlen 64 scopeid 0x20<link>: 這部分顯示了網(wǎng)絡(luò)接口的 IPv6 地址嗅义。
    • ether 02:42:37:f9:25:d7 txqueuelen 0 (Ethernet): 這部分顯示了網(wǎng)絡(luò)接口的 MAC 地址和一些其他信息屏歹。
    • RX packets 4197 bytes 250537 (244.6 KiB): 這部分顯示了接收到的數(shù)據(jù)包和字節(jié)數(shù)。
    • TX packets 4317 bytes 14144344 (13.4 MiB): 這部分顯示了發(fā)送的數(shù)據(jù)包和字節(jié)數(shù)之碗。蝙眶。
ifconfig

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:37ff:fef9:25d7  prefixlen 64  scopeid 0x20<link>
        ether 02:42:37:f9:25:d7  txqueuelen 0  (Ethernet)
        RX packets 4197  bytes 250537 (244.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4317  bytes 14144344 (13.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.180  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::2545:6607:f0f7:64cb  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:39:be:95  txqueuelen 1000  (Ethernet)
        RX packets 20615  bytes 15431772 (14.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10726  bytes 954390 (932.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 32  bytes 2592 (2.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 32  bytes 2592 (2.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

執(zhí)行ip a,也會(huì)看到類似的內(nèi)容:

  • <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default: 這部分顯示了網(wǎng)絡(luò)接口的名稱(docker0)褪那、狀態(tài)(DOWN)幽纷、標(biāo)志(NO-CARRIER、BROADCAST博敬、MULTICAST友浸、UP)、MTU(最大傳輸單元)值(1500)以及隊(duì)列規(guī)則(qdisc)等信息偏窝。
  • link/ether 02:42:37:f9:25:d7 brd ff:ff:ff:ff:ff:ff: 這部分顯示了網(wǎng)絡(luò)接口的 MAC 地址和廣播地址收恢。
  • inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever: 這部分顯示了網(wǎng)絡(luò)接口的 IPv4 地址(172.17.0.1)武学、子網(wǎng)掩碼(/16),以及廣播地址派诬。valid_lft和 `preferred_lft 分別表示地址的有效生存時(shí)間和首選生存時(shí)間劳淆,設(shè)置為 forever 表示永久有效。
  • inet6 fe80::42:37ff:fef9:25d7/64 scope link valid_lft forever preferred_lft forever: 這部分顯示了網(wǎng)絡(luò)接口的 IPv6 地址和范圍默赂。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:39:be:95 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.180/24 brd 192.168.0.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::2545:6607:f0f7:64cb/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:37:f9:25:d7 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:37ff:fef9:25d7/64 scope link 
       valid_lft forever preferred_lft forever

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

docker網(wǎng)絡(luò)顧名思義沛鸵,為什么要去研究它?

  • 控制容器間通信:只有容器不通信缆八,好比買了個(gè)手機(jī)不聯(lián)網(wǎng)曲掰,技能無(wú)法充分發(fā)揮。
  • 降低對(duì)網(wǎng)絡(luò)的運(yùn)維成本:容器IP變動(dòng)時(shí)(增加奈辰、減少容器數(shù)量等因素)栏妖,可以通過(guò)服務(wù)名進(jìn)行通信,保證通信不受影響奖恰。

Docker網(wǎng)絡(luò)相關(guān)命令

在docker run時(shí)吊趾,可以使用docker run --network bridge ...去指定驅(qū)動(dòng)程序。

docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local
  • NETWORK ID:網(wǎng)絡(luò)唯一標(biāo)識(shí)瑟啃。
  • NAME:起個(gè)名论泛。
  • DRIVER:Docker 網(wǎng)絡(luò)所使用的驅(qū)動(dòng)程序,一些常見的網(wǎng)絡(luò)驅(qū)動(dòng)程序包括:
    • bridge(橋接 默認(rèn)值): 默認(rèn)的 Docker 網(wǎng)絡(luò)驅(qū)動(dòng)程序蛹屿,使用docker0網(wǎng)卡連接容器到宿主機(jī)的網(wǎng)絡(luò)屁奏。
    • host(主機(jī)): 讓容器直接使用宿主機(jī)的網(wǎng)絡(luò)命名空間,與宿主機(jī)共享網(wǎng)絡(luò)棧错负,使用這個(gè)坟瓢,docker run -p就沒有意義了。
    • overlay(覆蓋): 允許在多個(gè) Docker 宿主機(jī)上創(chuàng)建連接的容器網(wǎng)絡(luò)犹撒,用于容器在不同宿主機(jī)間通信折联。
    • macvlan(MACVLAN): 允許容器擁有自己的 MAC 地址,并直接與物理網(wǎng)絡(luò)相連识颊。
    • none(無(wú)): 禁用容器的網(wǎng)絡(luò)崭庸,使容器無(wú)法進(jìn)行網(wǎng)絡(luò)通信,很少用谊囚。
    • container(容器):新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡怕享,而是和一個(gè)指定容器共享IP和端口,很少用镰踏,容易端口沖突函筋,且對(duì)容器有依賴性。
  • SCOPE:定義網(wǎng)絡(luò)范圍的作用域
    • local(本地 默認(rèn)值): 這表示網(wǎng)絡(luò)只在當(dāng)前 Docker 宿主機(jī)上可見和可用奠伪,不會(huì)跨越宿主機(jī)邊界跌帐。
    • global(全局): 這表示網(wǎng)絡(luò)在所有 Docker 宿主機(jī)上都可見和可用首懈,可以跨越宿主機(jī)邊界。
    • swarm(集群): 這表示網(wǎng)絡(luò)是 Docker Swarm 集群中的一部分谨敛,可以在整個(gè) Swarm 集群中使用究履。

Docker對(duì)網(wǎng)絡(luò)配置的增刪改查操作:

執(zhí)行網(wǎng)絡(luò)聯(lián)機(jī)的命令行幫助,會(huì)得到以下內(nèi)容脸狸,無(wú)外乎就是增刪改查
docker network --help
Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.


增:
docker network create test_net
7b7c0cbc15c65a5ef4a0e1ad5e7d997ec04afb322afc9e67845c8735ccf1fb06
docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
f4481eb7078e   bridge     bridge    local
c10b6f388063   host       host      local
21c306a93cbb   none       null      local
7b7c0cbc15c6   test_net   bridge    local

刪:
docker network rm test_net
^[[Atest_net
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local

改:極少操作最仑。

查:
docker inspect f4481eb7078e
返回一個(gè)json。

Docker網(wǎng)絡(luò)通信架構(gòu)

  • docker0:虛擬出來(lái)一塊網(wǎng)卡炊甲,讓容器之間泥彤、宿主機(jī)、進(jìn)行通信卿啡。docker0是虛擬出來(lái)的硬件吟吝,bridge是通信的方式。
  • veth:veth(Virtual Ethernet)是Linux系統(tǒng)中一種虛擬網(wǎng)絡(luò)設(shè)備颈娜,常用于 Docker 容器之間和容器與宿主機(jī)之間的通信剑逃,當(dāng)創(chuàng)建一個(gè)Docker容器時(shí),Docker會(huì)為容器分配一個(gè)唯一的網(wǎng)絡(luò)命名空間官辽,并為該容器創(chuàng)建一個(gè)veth pair設(shè)備蛹磺。容器內(nèi)的veth設(shè)備稱為 eth0(或其他指定的網(wǎng)絡(luò)接口名),而與之配對(duì)的宿主機(jī)端的veth設(shè)備可以在宿主機(jī)上看到野崇,通常以 vethXXX 這樣的形式命名称开。通過(guò)這種方式亩钟,容器可以通過(guò)自己的網(wǎng)絡(luò)接口與宿主機(jī)上的其他容器或外部網(wǎng)絡(luò)進(jìn)行通信乓梨。Docker 使用 Linux 的網(wǎng)絡(luò)命名空間和 veth 設(shè)備來(lái)隔離容器的網(wǎng)絡(luò)棧,同時(shí)通過(guò)網(wǎng)絡(luò)橋接(如 docker0)實(shí)現(xiàn)容器與宿主機(jī)網(wǎng)絡(luò)的連接和通信清酥。
  • eth0:這是每個(gè)容器實(shí)例或宿主機(jī)自身的內(nèi)部網(wǎng)卡扶镀。
  • 注意:容器內(nèi)的eth0和veth總是成雙成對(duì)的出現(xiàn)。
  • 通信方式:無(wú)論是容器與容器之間焰轻,容器與宿主機(jī)之間臭觉,都需要通過(guò)docker0的bridge方式通信。

上一張經(jīng)典的圖:


78ca3cb36a5648be91429bf85ce88759.png

開兩個(gè)Nginx證明一下是否是多出來(lái)兩個(gè)veth:

關(guān)閉宿主機(jī)nginx服務(wù)辱志,nginx設(shè)置開啟了服務(wù)
service nginx stop
起兩個(gè)nginx容器
docker run -d -p 80:80 nginx
docker run -d -p 8080:80 nginx
確定容器是否真的跑起來(lái)
docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS                                   NAMES
bf6321d659c4   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   funny_williams
859b85ccf760   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp       brave_vaughan

確定配置是否成功蝠筑,或用curl訪問(wèn)也行
netstat -nlp | grep 80
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      22982/docker-proxy  
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      22838/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      22988/docker-proxy  
tcp6       0      0 :::80                   :::*                    LISTEN      22844/docker-proxy  
unix  2      [ ACC ]     STREAM     LISTENING     50191    6480/abrtd           /var/run/abrt/abrt.socket


重點(diǎn)來(lái)了,然后再執(zhí)行ifconfig揩懒,會(huì)發(fā)現(xiàn)多出來(lái)兩個(gè)veth開頭的網(wǎng)卡:
ifconfig

veth7c2861b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::e881:5aff:fe82:55ca  prefixlen 64  scopeid 0x20<link>
        ether ea:81:5a:82:55:ca  txqueuelen 0  (Ethernet)
        RX packets 35  bytes 4797 (4.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 52  bytes 7096 (6.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth8ed54b8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::1cb3:6eff:fe84:1563  prefixlen 64  scopeid 0x20<link>
        ether 1e:b3:6e:84:15:63  txqueuelen 0  (Ethernet)
        RX packets 31  bytes 4017 (3.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 37  bytes 4395 (4.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

同理什乙,可以使用ip a命令
ip addr

14: veth7c2861b@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ea:81:5a:82:55:ca brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::e881:5aff:fe82:55ca/64 scope link 
       valid_lft forever preferred_lft forever
18: veth8ed54b8@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1e:b3:6e:84:15:63 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::1cb3:6eff:fe84:1563/64 scope link 
       valid_lft forever preferred_lft forever

想要驗(yàn)證,與eth0是否是成對(duì)出現(xiàn)的已球,但是nginx鏡像缺少ip 或者ifconfig命令臣镣,apt-get update命令報(bào)錯(cuò)辅愿,導(dǎo)致無(wú)法驗(yàn)證。
實(shí)際上宿主機(jī)上看的veth7c2861b@if13和veth8ed54b8@if17中的if13與if17忆某,都是與容器當(dāng)中的網(wǎng)卡編號(hào)對(duì)應(yīng)的点待。

當(dāng)使用docker inspect 容器id時(shí),就能看到該容器網(wǎng)絡(luò)相關(guān)的信息弃舒。

docker inspect 6dc7f1d29a17 | tail -n 21
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "",
                    "NetworkID": "f4481eb7078ebf9be90119f8a99f5869354ed14d9b093924da43bf1ba19b36a0",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null,
                    "DNSNames": null
                }
            }

對(duì)于這個(gè)json癞埠,做個(gè)介紹:

  • "IPAMConfig": 這是用于管理IP地址的配置,通常在Docker網(wǎng)絡(luò)模式為bridge時(shí)使用棒坏。
  • "Links": 這里是容器與其他容器之間鏈接的信息燕差,但在這個(gè)例子中為null,表示沒有其他容器鏈接到這個(gè)容器坝冕。
  • "Aliases": 這是容器的網(wǎng)絡(luò)別名徒探,也是null,表示沒有設(shè)置別名喂窟。
  • "MacAddress": 這是容器的MAC地址测暗,通常由Docker自動(dòng)生成。
  • "NetworkID": 這是網(wǎng)絡(luò)的唯一標(biāo)識(shí)符磨澡,用于區(qū)分不同的Docker網(wǎng)絡(luò)碗啄。
  • "EndpointID": 這是容器端點(diǎn)的唯一標(biāo)識(shí)符,用于標(biāo)識(shí)容器在網(wǎng)絡(luò)中的位置稳摄。
  • "Gateway": 這是網(wǎng)絡(luò)的網(wǎng)關(guān)地址稚字,通常由Docker提供。
  • "IPAddress": 這是容器分配的IP地址厦酬。
  • "IPPrefixLen": 這是容器IP地址的前綴長(zhǎng)度胆描,通常是一個(gè)整數(shù)。
  • "IPv6Gateway": 這是IPv6網(wǎng)絡(luò)的網(wǎng)關(guān)地址仗阅。
  • "GlobalIPv6Address": 這是容器的全局IPv6地址昌讲。
  • "GlobalIPv6PrefixLen": 這是容器的全局IPv6地址的前綴長(zhǎng)度。
  • "DriverOpts": 這是網(wǎng)絡(luò)驅(qū)動(dòng)的選項(xiàng)配置减噪,通常在特定網(wǎng)絡(luò)驅(qū)動(dòng)中使用短绸。
  • "DNSNames": 這是容器的DNS名稱列表,用于解析容器內(nèi)部的 DNS 查詢筹裕。

不同容器配置不同的Docker網(wǎng)絡(luò)

  • 為了分門別類醋闭,方便管理。
  • 有了它朝卒,可以避免IP變動(dòng)引起的故障证逻,為docker容器編排做準(zhǔn)備。
創(chuàng)建網(wǎng)絡(luò)
docker network create zs_test
ee465a9eccd7d758e3b4a4281539352d8169364f860091928f3296129c6ac384

并查看
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local
ee465a9eccd7   zs_test   bridge    local

開兩個(gè)終端分別執(zhí)行
docker run --name centos01 --network zs_test -it 5d0da3dc9764 /bin/bash
docker run --name centos02 --network zs_test -it 5d0da3dc9764 /bin/bash

然后再任意終端上ping另一個(gè)容器的name參數(shù)
ping centos02
PING centos02 (172.23.0.3) 56(84) bytes of data.
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=3 ttl=64 time=0.090 ms

使用name參數(shù)扎运,可以避免IP變動(dòng)情況的發(fā)生瑟曲。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饮戳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子洞拨,更是在濱河造成了極大的恐慌扯罐,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烦衣,死亡現(xiàn)場(chǎng)離奇詭異歹河,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)花吟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門秸歧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人衅澈,你說(shuō)我怎么就攤上這事键菱。” “怎么了今布?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵经备,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我部默,道長(zhǎng)侵蒙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任傅蹂,我火速辦了婚禮纷闺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘份蝴。我一直安慰自己犁功,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布搞乏。 她就那樣靜靜地躺著波桩,像睡著了一般戒努。 火紅的嫁衣襯著肌膚如雪请敦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天储玫,我揣著相機(jī)與錄音侍筛,去河邊找鬼。 笑死撒穷,一個(gè)胖子當(dāng)著我的面吹牛匣椰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播端礼,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼禽笑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼入录!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起佳镜,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤僚稿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蟀伸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚀同,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年啊掏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蠢络。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡迟蜜,死狀恐怖刹孔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娜睛,我是刑警寧澤芦疏,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站微姊,受9級(jí)特大地震影響酸茴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兢交,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一薪捍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧配喳,春花似錦酪穿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至涧团,卻和暖如春只磷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泌绣。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工钮追, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阿迈。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓元媚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子刊棕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容