鏡像分層的簡(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è)步驟:
- 加電自檢(Power-On Self-Test赊窥,POST):計(jì)算機(jī)啟動(dòng)時(shí),會(huì)執(zhí)行自檢程序狸页,檢查硬件是否正常锨能。如果自檢過(guò)程中發(fā)現(xiàn)硬件故障,計(jì)算機(jī)可能會(huì)發(fā)出警報(bào)或者停止啟動(dòng)芍耘。
- 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è)置。
- 引導(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)的初始化。
- 內(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)等樱哼。
- 用戶空間初始化:內(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)典的圖:
開兩個(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ā)生瑟曲。