提示:文章寫完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
Docker 網(wǎng)絡(luò)實(shí)現(xiàn)原理
Docker使用Linux橋接,在宿主機(jī)虛擬一個(gè)Docker容器網(wǎng)橋(docker0),Docker啟動(dòng)一個(gè)容器時(shí)會(huì)根據(jù)Docker網(wǎng)橋的網(wǎng)段分配給容器一個(gè)IP地址,稱為Container-IP,同時(shí)Docker網(wǎng)橋是每個(gè)容器的默認(rèn)網(wǎng)關(guān)。因?yàn)樵谕凰拗鳈C(jī)內(nèi)的容器都接入同一個(gè)網(wǎng)橋,這樣容器之間就能夠通過容器的 Container-IP 直接通信。
Docker網(wǎng)橋是宿主機(jī)虛擬出來的,并不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無法尋址到的,這也意味著外部網(wǎng)絡(luò)無法直接通過 Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主主機(jī)(端口映射),即 docker run 創(chuàng)建容器時(shí)候通過 -p 或 -P 參數(shù)來啟用,訪問容器的時(shí)候就通過[宿主機(jī)IP]:[容器端口]訪問容器。
docker run -d --name test1 -P nginx #隨機(jī)映射端口(從32768開始)
docker run -d --name test2 -p 43000:80 nginx #指定映射端口
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d3c04f57a68 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:43000->80/tcp test2
b04895f870e5 nginx "/docker-entrypoint.…" 17 seconds ago Up 15 seconds 0.0.0.0:49170->80/tcp test1
瀏覽器訪問:http://192.168.142.10:43000 、http://192.168.142.10:49170
#查看容器的輸出和日志信息
docker logs 容器的ID/名稱
Docker 的網(wǎng)絡(luò)模式
●Host:容器將不會(huì)虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。
●Container:創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的IP,而是和一個(gè)指定的容器共享IP、端口范圍。
●None:該模式關(guān)閉了容器的網(wǎng)絡(luò)功能。
●Bridge:默認(rèn)為該模式,此模式會(huì)為每一個(gè)容器分配、設(shè)置IP等,并將容器連接到一個(gè)docker0虛擬網(wǎng)橋,通過docker0網(wǎng)橋以及iptables nat 表配置與宿主機(jī)通信。
●自定義網(wǎng)絡(luò)
安裝Docker時(shí),它會(huì)自動(dòng)創(chuàng)建三個(gè)網(wǎng)絡(luò),bridge(創(chuàng)建容器默認(rèn)連接到此網(wǎng)絡(luò))、 none 、host
docker network ls 或 docker network list #查看docker網(wǎng)絡(luò)列表
NETWORK ID NAME DRIVER SCOPE
2b4359d229c6 bridge bridge local
0fa580365d39 host host local
cc13aa84a223 none null local
使用docker run創(chuàng)建Docker容器時(shí),可以用 --net 或 --network 選項(xiàng)指定容器的網(wǎng)絡(luò)模式
●host模式:使用 --net=host 指定。
●none模式:使用 --net=none 指定。
●container模式:使用 --net=container:NAME_or_ID 指定。
●bridge模式:使用 --net=bridge 指定,默認(rèn)設(shè)置,可省略。
網(wǎng)絡(luò)模式詳解
host模式
相當(dāng)于Vmware中的橋接模式,與宿主機(jī)在同一個(gè)網(wǎng)絡(luò)中,但沒有獨(dú)立IP地址。
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)容器的時(shí)候使用host模式,那么這個(gè)容器將不會(huì)獲得一個(gè)獨(dú)立的Network Namespace, 而是和宿主機(jī)共用一個(gè)Network Namespace。容器將不會(huì)虛擬出自己的網(wǎng)卡、配置自己的IP等,而是使用宿主機(jī)的IP和端口。
container模式
在理解了host模式后,這個(gè)模式也就好理解了。這個(gè)模式指定新創(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è)備通信。
none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。 也就是說,這個(gè)Docker容器沒有網(wǎng)卡、IP、路由等信息。這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒有其他網(wǎng)卡。這種類型的網(wǎng)絡(luò)沒有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
bridge模式
bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不用–net參數(shù),就是bridge模式。
相當(dāng)于Vmware中的 nat 模式,容器使用獨(dú)立network Namespace,并連接到docker0虛擬網(wǎng)卡。通過docker0網(wǎng)橋以及iptables nat表配置與宿主機(jī)通信,此模式會(huì)為每一個(gè)容器分配Network Namespace、設(shè)置IP等,并將一個(gè)主機(jī)上的 Docker 容器連接到一個(gè)虛擬網(wǎng)橋上。
(1)當(dāng)Docker進(jìn)程啟動(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ò)中。
(2)從docker0子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。在主機(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è)備。
(3)Docker將 veth pair 設(shè)備的一端放在新創(chuàng)建的容器中,并命名為 eth0(容器的網(wǎng)卡),另一端放在主機(jī)中, 以 veth* 這樣類似的名字命名, 并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到 docker0 網(wǎng)橋中??梢酝ㄟ^ brctl show 命令查看。
(4)使用 docker run -p 時(shí),docker實(shí)際是在iptables做了DNAT規(guī)則,實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能。可以使用iptables -t nat -vnL 查看。
自定義網(wǎng)絡(luò)
直接使用bridge模式,是無法支持指定IP運(yùn)行docker的,例如執(zhí)行以下命令就會(huì)報(bào)錯(cuò)
docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash
創(chuàng)建自定義網(wǎng)絡(luò)
#可以先自定義網(wǎng)絡(luò),再使用指定IP運(yùn)行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
----------------------------------------------------------------------------------------------------------
#docker1 為執(zhí)行 ifconfig -a 命令時(shí),顯示的網(wǎng)卡名,如果不使用 --opt 參數(shù)指定此名稱,那你在使用 ifconfig -a 命令查看網(wǎng)絡(luò)信息時(shí),看到的是類似 br-110eb56a0b22 這樣的名字,這顯然不怎么好記。
#mynetwork 為執(zhí)行 docker network list 命令時(shí),顯示的bridge網(wǎng)絡(luò)模式名稱。
----------------------------------------------------------------------------------------------------------
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash
資源控制(Cgroup)
Docker 通過 Cgroup 來控制容器使用的資源配額,包括 CPU、內(nèi)存、磁盤三大方面, 基本覆蓋了常見的資源配額和使用量控制。
Cgroup 是 ControlGroups 的縮寫,是 Linux 內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組所使用的物理資源(如 CPU、內(nèi)存、磁盤 IO 等等) 的機(jī)制,被 LXC、docker 等很多項(xiàng)目用于實(shí)現(xiàn)進(jìn)程資源控制。Cgroup 本身是提供將進(jìn)程進(jìn)行分組化管理的功能和接口的基礎(chǔ)結(jié)構(gòu),I/O 或內(nèi)存的分配控制等具體的資源管理是通過該功能來實(shí)現(xiàn)的。
CPU 資源控制
(1)設(shè)置CPU使用率上限
Linux通過CFS(Completely Fair Scheduler,完全公平調(diào)度器)來調(diào)度各個(gè)進(jìn)程對(duì)CPU的使用。CFS默認(rèn)的調(diào)度周期是100ms。
我們可以設(shè)置每個(gè)容器進(jìn)程的調(diào)度周期,以及在這個(gè)周期內(nèi)各個(gè)容器最多能使用多少 CPU 時(shí)間。
(2)設(shè)置CPU資源占用比(設(shè)置多個(gè)容器時(shí)才有效)
Docker 通過 --cpu-shares 指定 CPU 份額,默認(rèn)值為1024,值為1024的倍數(shù)。
#創(chuàng)建兩個(gè)容器為 c1 和 c2,若只有這兩個(gè)容器,設(shè)置容器的權(quán)重,使得c1和c2的CPU資源占比為1/3和2/3。
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
#分別進(jìn)入容器,進(jìn)行壓力測(cè)試
yum install -y epel-release
yum install -y stress
stress -c 4 #產(chǎn)生四個(gè)進(jìn)程,每個(gè)進(jìn)程都反復(fù)不停的計(jì)算隨機(jī)數(shù)的平方根
#查看容器運(yùn)行狀態(tài)(動(dòng)態(tài)更新)
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c3ee18e65852 c2 66.50% 5.5MiB / 976.3MiB 0.56% 20.4MB / 265kB 115MB / 14.2MB 4
bb02d3b345d8 c1 32.68% 2.625MiB / 976.3MiB 0.27% 20.4MB / 325kB 191MB / 12.7MB 4
可以看到在 CPU 進(jìn)行時(shí)間片分配的時(shí)候,容器 c2 比容器 c1 多一倍的機(jī)會(huì)獲得 CPU 的時(shí)間片。
但分配的結(jié)果取決于當(dāng)時(shí)主機(jī)和其他容器的運(yùn)行狀態(tài), 實(shí)際上也無法保證容器 c1 一定能獲得 CPU 時(shí)間片。比如容器 c1 的進(jìn)程一直是空閑的,那么容器 c2 是可以獲取比容器 c1 更多的 CPU 時(shí)間片的。極端情況下,例如主機(jī)上只運(yùn)行了一個(gè)容器,即使它的 CPU 份額只有 50,它也可以獨(dú)占整個(gè)主機(jī)的 CPU 資源。
Cgroups 只在容器分配的資源緊缺時(shí),即在需要對(duì)容器使用的資源進(jìn)行限制時(shí),才會(huì)生效。因此,無法單純根據(jù)某個(gè)容器的 CPU 份額來確定有多少 CPU 資源分配給它,資源分配結(jié)果取決于同時(shí)運(yùn)行的其他容器的 CPU 分配和容器中進(jìn)程運(yùn)行情況。文章來源:http://www.zghlxwxcb.cn/news/detail-615098.html
(3)設(shè)置容器綁定指定的CPU文章來源地址http://www.zghlxwxcb.cn/news/detail-615098.html
#先分配虛擬機(jī)4個(gè)CPU核數(shù)
docker run -itd --name test7 --cpuset-cpus 1,3 centos:7 /bin/bash
#進(jìn)入容器,進(jìn)行壓力測(cè)試
yum install -y epel-release
yum install stress -y
stress -c 4
#退出容器,執(zhí)行 top 命令再按 1 查看CPU使用情況。
對(duì)內(nèi)存使用的限制
#-m(--memory=) 選項(xiàng)用于限制容器可以使用的最大內(nèi)存
docker run -itd --name test8 -m 512m centos:7 /bin/bash
docker stats
#限制可用的 swap 大小, --memory-swap
強(qiáng)調(diào)一下,--memory-swap 是必須要與 --memory 一起使用的。
正常情況下,--memory-swap 的值包含容器可用內(nèi)存和可用 swap。
所以 -m 300m --memory-swap=1g 的含義為:容器可以使用 300M 的物理內(nèi)存,并且可以使用 700M(1G - 300)的 swap。
如果 --memory-swap 設(shè)置為 0 或者 不設(shè)置,則容器可以使用的 swap 大小為 -m 值的兩倍。
如果 --memory-swap 的值和 -m 值相同,則容器不能使用 swap。
如果 --memory-swap 值為 -1,它表示容器程序使用的內(nèi)存受限,而可以使用的 swap 空間使用不受限制(宿主機(jī)有多少 swap 容器就可以使用多少)。
對(duì)磁盤IO配額控制(blkio)的限制
--device-read-bps:限制某個(gè)設(shè)備上的讀速度bps(數(shù)據(jù)量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test9 --device-read-bps /dev/sda:1M centos:7 /bin/bash
--device-write-bps : 限制某個(gè)設(shè)備上的寫速度bps(數(shù)據(jù)量),單位可以是kb、mb(M)或者gb。
例:docker run -itd --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
--device-read-iops :限制讀某個(gè)設(shè)備的iops(次數(shù))
--device-write-iops :限制寫入某個(gè)設(shè)備的iops(次數(shù))
#創(chuàng)建容器,并限制寫速度
docker run -it --name test10 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
#通過dd來驗(yàn)證寫速度
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct #添加oflag參數(shù)以規(guī)避掉文件系統(tǒng)cache
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s
#清理docker占用的磁盤空間
docker system prune -a #可以用于清理磁盤,刪除關(guān)閉的容器、無用的數(shù)據(jù)卷和網(wǎng)絡(luò)
到了這里,關(guān)于【Linux】Docker 網(wǎng)絡(luò)與資源控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!